@nehon
I want to add a new MotionTrack to a spatial while a previous MotionTrack is still in the control list of that spatial and playing. Therefore I use this method to exchange the previous track with a new one:
[java] public void startMotion(Spatial spatial, MotionPath path, float initialDuration) {
MotionTrack previous = spatial.getControl(MotionTrack.class);
if (previous != null) {
previous.setPlayState(PlayState.Stopped); // I added this setter myself it doesn’t exist yet
spatial.removeControl(previous);
}
MotionTrack track = new MotionTrack(spatial, path, initialDuration + eps);
track.addListener(this);
track.setEnabled(true);
}[/java]
The problem is, that removing the track from the spatial doesn’t stop it so a NPE occurs. That’s why I added
the setter setPlayState(PlayState.Stopped), to stop the track from going through the update loop again while the spatial is already gone.
[java]Schwerwiegend: Uncaught exception thrown in Thread[LWJGL Renderer Thread,6,main]
java.lang.NullPointerException
at com.jme3.cinematic.MotionPath.getDist(MotionPath.java:148)
at com.jme3.cinematic.MotionPath.interpolatePath(MotionPath.java:97)
at com.jme3.cinematic.events.MotionTrack.onUpdate(MotionTrack.java:209)
at com.jme3.cinematic.events.MotionTrack.update(MotionTrack.java:171)
at com.jme3.scene.Spatial.runControlUpdate(Spatial.java:540)
at com.jme3.scene.Spatial.updateLogicalState(Spatial.java:658)
at com.jme3.scene.Node.updateLogicalState(Node.java:147)
at com.jme3.scene.Node.updateLogicalState(Node.java:154)
at com.jme3.scene.Node.updateLogicalState(Node.java:154)
at com.jme3.scene.Node.updateLogicalState(Node.java:154)
at com.jme3.app.SimpleApplication.update(SimpleApplication.java:259)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:149)
at com.jme3.system.lwjgl.LwjglCanvas.runLoop(LwjglCanvas.java:227)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:223)
at java.lang.Thread.run(Thread.java:722)[/java]
Also instead of adding that setter I would suggest to change the MotionTrack’s setEnabled method:
[java] public void setEnabled(boolean enabled) {
if (enabled) {
play();
} else {
playState = PlayState.Stopped;
}
}
}[/java]
There is a stop() method that you can call on the MotionTrack. You don’t need this setter.
also you’re right about the setEnabled, but instead I guess it would be better if it pauses the event instead of stopping it.
thanks for reporting the issue.
1 Like
I committed a fix