Jumping backwards in Time

Listen, both of you.

Seeking is working perfectly in the TestCinematic example in the repo. I tried to reproduce this issue so many times now that i’m starting to consider that i’m stuck in some kind of Groundhog Day cycle.



@garnaout I won’t debug your entire project because the problem can come from everywhere and i just don’t have the time for it.

If you and @nightwolf911, that seems to be interested, can exhibit the problem WITH the TestCinematic, or a SIMPLE test case, I’ll gladly fix it.

As long as you can’t, and it just fail in your project, i will only consider the issue being in your code.

@nehon the error is obvious there you go try this simple example:



The cube goes back and forth, on the way back try jumping to time 2 per se, it won’t jump but keep going. Your test example was too simplistic to show this behavior. As I am reading my trace from a file I have to call the animation function several times as shown in the example below:



[java]package mygame;



import com.jme3.animation.AnimControl;

import com.jme3.animation.AnimationFactory;

import com.jme3.animation.LoopMode;

import com.jme3.cinematic.Cinematic;

import com.jme3.cinematic.events.CinematicEvent;

import com.jme3.app.SimpleApplication;

import com.jme3.cinematic.PlayState;

import com.jme3.cinematic.events.AnimationTrack;

import com.jme3.cinematic.events.CinematicEventListener;

import com.jme3.cinematic.events.PositionTrack;

import com.jme3.input.ChaseCamera;

import com.jme3.input.controls.ActionListener;

import com.jme3.input.controls.KeyTrigger;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.math.Quaternion;

import com.jme3.math.Vector3f;

import com.jme3.scene.Geometry;

import com.jme3.scene.Spatial;

import com.jme3.scene.shape.Box;

import java.io.File;

import javax.swing.JFileChooser;

import javax.swing.JOptionPane;



public class TimeTest extends SimpleApplication {



private Spatial model;

private Cinematic cinematic;

private ChaseCamera chaseCam;



public static void main(String[] args) {

TimeTest app = new TimeTest();

app.start();



}



@Override

public void simpleInitApp() {



createScene();



cinematic = new Cinematic(rootNode, 1000);

stateManager.attach(cinematic);



AnimationFactory factory = new AnimationFactory(5, “animation”);

factory.addTimeTranslation(0, new Vector3f(0, 0, 0));

factory.addTimeTranslation(5, new Vector3f(5, 0, 0));



AnimControl control = model.getControl(AnimControl.class);

if( control == null){

control = new AnimControl();

model.addControl(control);

}



control.addAnim(factory.buildAnimation());



cinematic.addCinematicEvent(0, new AnimationTrack(model, “animation”));





AnimationFactory factory2 = new AnimationFactory(5, “animation2”);

factory2.addTimeTranslation(0, new Vector3f(5, 0, 0));

factory2.addTimeTranslation(5, new Vector3f(0, 0, 0));



AnimControl control2 = model.getControl(AnimControl.class);

if( control2 == null){

control2 = new AnimControl();

model.addControl(control2);

}



control2.addAnim(factory2.buildAnimation());



cinematic.addCinematicEvent(5.1f, new AnimationTrack(model, “animation2”));











cinematic.addListener(new CinematicEventListener() {



public void onPlay(CinematicEvent s) {

chaseCam.setEnabled(false);

System.out.println(“play”);

System.out.println("Animation Speed: " + cinematic.getSpeed());

System.out.println("Animation State: " + cinematic.getPlayState());

System.out.println("Animation Time: " + cinematic.getTime());

}



public void onPause(CinematicEvent cinematic) {

chaseCam.setEnabled(false);

System.out.println(“pause”);

System.out.println("Animation Speed: " + cinematic.getSpeed());

System.out.println("Animation State: " + cinematic.getPlayState());

System.out.println("Animation Time: " + cinematic.getTime());

}



public void onStop(CinematicEvent cinematic) {

chaseCam.setEnabled(false);

// fade.setValue(1);

System.out.println(“stop”);

}

});



flyCam.setEnabled(false);

chaseCam = new ChaseCamera(cam, model, inputManager);



initInputs();

cinematic.setSpeed(3);



}



private void createScene() {



Box drive_unit = new Box(new Vector3f(0, 0, 0), 1, .25f, .5f); // must take from config xml file (TODO)

model = new Geometry(“Drive #”, drive_unit);



if (assetManager == null) {

System.out.println(“Asset Manager is null”);

}



Material mat1 = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);

mat1.setColor(“Color”, ColorRGBA.Orange);

model.setMaterial(mat1);



model.center();



rootNode.attachChild(model);



jumpBackwards();



Material matSoil = new Material(assetManager, “Common/MatDefs/Light/Lighting.j3md”);

matSoil.setBoolean(“UseMaterialColors”, true);

matSoil.setColor(“Ambient”, ColorRGBA.Gray);

matSoil.setColor(“Diffuse”, ColorRGBA.Green);

matSoil.setColor(“Specular”, ColorRGBA.Black);



}



private void initInputs() {

inputManager.addMapping(“togglePause”, new KeyTrigger(keyInput.KEY_RETURN));

inputManager.addMapping(“jump”, new KeyTrigger(keyInput.KEY_J));

ActionListener acl = new ActionListener() {



public void onAction(String name, boolean keyPressed, float tpf) {

if (name.equals(“togglePause”) && keyPressed) {

if (cinematic.getPlayState() == PlayState.Playing) {

cinematic.pause();

} else {

cinematic.play();

}

}



if (name.equals(“jump”) && keyPressed) {

System.out.println("Time skipped to t = "

  • cinematic.getTime());



    jumpBackwards();



    }



    }

    };

    inputManager.addListener(acl, "togglePause");

    inputManager.addListener(acl, "jump");

    }



    private void jumpBackwards() {



    try {

    float value = Float.parseFloat(JOptionPane.showInputDialog(null,

    "Enter Time",

    "Choose Desired Jump Time",

    JOptionPane.QUESTION_MESSAGE));



    // get jumpTime form user input

    cinematic.setTime(value);



    System.out.println("Time skipped to t = "
  • cinematic.getTime() + " -> " + value);



    } catch (Exception nFE) {

    // do nothing just cancel command

    }

    }

    }[/java]

So tell me…really, why didn’t you start with this test case?

there is an issue indeed when you have 2 spatial animations on the same model.

I’m on it.

ok, the issue was in fact occurring when you had several Spatial anim and a speed over 1.



it’s fixed in svn.

You should get consistent behavior now when you seek into a cinematic.



However, the way you input the time in your test case produce another issue.

When your dialog box pops up it stops the rendering and updating waiting for the user to enter a time. This is not good an will produce a “jump” in the cinematic when you close the dialog box, because the tpf passed to the cinematic right after is equal to the time you spent inputting the value.



You should pop your dialog box using a future and set the cinematic time from this future with a app.enqueue(callable). also use setPauseOnLostFocus(false); so that the app does not pause when the dialog pops up.

@nehon thanks for quickly resolving this. If I want to update my code w/o using the nightly which files in particular did you update? I am trying to stick with the stable version.




When your dialog box pops up it stops the rendering and updating waiting for the user to enter a time. This is not good an will produce a “jump” in the cinematic when you close the dialog box, because the tpf passed to the cinematic right after is equal to the time you spent inputting the value.


Not sure I quite got the fix. Wouldn't that be also resolved by adding Pause() every time Jump is called? that's how I have it in my actual code, I pause everytime a FFW or Reqing or jump is called. Could u explain the fix more not sure I quite got the following:

You should pop your dialog box using a future and set the cinematic time from this future with a app.enqueue(callable). also use setPauseOnLostFocus(false); so that the app does not pause when the dialog pops up.
@garnaout said:
@nehon thanks for quickly resolving this. If I want to update my code w/o using the nightly which files in particular did you update? I am trying to stick with the stable version.

then wait for the next stable....it's not stable anymore if you patch it...

@garnaout said:
Not sure I quite got the fix. Wouldn't that be also resolved by adding Pause() every time Jump is called? that's how I have it in my actual code, I pause everytime a FFW or Reqing or jump is called. Could u explain the fix more not sure I quite got the following:

pause won't fix it, because pause, pauses application but not actual time.

do this
[java]
public class YourApp extends SimpleApplication {
.....
private ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(2);
private Cinematic cinematic;
....
....
private void initInputs(){
....
if (name.equals("jump") && keyPressed) {
exec.submit(jumpBackwards);
}
....
}

Callable jumpBackwards = new Callable() {

public Object call() throws Exception {
try {
final float value = Float.parseFloat(JOptionPane.showInputDialog(null,
"Enter Time",
"Choose Desired Jump Time",
JOptionPane.QUESTION_MESSAGE));

YourApp.this.enqueue(new Callable<Void>() {

public Void call() throws Exception {
cinematic.setTime(value);
return null;
}
});

} catch (Exception nFE) {
// do nothing just cancel command
}
return null;
}
};

[/java]
1 Like
then wait for the next stable….it’s not stable anymore if you patch it…


but that could take a long time :) can you just tell me which files you modified and I will do the appropriate modifications on my project?

http://code.google.com/p/jmonkeyengine/source/detail?r=9239



you can seen every commit in the google code repo

http://code.google.com/p/jmonkeyengine/source/list

1 Like

I am trying this code in my project using the latest nightly however this function:



[java] public Object call() throws Exception {

try {

final float value = Float.parseFloat(JOptionPane.showInputDialog(null,

“Enter Time”,

“Choose Desired Jump Time”,

JOptionPane.QUESTION_MESSAGE));



YourApp.this.enqueue(new Callable<Void>() {



public Void call() throws Exception {

cinematic.setTime(value);

return null;

}

});[/java]



has something in it where I can’t pass the desired jump time. Any number I input won’t get passed to cinematic. If I explicitly put a value for the variable value, it works.

@nightwolf911 I am having the same issue with Eclipse but it doesn’t happen in the sdk.



@nehon I gave it a shot and the bug persists in other scenarios.



I attached to you a testCase to show you the issue in code. To better see the issue, wait till the orange car is on its way back to its initial position and try to jump to time 2 lets say, and watch how the blue car doesn’t go back to its initial position when you jump back. It does what’s its supposed to do “delayed” which you might think is fine here, but when you run on larger systems this delay could be minutes (which is whats happening to my project) and when you’re dealing with sequential events, good luck, it messes up everything.



[java]

package mygame;





import com.jme3.animation.AnimControl;

import com.jme3.animation.AnimationFactory;

import com.jme3.animation.LoopMode;

import com.jme3.cinematic.Cinematic;

import com.jme3.cinematic.events.CinematicEvent;

import com.jme3.app.SimpleApplication;

import com.jme3.cinematic.PlayState;

import com.jme3.cinematic.events.AnimationTrack;

import com.jme3.cinematic.events.CinematicEventListener;

import com.jme3.cinematic.events.PositionTrack;

import com.jme3.input.ChaseCamera;

import com.jme3.input.controls.ActionListener;

import com.jme3.input.controls.KeyTrigger;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.math.Quaternion;

import com.jme3.math.Vector3f;

import com.jme3.scene.Geometry;

import com.jme3.scene.Spatial;

import com.jme3.scene.shape.Box;

import java.io.File;

import java.util.concurrent.Callable;

import java.util.concurrent.ScheduledThreadPoolExecutor;

import javax.swing.JFileChooser;

import javax.swing.JOptionPane;



public class TimeTest extends SimpleApplication {



private Spatial model;

private Spatial podModel;



private Cinematic cinematic;

private ChaseCamera chaseCam;

private ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(2);





public static void main(String[] args) {

TimeTest app = new TimeTest();

app.start();



}



@Override

public void simpleInitApp() {



createScene();



cinematic = new Cinematic(rootNode, 1000);

stateManager.attach(cinematic);



AnimationFactory factory = new AnimationFactory(10, “animation”);

factory.addTimeTranslation(0, new Vector3f(0, 0, 0));

factory.addTimeTranslation(10, new Vector3f(5, 0, 0));



AnimControl control = model.getControl(AnimControl.class);

if( control == null){

control = new AnimControl();

model.addControl(control);

}



control.addAnim(factory.buildAnimation());



cinematic.addCinematicEvent(0, new AnimationTrack(model, “animation”));



AnimationFactory factory2 = new AnimationFactory(10, “animation2”);

factory2.addTimeTranslation(0, new Vector3f(5, 0, 0));

factory2.addTimeTranslation(10, new Vector3f(0, 0, 0));



AnimControl control2 = model.getControl(AnimControl.class);

if( control2 == null){

control2 = new AnimControl();

model.addControl(control2);

}



control2.addAnim(factory2.buildAnimation());



cinematic.addCinematicEvent(10.1f, new AnimationTrack(model, “animation2”));





AnimationFactory factory3 = new AnimationFactory(3, “animation3”);

factory3.addTimeTranslation(0, new Vector3f(0, 0, 1));

factory3.addTimeTranslation(3, new Vector3f(5, 0, 1));



AnimControl control3 = podModel.getControl(AnimControl.class);

if( control3 == null){

control3 = new AnimControl();

podModel.addControl(control3);

}



control3.addAnim(factory3.buildAnimation());



cinematic.addCinematicEvent(8.1f, new AnimationTrack(podModel, “animation3”));



cinematic.addListener(new CinematicEventListener() {



public void onPlay(CinematicEvent s) {

chaseCam.setEnabled(false);

System.out.println(“play”);

System.out.println("Animation Speed: " + cinematic.getSpeed());

System.out.println("Animation State: " + cinematic.getPlayState());

System.out.println("Animation Time: " + cinematic.getTime());

}



public void onPause(CinematicEvent cinematic) {

chaseCam.setEnabled(false);

System.out.println(“pause”);

System.out.println("Animation Speed: " + cinematic.getSpeed());

System.out.println("Animation State: " + cinematic.getPlayState());

System.out.println("Animation Time: " + cinematic.getTime());

}



public void onStop(CinematicEvent cinematic) {

chaseCam.setEnabled(false);

// fade.setValue(1);

System.out.println(“stop”);

}

});



flyCam.setEnabled(false);

chaseCam = new ChaseCamera(cam, model, inputManager);



initInputs();

cinematic.setSpeed(1);



}





Callable jumpBackwards = new Callable() {



public Object call() throws Exception {

try {

final float value = Float.parseFloat(JOptionPane.showInputDialog(null,

“Enter Time”,

“Choose Desired Jump Time”,

JOptionPane.QUESTION_MESSAGE));



TimeTest.this.enqueue(new Callable<Void>() {



public Void call() throws Exception {

cinematic.setTime(value);

return null;

}

});



} catch (Exception nFE) {

// do nothing just cancel command

}

return null;

}

};







private void createScene() {



Box pod = new Box(new Vector3f(0, 0, 1f), 1, .25f, .5f);

podModel = new Geometry(“pod #”, pod);

Material mat2 = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);

mat2.setColor(“Color”, ColorRGBA.Blue);

podModel.setMaterial(mat2);



Box drive_unit = new Box(new Vector3f(0, 0, 0), 1, .25f, .5f); // must take from config xml file (TODO)

model = new Geometry(“Drive #”, drive_unit);

Material mat1 = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);

mat1.setColor(“Color”, ColorRGBA.Orange);

model.setMaterial(mat1);



model.center();

//podModel.center();



rootNode.attachChild(model);

rootNode.attachChild(podModel);



//jumpBackwards();



Material matSoil = new Material(assetManager, “Common/MatDefs/Light/Lighting.j3md”);

matSoil.setBoolean(“UseMaterialColors”, true);

matSoil.setColor(“Ambient”, ColorRGBA.Gray);

matSoil.setColor(“Diffuse”, ColorRGBA.Green);

matSoil.setColor(“Specular”, ColorRGBA.Black);



}



private void initInputs() {

inputManager.addMapping(“togglePause”, new KeyTrigger(keyInput.KEY_RETURN));

inputManager.addMapping(“jump”, new KeyTrigger(keyInput.KEY_J));

inputManager.addMapping(“increaseSpeed”, new KeyTrigger(keyInput.KEY_EQUALS));

ActionListener acl = new ActionListener() {



public void onAction(String name, boolean keyPressed, float tpf) {

if (name.equals(“togglePause”) && keyPressed) {

if (cinematic.getPlayState() == PlayState.Playing) {

cinematic.pause();

} else {

cinematic.play();

}

}



if (name.equals(“jump”) && keyPressed) {

System.out.println("Time skipped to t = "

  • cinematic.getTime());



    exec.submit(jumpBackwards);



    }



    else if (name.equals("increaseSpeed") && keyPressed) {



    //pause to maintain animation accuracy

    //cinematic.pause();

    exec.submit(increaseSpeed);

    // exec.submit(increaseSpeed);

    // increase animation speed by 1x

    //cinematic.setSpeed(cinematic.getSpeed() + 1);

    }





    }

    };

    inputManager.addListener(acl, "togglePause");

    inputManager.addListener(acl, "jump");

    inputManager.addListener(acl, "increaseSpeed");

    }



    /** Jump time function. Allows user to jump
  • in time during the animation (forward/backward)

    /

    Callable jumpTime = new Callable() {



    public Object call() throws Exception {

    try {



    //setPauseOnLostFocus(false);

    final float value = Float.parseFloat(JOptionPane.showInputDialog(null,

    "Enter Time",

    "Choose Desired Jump Time",

    JOptionPane.QUESTION_MESSAGE));





    TimeTest.this.enqueue(new Callable<Void>() {



    public Void call() throws Exception {



    cinematic.setTime(value);

    System.out.println("Jumping to time: "+cinematic.getTime());

    return null;

    }

    });



    } catch (Exception nFE) {

    // do nothing just cancel command

    System.out.println("Exception: Jumping in time failed");

    }

    return null;

    }

    };







    /
    * Jump time function. Allows user to jump
  • in time during the animation (forward/backward)

    */

    Callable increaseSpeed = new Callable() {



    public Object call() throws Exception {

    try {



    TimeTest.this.enqueue(new Callable<Void>() {



    public Void call() throws Exception {

    cinematic.pause();

    cinematic.setSpeed(cinematic.getSpeed() + 1);

    return null;

    }

    });



    } catch (Exception nFE) {

    // do nothing just cancel command

    }

    return null;

    }

    };

    }

    [/java]

even try to keep the animation paused and start jumping back in time, only the orange one moves as you go up in time, the blue one stays the same place

I updated the testCase in fact there is an issue with increasing speed and pause(). Try increasing speed using the hotkey “=” there’s a jump in the animation even if you use Callable. (try it jumping X 2 for example , it’s easily noticed)



I have noticed some strange behaviors also pausing at higher speeds

mhh ok the cinematic does not reset the transforms the spatial had before the event. This is not an issue if there is an actual event at the time you seek because it will update the position, but if you have no event, the spatial just stays still.



ok that’s an actual issue thank you, i’ll fix it

1 Like

http://code.google.com/p/jmonkeyengine/source/detail?r=9245

here is the fix

Okay now things return to where they’re supposed to be but a few issues:



1- if I changed their colors, the colors remain the same and never change back.



2- with longer trace files, things get messy. By that, I mean that even that things go to their initial place the events are not synchronized (eventually will get synchronized but takes some time). See testCase below and try this: from the beginning to jump to time 1 or 0, see how the blue box changes location although it shouldn’t.



3- which leads me to this point where this might be causing it, check trace below. As I mentioned before, there’s a bug related to increasing the speed of teh animation (even though I am using Callable). when you increase the speed, nothing happens , then suddently the spatial JUMPS. with longer trace files, this jumps messes up everything. Give it a shot to see what I 'm talking about:



I collected two of these bugs in the following testcase:



[java]

package mygame;





import com.jme3.animation.AnimControl;

import com.jme3.animation.AnimationFactory;

import com.jme3.cinematic.Cinematic;

import com.jme3.cinematic.events.CinematicEvent;

import com.jme3.app.SimpleApplication;

import com.jme3.cinematic.PlayState;

import com.jme3.cinematic.events.AnimationTrack;

import com.jme3.cinematic.events.CinematicEventListener;

import com.jme3.input.ChaseCamera;

import com.jme3.input.controls.ActionListener;

import com.jme3.input.controls.KeyTrigger;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.math.Vector3f;

import com.jme3.scene.Geometry;

import com.jme3.scene.Spatial;

import com.jme3.scene.shape.Box;

import java.util.concurrent.Callable;

import java.util.concurrent.ScheduledThreadPoolExecutor;

import javax.swing.JOptionPane;



public class TimeTest extends SimpleApplication {



private Spatial model;

private Spatial podModel;



private Cinematic cinematic;

private ChaseCamera chaseCam;

private ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(2);





public static void main(String[] args) {

TimeTest app = new TimeTest();

app.start();



}



@Override

public void simpleInitApp() {



createScene();



cinematic = new Cinematic(rootNode, 1000);

stateManager.attach(cinematic);



AnimationFactory factory = new AnimationFactory(10, “animation”);

factory.addTimeTranslation(0, new Vector3f(0, 0, 0));

factory.addTimeTranslation(10, new Vector3f(5, 0, 0));



AnimControl control = model.getControl(AnimControl.class);

if( control == null){

control = new AnimControl();

model.addControl(control);

}



control.addAnim(factory.buildAnimation());



cinematic.addCinematicEvent(0, new AnimationTrack(model, “animation”));



AnimationFactory factory2 = new AnimationFactory(10, “animation2”);

factory2.addTimeTranslation(0, new Vector3f(5, 0, 0));

factory2.addTimeTranslation(10, new Vector3f(0, 0, 0));



AnimControl control2 = model.getControl(AnimControl.class);

if( control2 == null){

control2 = new AnimControl();

model.addControl(control2);

}



control2.addAnim(factory2.buildAnimation());



cinematic.addCinematicEvent(10.1f, new AnimationTrack(model, “animation2”));





AnimationFactory factory3 = new AnimationFactory(3, “animation3”);

factory3.addTimeTranslation(0, new Vector3f(0, 0, 1));

factory3.addTimeTranslation(3, new Vector3f(5, 0, 1));



AnimControl control3 = podModel.getControl(AnimControl.class);

if( control3 == null){

control3 = new AnimControl();

podModel.addControl(control3);

}



control3.addAnim(factory3.buildAnimation());



cinematic.addCinematicEvent(8.1f, new AnimationTrack(podModel, “animation3”));







AnimationFactory factory4 = new AnimationFactory(5, “animation4”);

factory4.addTimeTranslation(0, new Vector3f(5, 0, 1));

factory4.addTimeRotationAngles(0, 0, 0, 0);

factory4.addTimeRotationAngles(5, 0, 0, 0.785f);



AnimControl control4 = podModel.getControl(AnimControl.class);

if( control4 == null){

control4 = new AnimControl();

podModel.addControl(control4);

}



control4.addAnim(factory4.buildAnimation());



cinematic.addCinematicEvent(21f, new AnimationTrack(podModel, “animation4”));







/////////////////////////////////////////////////////////////////////////////////





cinematic.addListener(new CinematicEventListener() {



public void onPlay(CinematicEvent s) {

chaseCam.setEnabled(false);

System.out.println(“play”);

System.out.println("Animation Speed: " + cinematic.getSpeed());

System.out.println("Animation State: " + cinematic.getPlayState());

System.out.println("Animation Time: " + cinematic.getTime());

}



public void onPause(CinematicEvent cinematic) {

chaseCam.setEnabled(false);

System.out.println(“pause”);

System.out.println("Animation Speed: " + cinematic.getSpeed());

System.out.println("Animation State: " + cinematic.getPlayState());

System.out.println("Animation Time: " + cinematic.getTime());

}



public void onStop(CinematicEvent cinematic) {

chaseCam.setEnabled(false);

// fade.setValue(1);

System.out.println(“stop”);

}

});



flyCam.setEnabled(false);

chaseCam = new ChaseCamera(cam, model, inputManager);



initInputs();

cinematic.setSpeed(1);



}





Callable jumpBackwards = new Callable() {



public Object call() throws Exception {

try {

final float value = Float.parseFloat(JOptionPane.showInputDialog(null,

“Enter Time”,

“Choose Desired Jump Time”,

JOptionPane.QUESTION_MESSAGE));



TimeTest.this.enqueue(new Callable<Void>() {



public Void call() throws Exception {

cinematic.setTime(value);

return null;

}

});



} catch (Exception nFE) {

// do nothing just cancel command

}

return null;

}

};







private void createScene() {



Box pod = new Box(new Vector3f(0, 0, 1f), 1, .25f, .5f);

podModel = new Geometry(“pod #”, pod);

Material mat2 = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);

mat2.setColor(“Color”, ColorRGBA.Blue);

podModel.setMaterial(mat2);



Box drive_unit = new Box(new Vector3f(0, 0, 0), 1, .25f, .5f); // must take from config xml file (TODO)

model = new Geometry(“Drive #”, drive_unit);

Material mat1 = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);

mat1.setColor(“Color”, ColorRGBA.Orange);

model.setMaterial(mat1);



model.center();

//podModel.center();



rootNode.attachChild(model);

rootNode.attachChild(podModel);



//jumpBackwards();



Material matSoil = new Material(assetManager, “Common/MatDefs/Light/Lighting.j3md”);

matSoil.setBoolean(“UseMaterialColors”, true);

matSoil.setColor(“Ambient”, ColorRGBA.Gray);

matSoil.setColor(“Diffuse”, ColorRGBA.Green);

matSoil.setColor(“Specular”, ColorRGBA.Black);



}



private void initInputs() {

inputManager.addMapping(“togglePause”, new KeyTrigger(keyInput.KEY_RETURN));

inputManager.addMapping(“jump”, new KeyTrigger(keyInput.KEY_J));

inputManager.addMapping(“increaseSpeed”, new KeyTrigger(keyInput.KEY_EQUALS));

ActionListener acl = new ActionListener() {



public void onAction(String name, boolean keyPressed, float tpf) {

if (name.equals(“togglePause”) && keyPressed) {

if (cinematic.getPlayState() == PlayState.Playing) {

cinematic.pause();

} else {

cinematic.play();

}

}



if (name.equals(“jump”) && keyPressed) {

System.out.println("Time skipped to t = "

  • cinematic.getTime());



    exec.submit(jumpBackwards);



    }



    else if (name.equals("increaseSpeed") && keyPressed) {



    //pause to maintain animation accuracy

    //cinematic.pause();

    exec.submit(increaseSpeed);

    // exec.submit(increaseSpeed);

    // increase animation speed by 1x

    //cinematic.setSpeed(cinematic.getSpeed() + 1);

    }





    }

    };

    inputManager.addListener(acl, "togglePause");

    inputManager.addListener(acl, "jump");

    inputManager.addListener(acl, "increaseSpeed");

    }



    /** Jump time function. Allows user to jump
  • in time during the animation (forward/backward)

    /

    Callable jumpTime = new Callable() {



    public Object call() throws Exception {

    try {



    //setPauseOnLostFocus(false);

    final float value = Float.parseFloat(JOptionPane.showInputDialog(null,

    "Enter Time",

    "Choose Desired Jump Time",

    JOptionPane.QUESTION_MESSAGE));





    TimeTest.this.enqueue(new Callable<Void>() {



    public Void call() throws Exception {



    cinematic.setTime(value);

    System.out.println("Jumping to time: "+cinematic.getTime());

    return null;

    }

    });



    } catch (Exception nFE) {

    // do nothing just cancel command

    System.out.println("Exception: Jumping in time failed");

    }

    return null;

    }

    };







    /
    * Jump time function. Allows user to jump
  • in time during the animation (forward/backward)

    */

    Callable increaseSpeed = new Callable() {



    public Object call() throws Exception {

    try {



    TimeTest.this.enqueue(new Callable<Void>() {



    public Void call() throws Exception {

    //cinematic.pause();

    cinematic.setSpeed(cinematic.getSpeed() + 1);

    return null;

    }

    });



    } catch (Exception nFE) {

    // do nothing just cancel command

    }

    return null;

    }

    };

    }[/java]



    PS: In eclipse the pause pauses the animation but when you resume things go chaotic as if it never paused, this does not happen in jME (but it didn’t happen in Eclipse before the update)

note (for the Pause issue) that I am using the nightly in the SDK and patching the files in Eclipse so I am assuming I am missing an update in the nightly. Could you maybe point out what files could be affecting the Pause()?

@garnaout said:
Okay now things return to where they're supposed to be but a few issues:
1- if I changed their colors, the colors remain the same and never change back.

What the f... are you talking about?

@garnaout said:
I collected two of these bugs in the following testcase:

...listen...a test case is a small class that exhibit ONE issue, i'm kinda tired of spending my evenings sorting out your spaghetti code.
Also you could investigate your own issue, you know that open source means you have access to the code?
I just have the feeling that i'm just doing personal support for your project...for free.
You helped exhibit some issues of the cinematic system, and i'm grateful for this, but i also must say that it has been the more painful debugging process I have ever been through as most of the time i don't have a damn clue about what the output should be and i have to sort out a 300 lines class with no comment.

@nehon with all due respect, I thought this is helpful for both of us, I am finding issues with your code after you suggested to switch from PositionTrack to AnimationTrack and the issues are still occuring - the same issues - which is time seeking. I am writing quick testCases just to point out where the issues are (so of course it won’t be a neat code) and most of the times they were issues indeed - don’t you want to find them?



I think I am one of the very few using cinematics and that allows you to stress test you code, not sure why that bothers you. I don’t mind submitting bugs into more specific testCases rather than putting them into one. But there are definitely issues with the code and I don’t have nearly the expertise you have in that code. It would literally take me months to find the issues you find in a few minutes.



let me know if you still want me to submit them individually or simply stop bugging you as you already helped me A LOT and I can’t deny that. But I do also think many other users could benefit from these questions on the forum as these issues will sooner or later have to be resolved.

wow this is a headache lol when is the next stable version? I guess i’m gonna wait for that one.

@garnaout said:
@nehon with all due respect, I thought this is helpful for both of us, I am finding issues with your code after you suggested to switch from PositionTrack to AnimationTrack and the issues are still occuring - the same issues - which is time seeking. I am writing quick testCases just to point out where the issues are (so of course it won't be a neat code) and most of the times they were issues indeed - don't you want to find them?

You're bending the system to suit your needs.
Cinematic are designed to make cutscenes in a game, period!
Not to be fed with whatever file data, that i still don't get why you want to use to make some kind of simulation that i don't get neither.

Cinematics are working fine when you play them forward. That's 99% of the use cases there will be in a cutscene in a game.
Seeking through a Cinematic only matters at design time, or in game in very few specific cases.

@garnaout said:
I think I am one of the very few using cinematics

You're right about that, and i'm seriously considering getting it out of the core.
Sometime when a system as issues and is not used, it's just useless and time consuming.

@garnaout said:
It would literally take me months to find the issues you find in a few minutes.

That's the crappiest excuse I've ever heard. "I don't try to resolve my issues because i know someone that would do it a lot faster than i would...."
We don't have a common time pool you and me, minutes of my time are minutes of MY time, period. And I'd rather use them as I see fit.