after quite some time trying different methods, the only method that I was able to write in order to animate acceleration/deceleration perfectly (with very precise numbers) was the following:
[java]
public class AccelerateTrack extends AbstractCinematicEvent {
private static final Logger log = Logger.getLogger(AccelerateTrack.class.getName());
private Spatial spatial;
private String spatialName = “”;
private double value = 0;
private Vector3f endPosition;
private float currentSpeed;
private final Vector3f acceleration;
private double previousSpeed;
float animationSpeed;
private final double theta;
// create an instance of the Simpleapplication inside Jme3Cinematics
private final AnimatorVisualizer myApp;
// reads the asset manager initialized in Jme3Cinematics
private final AssetManager assetManager;
public AccelerateTrack(AnimatorVisualizer cinematics, Spatial spatial,
Vector3f endPosition, double duration,
double acceleration, double previousSpeed, double theta,
LoopMode loopMode)
{
super((float) duration, loopMode);
this.myApp = cinematics;
this.assetManager = myApp.getAssetManager();
this.endPosition = endPosition;
this.spatial = spatial;
// the vector for acceleration has z = 0
this.acceleration = new Vector3f((float)acceleration,(float) acceleration, 0);
this.previousSpeed = previousSpeed;
this.spatialName = spatial.getName();
currentSpeed = (float) previousSpeed;
this.theta = Math.toRadians(theta);
}
@Override
public void initEvent(Application app, Cinematic cinematic) {
super.initEvent(app, cinematic);
if (spatial == null) {
spatial = cinematic.getScene().getChild(spatialName);
if (spatial == null) {
} else {
log.log(Level.WARNING, “spatial {0} not found in the scene”, spatialName);
}
}
}
@Override
public void onPause() {
// running = false;
}
@Override
public void onPlay() {
}
@Override
public void onStop() {
value = 0;
}
// note that reverse here is done via acceleration, then deceleration
// and NOT deceleration than acceleration (like the sim)
// tpf : time elapsed since the last frame (not constant) - this is delta t
// time: time elapsed since the beginning of the animation event (0) until its duration
@Override
public void onUpdate(float tpf) {
//value = Math.min(time / initialDuration, 1.0f);
//time = time+ (tpf * speed);
// get spatial acceleration direction
float vx = (float) (currentSpeed * Math.cos(theta));
float vy = (float) (currentSpeed * Math.sin(theta));
// get spatial local translation
Vector3f x0 = spatial.getLocalTranslation();
// get spatial initial speed
Vector3f v0 = new Vector3f(vx, vy, 0);
// get spatial x(t) according to the formula
// x(t) = x0 + v0(t) + 1/2 at^2
// tpf is the delta time here
Vector3f xi = x0.add(v0.mult(tpf * myApp.getAnimationSpeed()));
xi.addLocal(acceleration.mult(0.5f * tpf * tpf));
// update the location of the spatial accordingly
spatial.setLocalTranslation( xi );
// update the current speed for the next update
currentSpeed = currentSpeed + acceleration.x * tpf * myApp.getAnimationSpeed();
}
@Override
public void write(JmeExporter ex) throws IOException {
super.write(ex);
OutputCapsule oc = ex.getCapsule(this);
oc.write(spatialName, “spatialName”, “”);
oc.write(endPosition, “endPosition”, null);
}
@Override
public void read(JmeImporter im) throws IOException {
super.read(im);
InputCapsule ic = im.getCapsule(this);
spatialName = ic.readString(“spatialName”, “”);
endPosition = (Vector3f) ic.readSavable(“endPosition”, null);
}
}
[/java]
now this method does not take the variable “time” into consideration which is necessary for AnimationTrack. Any idea how can I modify this class in order to implement time w/o messing up the accuracy of my acceleration?
thanks in advance
If it’s working like this please keep it as it is.
wouldn’t that affect the time seeking negatively when I jump back in time if I’m not taking time into consideration?
how is it working right now when you’re seeking?
it gets messy for a little bit then eventually fixes itself…