package actor;
import render.Matrix;
public class AnimationManager
{
private KeyFrameAnimation fromAnimation, toAnimation;
private double prevTime = 0.0, transition = 1.0;
private double beat = 0.0, elapsed = 0.0;
public AnimationManager() {}
public AnimationManager(KeyFrameAnimation animation)
{
super();
this.toAnimation = animation;
}
public Point3D[] getAnimatedVertices(WorldState world, Actor actor)
{
Point3D[] newAnimationPts = getAnimatedVerticesOffsets(world, actor);
for(int i = 0; i < newAnimationPts.length; i++)
newAnimationPts[i].add(actor.getModel().getBaseShape()[i]);
return newAnimationPts;
}
public Point3D[] getAnimatedVerticesOffsets(WorldState world, Actor actor)
{
double time = world.getTime();
if(prevTime == 0.0) prevTime = time;
elapsed = time - prevTime;
prevTime = time;
Point3D[] newAnimationPts;
transition = Math.min(1, transition + elapsed);
if(transition >= 1.0)
{
actor.setAnimationTravel(
elapsed * toAnimation.getTravel() * toAnimation.getRate());
beat = (beat + elapsed * toAnimation.getRate())
% toAnimation.getFrameCount();
newAnimationPts = toAnimation.getVertexOffsets(elapsed, beat);
}
else
{
actor.setAnimationTravel(elapsed
* lerp(transition, fromAnimation.getTravel(), toAnimation.getTravel())
* lerp(transition, fromAnimation.getRate(), toAnimation.getRate()));
beat = (beat + elapsed * lerp(transition, fromAnimation.getRate(),
toAnimation.getRate())) % fromAnimation.getFrameCount();
KeyFrame kfFrom = new KeyFrame
(fromAnimation.getVertexOffsets(elapsed, beat));
KeyFrame kfTo = new KeyFrame
(toAnimation.getVertexOffsets(elapsed, beat));
newAnimationPts = KeyFrame.keyFrameLerp(transition, kfFrom, kfTo);
}
return newAnimationPts;
}
public void changeAnimation(KeyFrameAnimation kFA)
{
if(fromAnimation == null)
initiateTransition(kFA, kFA, 1.0);
else if (toAnimation != kFA)
initiateTransition(toAnimation, kFA, 0.0);
}
public void initiateTransition(
KeyFrameAnimation from,
KeyFrameAnimation to,
double transition)
{
this.fromAnimation = from;
this.toAnimation = to;
this.transition = transition;
}
public static Point3D[] orientAnimationVertices(MotionChange mC, Point3D[] p)
{
Point3D[] returnPts = new Point3D[p.length];
if (mC.newDirection != null)
{
Matrix rotationMatrix = new Matrix();
rotationMatrix.rotateY(mC.newDirection.getYRotation());
for (int i = 0; i < returnPts.length; i++)
returnPts[i] = Point3D.matrixTransform(rotationMatrix, p[i]);
}
else
{
for (int i = 0; i < returnPts.length; i++)
returnPts[i] = p[i];
}
return returnPts;
}
public double getTransition()
{
return transition;
}
public void setTransition(double transition)
{
this.transition = transition;
}
public double getBeat()
{
return beat;
}
public void setBeat(double beat)
{
this.beat = beat;
}
public KeyFrameAnimation getFromAnimation()
{
return fromAnimation;
}
public void setFromAnimation(KeyFrameAnimation from)
{
this.fromAnimation = from;
}
public double getPrevTime()
{
return prevTime;
}
public void setPrevTime(double prevTime)
{
this.prevTime = prevTime;
}
public KeyFrameAnimation getToAnimation()
{
return toAnimation;
}
public void setToAnimation(KeyFrameAnimation toAnimation)
{
this.toAnimation = toAnimation;
}
public double getElapsed()
{
return elapsed;
}
public void setElapsed(double elapsed)
{
this.elapsed = elapsed;
}
public static double lerp(double t, double a, double b)
{
return a + t * (b - a);
}
public void onBehaviorListChange(BehaviorListChangedEvent bce)
{
if (bce.getType() == BehaviorListChangedEvent.CHANGED) {
AbstractBehavior to = bce.getBehavior();
}
}
}