package robombs.game.view;
import robombs.game.Globals;
import robombs.game.model.*;
import com.threed.jpct.*;
/**
* An animated object is an extended client object which can use the animation information already present
* in the client object to play a keyframe animation!
*/
public abstract class AnimatedObject extends ClientObject {
private static final long serialVersionUID = 1L;
public AnimatedObject() {
super(Object3D.createDummyObj());
if (Globals.compiledObjects) {
compile(true);
}
}
public AnimatedObject(Object3D obj) {
super(obj);
if (Globals.compiledObjects) {
compile(true);
}
}
public AnimatedObject(Object3D obj, Object3D child) {
super(obj, child);
if (Globals.compiledObjects) {
compile(true);
getChild().compile(true);
}
}
/**
* Updates the view, i.e. animates the object and does the movement interpolation based on linear interpolation
* until a new state from the server arrives.
* @param ticks the ticks passed since the last call
* @param level the level. Not used in within this method ATM.
*/
public void process(long ticks, Level level) {
int animSeq = getBackAnimation();
int animSpeed = getBackAnimationSpeed();
float offset = 0;
boolean stop = false;
if (animSeq > Animations.NOLOOP) {
animSeq -= Animations.NOLOOP;
stop = true;
}
if (isModified() || animSeq == Animations.DIE) {
// Has moved or is dead anyway: Take the position that the server has transmitted
SimpleVector pos = getBackPosition();
getTranslationMatrix().setIdentity();
translate(pos);
setModified(false);
} else {
// Otherwise, the client wins and the translation will be applied
SimpleVector spd = new SimpleVector(getBackSpeed());
spd.scalarMul(ticks);
translate(spd);
}
Matrix tar = getRotationMatrix().cloneMatrix();
tar.interpolate(getRotationMatrix(), getBackRotationMatrix(), 0.4f * (float) ticks);
setRotationMatrix(tar);
int mul = 1;
if (!getBackSpeed().equals(SimpleVector.ORIGIN) && getBackSpeed().calcDot(getBackRotationMatrix().getZAxis()) < 0) {
mul = -1;
}
if (getLastSequence() != animSeq) {
resetTicks();
}
setLastSequence(animSeq);
setAnimSpeed(animSpeed);
if (animSeq == Animations.DIE) {
offset = 0.631f; // The death animation that we want to use starts here (why not at 0? Only md2 knows...):
setClampingMode(Animation.USE_CLAMPING);
} else {
setClampingMode(Animation.USE_WRAPPING);
}
long tickCnt = getTicks();
if (animSpeed != 0) {
if (getAnimationSequence()!=null) {
// Do this onyl for "visual" clients. Bots don't play this animation.
if (!stop) {
animate((float) (tickCnt % animSpeed) / (float) animSpeed + offset, animSeq);
} else {
animate(1f, animSeq);
}
}
}
addToTicks(ticks * mul);
}
}