Cinematic, fixed time seeking when having several SpatialAnimation with a speed > 1

fixed an issue in soundTrack crashing when time was < 0
properly implemented GuiTrack stop() method

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9239 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
rem..om 13 years ago
parent 191bd21b40
commit 8eae2cfd8a
  1. 14
      engine/src/core/com/jme3/animation/AnimChannel.java
  2. 128
      engine/src/core/com/jme3/cinematic/Cinematic.java
  3. 8
      engine/src/core/com/jme3/cinematic/events/AbstractCinematicEvent.java
  4. 14
      engine/src/core/com/jme3/cinematic/events/AnimationTrack.java
  5. 5
      engine/src/core/com/jme3/cinematic/events/SoundTrack.java
  6. 11
      engine/src/niftygui/com/jme3/cinematic/events/GuiTrack.java
  7. 2
      engine/test-data/Interface/Nifty/CinematicTest.xml

@ -316,6 +316,20 @@ public final class AnimChannel {
BitSet getAffectedBones(){ BitSet getAffectedBones(){
return affectedBones; return affectedBones;
} }
public void reset(boolean rewind){
if(rewind){
setTime(0);
if(control.getSkeleton()!=null){
control.getSkeleton().resetAndUpdate();
}else{
TempVars vars = TempVars.get();
update(0, vars);
vars.release();
}
}
animation = null;
}
void update(float tpf, TempVars vars) { void update(float tpf, TempVars vars) {
if (animation == null) if (animation == null)

@ -59,7 +59,7 @@ import java.util.logging.Logger;
* @author Nehon * @author Nehon
*/ */
public class Cinematic extends AbstractCinematicEvent implements AppState { public class Cinematic extends AbstractCinematicEvent implements AppState {
private static final Logger logger = Logger.getLogger(Application.class.getName()); private static final Logger logger = Logger.getLogger(Application.class.getName());
private Node scene; private Node scene;
protected TimeLine timeLine = new TimeLine(); protected TimeLine timeLine = new TimeLine();
@ -68,30 +68,30 @@ public class Cinematic extends AbstractCinematicEvent implements AppState {
private Map<String, CameraNode> cameras = new HashMap<String, CameraNode>(); private Map<String, CameraNode> cameras = new HashMap<String, CameraNode>();
private CameraNode currentCam; private CameraNode currentCam;
private boolean initialized = false; private boolean initialized = false;
private Map<String, Map<String, Object>> eventsData; private Map<String, Map<String, Object>> eventsData;
public Cinematic() { public Cinematic() {
} }
public Cinematic(Node scene) { public Cinematic(Node scene) {
this.scene = scene; this.scene = scene;
} }
public Cinematic(Node scene, float initialDuration) { public Cinematic(Node scene, float initialDuration) {
super(initialDuration); super(initialDuration);
this.scene = scene; this.scene = scene;
} }
public Cinematic(Node scene, LoopMode loopMode) { public Cinematic(Node scene, LoopMode loopMode) {
super(loopMode); super(loopMode);
this.scene = scene; this.scene = scene;
} }
public Cinematic(Node scene, float initialDuration, LoopMode loopMode) { public Cinematic(Node scene, float initialDuration, LoopMode loopMode) {
super(initialDuration, loopMode); super(initialDuration, loopMode);
this.scene = scene; this.scene = scene;
} }
@Override @Override
public void onPlay() { public void onPlay() {
if (isInitialized()) { if (isInitialized()) {
@ -105,7 +105,7 @@ public class Cinematic extends AbstractCinematicEvent implements AppState {
} }
} }
} }
@Override @Override
public void onStop() { public void onStop() {
time = 0; time = 0;
@ -116,7 +116,7 @@ public class Cinematic extends AbstractCinematicEvent implements AppState {
} }
enableCurrentCam(false); enableCurrentCam(false);
} }
@Override @Override
public void onPause() { public void onPause() {
for (int i = 0; i < cinematicEvents.size(); i++) { for (int i = 0; i < cinematicEvents.size(); i++) {
@ -126,28 +126,28 @@ public class Cinematic extends AbstractCinematicEvent implements AppState {
} }
} }
} }
@Override @Override
public void write(JmeExporter ex) throws IOException { public void write(JmeExporter ex) throws IOException {
super.write(ex); super.write(ex);
OutputCapsule oc = ex.getCapsule(this); OutputCapsule oc = ex.getCapsule(this);
oc.writeSavableArrayList((ArrayList) cinematicEvents, "cinematicEvents", null); oc.writeSavableArrayList((ArrayList) cinematicEvents, "cinematicEvents", null);
oc.writeStringSavableMap(cameras, "cameras", null); oc.writeStringSavableMap(cameras, "cameras", null);
oc.write(timeLine, "timeLine", null); oc.write(timeLine, "timeLine", null);
} }
@Override @Override
public void read(JmeImporter im) throws IOException { public void read(JmeImporter im) throws IOException {
super.read(im); super.read(im);
InputCapsule ic = im.getCapsule(this); InputCapsule ic = im.getCapsule(this);
cinematicEvents = ic.readSavableArrayList("cinematicEvents", null); cinematicEvents = ic.readSavableArrayList("cinematicEvents", null);
cameras = (Map<String, CameraNode>) ic.readStringSavableMap("cameras", null); cameras = (Map<String, CameraNode>) ic.readStringSavableMap("cameras", null);
timeLine = (TimeLine) ic.readSavable("timeLine", null); timeLine = (TimeLine) ic.readSavable("timeLine", null);
} }
@Override @Override
public void setSpeed(float speed) { public void setSpeed(float speed) {
super.setSpeed(speed); super.setSpeed(speed);
@ -155,53 +155,53 @@ public class Cinematic extends AbstractCinematicEvent implements AppState {
CinematicEvent ce = cinematicEvents.get(i); CinematicEvent ce = cinematicEvents.get(i);
ce.setSpeed(speed); ce.setSpeed(speed);
} }
} }
public void initialize(AppStateManager stateManager, Application app) { public void initialize(AppStateManager stateManager, Application app) {
initEvent(app, this); initEvent(app, this);
for (CinematicEvent cinematicEvent : cinematicEvents) { for (CinematicEvent cinematicEvent : cinematicEvents) {
cinematicEvent.initEvent(app, this); cinematicEvent.initEvent(app, this);
} }
initialized = true; initialized = true;
} }
public boolean isInitialized() { public boolean isInitialized() {
return initialized; return initialized;
} }
public void setEnabled(boolean enabled) { public void setEnabled(boolean enabled) {
if (enabled) { if (enabled) {
play(); play();
} }
} }
public boolean isEnabled() { public boolean isEnabled() {
return playState == PlayState.Playing; return playState == PlayState.Playing;
} }
public void stateAttached(AppStateManager stateManager) { public void stateAttached(AppStateManager stateManager) {
} }
public void stateDetached(AppStateManager stateManager) { public void stateDetached(AppStateManager stateManager) {
stop(); stop();
} }
public void update(float tpf) { public void update(float tpf) {
if (isInitialized()) { if (isInitialized()) {
internalUpdate(tpf); internalUpdate(tpf);
} }
} }
@Override @Override
public void onUpdate(float tpf) { public void onUpdate(float tpf) {
for (int i = 0; i < cinematicEvents.size(); i++) { for (int i = 0; i < cinematicEvents.size(); i++) {
CinematicEvent ce = cinematicEvents.get(i); CinematicEvent ce = cinematicEvents.get(i);
ce.internalUpdate(tpf); ce.internalUpdate(tpf);
} }
int keyFrameIndex = timeLine.getKeyFrameIndexFromTime(time); int keyFrameIndex = timeLine.getKeyFrameIndexFromTime(time);
//iterate to make sure every key frame is triggered //iterate to make sure every key frame is triggered
@ -211,33 +211,37 @@ public class Cinematic extends AbstractCinematicEvent implements AppState {
keyFrame.trigger(); keyFrame.trigger();
} }
} }
lastFetchedKeyFrame = keyFrameIndex; lastFetchedKeyFrame = keyFrameIndex;
} }
@Override @Override
public void setTime(float time) { public void setTime(float time) {
super.setTime(time); super.setTime(time);
int keyFrameIndex = timeLine.getKeyFrameIndexFromTime(time); //stopping all events
for (CinematicEvent ce : cinematicEvents) {
ce.stop();
}
//triggering all the event from start to "time" //triggering all the event from start to "time"
//then computing timeOffset for each event //then computing timeOffset for each event
for (int i = 0; i <= keyFrameIndex; i++) { for (KeyFrame keyFrame : timeLine.values()) {
KeyFrame keyFrame = timeLine.get(i); //KeyFrame keyFrame = timeLine.get(timeLine.keySet());
if (keyFrame != null) { if (keyFrame != null) {
for (CinematicEvent ce : keyFrame.getCinematicEvents()) { for (CinematicEvent ce : keyFrame.getCinematicEvents()) {
ce.play(); float t = this.time - timeLine.getKeyFrameTime(keyFrame);
ce.setTime(time - timeLine.getKeyFrameTime(keyFrame)); if (t >= 0 && (t <= ce.getInitialDuration() || ce.getLoopMode() != LoopMode.DontLoop)) {
ce.play();
ce.setTime(t);
}
} }
} }
} }
if (playState != PlayState.Playing) { if (playState != PlayState.Playing) {
pause(); pause();
} }
// step();
} }
public KeyFrame addCinematicEvent(float timeStamp, CinematicEvent cinematicEvent) { public KeyFrame addCinematicEvent(float timeStamp, CinematicEvent cinematicEvent) {
KeyFrame keyFrame = timeLine.getKeyFrameAtTime(timeStamp); KeyFrame keyFrame = timeLine.getKeyFrameAtTime(timeStamp);
if (keyFrame == null) { if (keyFrame == null) {
@ -248,13 +252,13 @@ public class Cinematic extends AbstractCinematicEvent implements AppState {
cinematicEvents.add(cinematicEvent); cinematicEvents.add(cinematicEvent);
return keyFrame; return keyFrame;
} }
public void render(RenderManager rm) { public void render(RenderManager rm) {
} }
public void postRender() { public void postRender() {
} }
public void cleanup() { public void cleanup() {
} }
@ -270,10 +274,10 @@ public class Cinematic extends AbstractCinematicEvent implements AppState {
d = (ce.getDuration() * ce.getSpeed()); d = (ce.getDuration() * ce.getSpeed());
} }
} }
initialDuration = d; initialDuration = d;
} }
public CameraNode bindCamera(String cameraName, Camera cam) { public CameraNode bindCamera(String cameraName, Camera cam) {
CameraNode node = new CameraNode(cameraName, cam); CameraNode node = new CameraNode(cameraName, cam);
node.setControlDir(ControlDirection.SpatialToCamera); node.setControlDir(ControlDirection.SpatialToCamera);
@ -282,17 +286,17 @@ public class Cinematic extends AbstractCinematicEvent implements AppState {
scene.attachChild(node); scene.attachChild(node);
return node; return node;
} }
public CameraNode getCamera(String cameraName) { public CameraNode getCamera(String cameraName) {
return cameras.get(cameraName); return cameras.get(cameraName);
} }
private void enableCurrentCam(boolean enabled) { private void enableCurrentCam(boolean enabled) {
if (currentCam != null) { if (currentCam != null) {
currentCam.getControl(CameraControl.class).setEnabled(enabled); currentCam.getControl(CameraControl.class).setEnabled(enabled);
} }
} }
public void setActiveCamera(String cameraName) { public void setActiveCamera(String cameraName) {
enableCurrentCam(false); enableCurrentCam(false);
currentCam = cameras.get(cameraName); currentCam = cameras.get(cameraName);
@ -301,51 +305,51 @@ public class Cinematic extends AbstractCinematicEvent implements AppState {
} }
enableCurrentCam(true); enableCurrentCam(true);
} }
public void activateCamera(final float timeStamp, final String cameraName) { public void activateCamera(final float timeStamp, final String cameraName) {
addCinematicEvent(timeStamp, new AbstractCinematicEvent() { addCinematicEvent(timeStamp, new AbstractCinematicEvent() {
@Override @Override
public void play() { public void play() {
super.play(); super.play();
stop(); stop();
} }
@Override @Override
public void onPlay() { public void onPlay() {
setActiveCamera(cameraName); setActiveCamera(cameraName);
} }
@Override @Override
public void onUpdate(float tpf) { public void onUpdate(float tpf) {
} }
@Override @Override
public void onStop() { public void onStop() {
} }
@Override @Override
public void onPause() { public void onPause() {
} }
@Override @Override
public void setTime(float time) { public void setTime(float time) {
play(); play();
} }
}); });
} }
public void setScene(Node scene) { public void setScene(Node scene) {
this.scene = scene; this.scene = scene;
} }
private Map<String, Map<String, Object>> getEventsData() { private Map<String, Map<String, Object>> getEventsData() {
if (eventsData == null) { if (eventsData == null) {
eventsData = new HashMap<String, Map<String, Object>>(); eventsData = new HashMap<String, Map<String, Object>>();
} }
return eventsData; return eventsData;
} }
public void putEventData(String type, String name, Object object) { public void putEventData(String type, String name, Object object) {
Map<String, Map<String, Object>> data = getEventsData(); Map<String, Map<String, Object>> data = getEventsData();
Map<String, Object> row = data.get(type); Map<String, Object> row = data.get(type);
@ -354,7 +358,7 @@ public class Cinematic extends AbstractCinematicEvent implements AppState {
} }
row.put(name, object); row.put(name, object);
} }
public Object getEventData(String type, String name) { public Object getEventData(String type, String name) {
if (eventsData != null) { if (eventsData != null) {
Map<String, Object> row = eventsData.get(type); Map<String, Object> row = eventsData.get(type);
@ -364,7 +368,7 @@ public class Cinematic extends AbstractCinematicEvent implements AppState {
} }
return null; return null;
} }
public Savable removeEventData(String type, String name) { public Savable removeEventData(String type, String name) {
if (eventsData != null) { if (eventsData != null) {
Map<String, Object> row = eventsData.get(type); Map<String, Object> row = eventsData.get(type);
@ -374,7 +378,7 @@ public class Cinematic extends AbstractCinematicEvent implements AppState {
} }
return null; return null;
} }
public Node getScene() { public Node getScene() {
return scene; return scene;
} }

@ -100,7 +100,7 @@ public abstract class AbstractCinematicEvent implements CinematicEvent {
* Play this event * Play this event
*/ */
public void play() { public void play() {
onPlay(); onPlay();
playState = PlayState.Playing; playState = PlayState.Playing;
if (listeners != null) { if (listeners != null) {
for (int i = 0; i < listeners.size(); i++) { for (int i = 0; i < listeners.size(); i++) {
@ -121,9 +121,7 @@ public abstract class AbstractCinematicEvent implements CinematicEvent {
*/ */
public void internalUpdate(float tpf) { public void internalUpdate(float tpf) {
if (playState == PlayState.Playing) { if (playState == PlayState.Playing) {
time = time + (tpf * speed); time = time + (tpf * speed);
//time = elapsedTimePause + (timer.getTimeInSeconds() - start) * speed;
onUpdate(tpf); onUpdate(tpf);
if (time >= initialDuration && loopMode == loopMode.DontLoop) { if (time >= initialDuration && loopMode == loopMode.DontLoop) {
stop(); stop();
@ -311,7 +309,7 @@ public abstract class AbstractCinematicEvent implements CinematicEvent {
* @param time the time to fast forward to * @param time the time to fast forward to
*/ */
public void setTime(float time) { public void setTime(float time) {
this.time = time / speed; this.time = time ;
} }
public float getTime() { public float getTime() {

@ -109,17 +109,17 @@ public class AnimationTrack extends AbstractCinematicEvent {
public void setTime(float time) { public void setTime(float time) {
super.setTime(time); super.setTime(time);
float t = time; float t = time;
if(loopMode == loopMode.Loop){ if (loopMode == loopMode.Loop) {
t = t % channel.getAnimMaxTime(); t = t % channel.getAnimMaxTime();
} }
if(loopMode == loopMode.Cycle){ if (loopMode == loopMode.Cycle) {
float parity = (float)Math.ceil(time / channel.getAnimMaxTime()); float parity = (float) Math.ceil(time / channel.getAnimMaxTime());
if(parity >0 && parity%2 ==0){ if (parity > 0 && parity % 2 == 0) {
t = channel.getAnimMaxTime() - t % channel.getAnimMaxTime(); t = channel.getAnimMaxTime() - t % channel.getAnimMaxTime();
}else{ } else {
t = t % channel.getAnimMaxTime(); t = t % channel.getAnimMaxTime();
} }
} }
channel.setTime(t); channel.setTime(t);
channel.getControl().update(0); channel.getControl().update(0);
@ -142,8 +142,8 @@ public class AnimationTrack extends AbstractCinematicEvent {
@Override @Override
public void onStop() { public void onStop() {
channel.getControl().setEnabled(false);
channel.setTime(0); channel.setTime(0);
channel.reset(false);
} }
@Override @Override

@ -116,10 +116,11 @@ public class SoundTrack extends AbstractCinematicEvent {
public void setTime(float time) { public void setTime(float time) {
super.setTime(time); super.setTime(time);
//can occur on rewind //can occur on rewind
if (time < 0) { if (time < 0f) {
stop(); stop();
}else{
audioNode.setTimeOffset(time);
} }
audioNode.setTimeOffset(time);
} }
@Override @Override

@ -32,13 +32,13 @@
package com.jme3.cinematic.events; package com.jme3.cinematic.events;
import com.jme3.animation.LoopMode; import com.jme3.animation.LoopMode;
import com.jme3.app.Application;
import com.jme3.cinematic.Cinematic;
import com.jme3.export.InputCapsule; import com.jme3.export.InputCapsule;
import com.jme3.export.JmeExporter; import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter; import com.jme3.export.JmeImporter;
import com.jme3.export.OutputCapsule; import com.jme3.export.OutputCapsule;
import de.lessvoid.nifty.Nifty; import de.lessvoid.nifty.Nifty;
import de.lessvoid.nifty.screen.NullScreen;
import de.lessvoid.nifty.screen.Screen;
import java.io.IOException; import java.io.IOException;
/** /**
@ -78,13 +78,14 @@ public class GuiTrack extends AbstractCinematicEvent {
@Override @Override
public void onPlay() { public void onPlay() {
System.out.println("screen should be "+screen); System.out.println("screen should be " + screen);
nifty.gotoScreen(screen); nifty.gotoScreen(screen);
} }
@Override @Override
public void onStop() { public void onStop() { if (!(nifty.getCurrentScreen() instanceof NullScreen)) {
nifty.gotoScreen(""); nifty.getCurrentScreen().endScreen(null);
}
} }
@Override @Override

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<nifty> <nifty>
<screen id="start" controller="jme3test.niftygui.TestNiftyGui"> <screen id="start" >
<layer id="layer" backgroundColor="#0000" childLayout="center"> <layer id="layer" backgroundColor="#0000" childLayout="center">
<panel id="panel" width="100%" height="100%" backgroundColor="#0000" childLayout="center" visibleToMouse="true" > <panel id="panel" width="100%" height="100%" backgroundColor="#0000" childLayout="center" visibleToMouse="true" >
<text id="text" font="aurulent-sans-16.fnt" color="#000f" text="" align="center" valign="bottom" /> <text id="text" font="aurulent-sans-16.fnt" color="#000f" text="" align="center" valign="bottom" />

Loading…
Cancel
Save