diff --git a/engine/src/core/com/jme3/cinematic/Cinematic.java b/engine/src/core/com/jme3/cinematic/Cinematic.java index 6a2746c80..3477c221f 100644 --- a/engine/src/core/com/jme3/cinematic/Cinematic.java +++ b/engine/src/core/com/jme3/cinematic/Cinematic.java @@ -35,6 +35,7 @@ import com.jme3.animation.LoopMode; import com.jme3.app.Application; import com.jme3.app.state.AppState; import com.jme3.app.state.AppStateManager; +import com.jme3.asset.TextureKey; import com.jme3.cinematic.events.AbstractCinematicEvent; import com.jme3.cinematic.events.CinematicEvent; import com.jme3.cinematic.events.CinematicEventListener; @@ -58,7 +59,7 @@ import java.util.logging.Logger; * @author Nehon */ public class Cinematic extends AbstractCinematicEvent implements AppState { - + private static final Logger logger = Logger.getLogger(Application.class.getName()); private Node scene; protected TimeLine timeLine = new TimeLine(); @@ -67,36 +68,33 @@ public class Cinematic extends AbstractCinematicEvent implements AppState { private Map cameras = new HashMap(); private CameraNode currentCam; private boolean initialized = false; - private Map> eventsData; - private int scheduledPause = -1; - + private Map> eventsData; + public Cinematic() { } - + public Cinematic(Node scene) { this.scene = scene; } - + public Cinematic(Node scene, float initialDuration) { super(initialDuration); this.scene = scene; } - + public Cinematic(Node scene, LoopMode loopMode) { super(loopMode); this.scene = scene; } - + public Cinematic(Node scene, float initialDuration, LoopMode loopMode) { super(initialDuration, loopMode); this.scene = scene; } - + @Override public void onPlay() { if (isInitialized()) { - scheduledPause = -1; - //enableCurrentCam(true); if (playState == PlayState.Paused) { for (int i = 0; i < cinematicEvents.size(); i++) { CinematicEvent ce = cinematicEvents.get(i); @@ -107,7 +105,7 @@ public class Cinematic extends AbstractCinematicEvent implements AppState { } } } - + @Override public void onStop() { time = 0; @@ -118,7 +116,7 @@ public class Cinematic extends AbstractCinematicEvent implements AppState { } enableCurrentCam(false); } - + @Override public void onPause() { for (int i = 0; i < cinematicEvents.size(); i++) { @@ -128,28 +126,28 @@ public class Cinematic extends AbstractCinematicEvent implements AppState { } } } - + @Override public void write(JmeExporter ex) throws IOException { super.write(ex); OutputCapsule oc = ex.getCapsule(this); - + oc.writeSavableArrayList((ArrayList) cinematicEvents, "cinematicEvents", null); oc.writeStringSavableMap(cameras, "cameras", null); oc.write(timeLine, "timeLine", null); - + } - + @Override public void read(JmeImporter im) throws IOException { super.read(im); InputCapsule ic = im.getCapsule(this); - + cinematicEvents = ic.readSavableArrayList("cinematicEvents", null); cameras = (Map) ic.readStringSavableMap("cameras", null); timeLine = (TimeLine) ic.readSavable("timeLine", null); } - + @Override public void setSpeed(float speed) { super.setSpeed(speed); @@ -157,67 +155,53 @@ public class Cinematic extends AbstractCinematicEvent implements AppState { CinematicEvent ce = cinematicEvents.get(i); ce.setSpeed(speed); } - - + + } - + public void initialize(AppStateManager stateManager, Application app) { initEvent(app, this); for (CinematicEvent cinematicEvent : cinematicEvents) { cinematicEvent.initEvent(app, this); } - + initialized = true; } - + public boolean isInitialized() { return initialized; } - + public void setEnabled(boolean enabled) { if (enabled) { play(); } } - + public boolean isEnabled() { return playState == PlayState.Playing; } - + public void stateAttached(AppStateManager stateManager) { } - + public void stateDetached(AppStateManager stateManager) { stop(); } - + public void update(float tpf) { if (isInitialized()) { internalUpdate(tpf); } } - - private void step() { - if (playState != PlayState.Playing) { - play(); - scheduledPause = 2; - } - } - + @Override - public void onUpdate(float tpf) { - if (scheduledPause >= 0) { - if (scheduledPause == 0) { - pause(); - } - scheduledPause--; - } - + public void onUpdate(float tpf) { for (int i = 0; i < cinematicEvents.size(); i++) { CinematicEvent ce = cinematicEvents.get(i); ce.internalUpdate(tpf); } - + int keyFrameIndex = timeLine.getKeyFrameIndexFromTime(time); //iterate to make sure every key frame is triggered @@ -227,13 +211,13 @@ public class Cinematic extends AbstractCinematicEvent implements AppState { keyFrame.trigger(); } } - + lastFetchedKeyFrame = keyFrameIndex; } - + @Override public void setTime(float time) { - super.setTime(time); + super.setTime(time); int keyFrameIndex = timeLine.getKeyFrameIndexFromTime(time); //triggering all the event from start to "time" @@ -242,17 +226,18 @@ public class Cinematic extends AbstractCinematicEvent implements AppState { KeyFrame keyFrame = timeLine.get(i); if (keyFrame != null) { for (CinematicEvent ce : keyFrame.getCinematicEvents()) { - if (playState == PlayState.Playing) { - ce.play(); - } + ce.play(); ce.setTime(time - timeLine.getKeyFrameTime(keyFrame)); } } } + if (playState != PlayState.Playing) { + pause(); + } - step(); + // step(); } - + public KeyFrame addCinematicEvent(float timeStamp, CinematicEvent cinematicEvent) { KeyFrame keyFrame = timeLine.getKeyFrameAtTime(timeStamp); if (keyFrame == null) { @@ -263,13 +248,13 @@ public class Cinematic extends AbstractCinematicEvent implements AppState { cinematicEvents.add(cinematicEvent); return keyFrame; } - + public void render(RenderManager rm) { } - + public void postRender() { } - + public void cleanup() { } @@ -285,10 +270,10 @@ public class Cinematic extends AbstractCinematicEvent implements AppState { d = (ce.getDuration() * ce.getSpeed()); } } - + initialDuration = d; } - + public CameraNode bindCamera(String cameraName, Camera cam) { CameraNode node = new CameraNode(cameraName, cam); node.setControlDir(ControlDirection.SpatialToCamera); @@ -297,17 +282,17 @@ public class Cinematic extends AbstractCinematicEvent implements AppState { scene.attachChild(node); return node; } - + public CameraNode getCamera(String cameraName) { return cameras.get(cameraName); } - + private void enableCurrentCam(boolean enabled) { if (currentCam != null) { currentCam.getControl(CameraControl.class).setEnabled(enabled); } } - + public void setActiveCamera(String cameraName) { enableCurrentCam(false); currentCam = cameras.get(cameraName); @@ -316,51 +301,51 @@ public class Cinematic extends AbstractCinematicEvent implements AppState { } enableCurrentCam(true); } - + public void activateCamera(final float timeStamp, final String cameraName) { addCinematicEvent(timeStamp, new AbstractCinematicEvent() { - + @Override public void play() { super.play(); stop(); } - + @Override public void onPlay() { setActiveCamera(cameraName); } - + @Override public void onUpdate(float tpf) { } - + @Override public void onStop() { } - + @Override public void onPause() { } - + @Override public void setTime(float time) { play(); } }); } - + public void setScene(Node scene) { this.scene = scene; } - + private Map> getEventsData() { if (eventsData == null) { eventsData = new HashMap>(); } return eventsData; } - + public void putEventData(String type, String name, Object object) { Map> data = getEventsData(); Map row = data.get(type); @@ -369,7 +354,7 @@ public class Cinematic extends AbstractCinematicEvent implements AppState { } row.put(name, object); } - + public Object getEventData(String type, String name) { if (eventsData != null) { Map row = eventsData.get(type); @@ -379,7 +364,7 @@ public class Cinematic extends AbstractCinematicEvent implements AppState { } return null; } - + public Savable removeEventData(String type, String name) { if (eventsData != null) { Map row = eventsData.get(type); @@ -389,7 +374,7 @@ public class Cinematic extends AbstractCinematicEvent implements AppState { } return null; } - + public Node getScene() { return scene; } diff --git a/engine/src/core/com/jme3/cinematic/MotionPath.java b/engine/src/core/com/jme3/cinematic/MotionPath.java index 1f7cdc9ce..64bdc2234 100644 --- a/engine/src/core/com/jme3/cinematic/MotionPath.java +++ b/engine/src/core/com/jme3/cinematic/MotionPath.java @@ -81,56 +81,23 @@ public class MotionPath implements Savable { TempVars vars = TempVars.get(); Vector3f temp = vars.vect1; Vector3f tmpVector = vars.vect2; - switch (spline.getType()) { - case CatmullRom: - - //this iterative process is done to keep the spatial travel at a constant speed on the path even if - //waypoints are not equally spread over the path - - // we compute the theorical distance that the spatial should travel on this frame - val = (time * (spline.getTotalLength() / control.getDuration())) - control.getTraveledDistance(); - //adding and epsilon value to the control currents value - control.setCurrentValue(control.getCurrentValue() + eps); - //computing the new position at current value - spline.interpolate(control.getCurrentValue(), control.getCurrentWayPoint(), temp); - //computing traveled distance at current value - float dist = getDist(control, temp, tmpVector); - - //While the distance traveled this frame is below the theorical distance we iterate the obove computation - while (dist < val) { - //storing the distance traveled this frame - traveledDistance = dist; - control.setCurrentValue(control.getCurrentValue() + eps); - spline.interpolate(control.getCurrentValue(), control.getCurrentWayPoint(), temp); - dist = getDist(control, temp, tmpVector); - } - //compute the direction of the spline - if (control.needsDirection()) { - tmpVector.set(temp); - control.setDirection(tmpVector.subtractLocal(control.getSpatial().getLocalTranslation()).normalizeLocal()); - } - //updating traveled distance to the total distance traveled by the spatial since the start - traveledDistance += control.getTraveledDistance(); - break; - case Linear: - //distance traveled this frame - val = (time * (spline.getTotalLength() / control.getDuration())) - control.getTraveledDistance(); - // computing total traveled distance - traveledDistance = control.getTraveledDistance() + val; - //computing interpolation ratio for this frame - val = val / spline.getSegmentsLength().get(control.getCurrentWayPoint()); - control.setCurrentValue(Math.min(control.getCurrentValue() + val, 1.0f)); - //interpolationg position - spline.interpolate(control.getCurrentValue(), control.getCurrentWayPoint(), temp); - //computing line direction - if (control.needsDirection()) { - tmpVector.set(spline.getControlPoints().get(control.getCurrentWayPoint() + 1)); - control.setDirection(tmpVector.subtractLocal(spline.getControlPoints().get(control.getCurrentWayPoint())).normalizeLocal()); - } - break; - default: - break; + //computing traveled distance according to new time + traveledDistance = time * (getLength() / control.getInitialDuration()); + + //getting waypoint index and current value from new traveled distance + Vector2f v = getWayPointIndexForDistance(traveledDistance); + + //setting values + control.setCurrentWayPoint((int) v.x); + control.setCurrentValue(v.y); + + //interpolating new position + getSpline().interpolate(control.getCurrentValue(), control.getCurrentWayPoint(), temp); + if (control.needsDirection()) { + tmpVector.set(temp); + control.setDirection(tmpVector.subtractLocal(control.getSpatial().getLocalTranslation()).normalizeLocal()); } + control.getSpatial().setLocalTranslation(temp); vars.release(); return traveledDistance; diff --git a/engine/src/core/com/jme3/cinematic/events/AbstractCinematicEvent.java b/engine/src/core/com/jme3/cinematic/events/AbstractCinematicEvent.java index 84d087910..ea2d13215 100644 --- a/engine/src/core/com/jme3/cinematic/events/AbstractCinematicEvent.java +++ b/engine/src/core/com/jme3/cinematic/events/AbstractCinematicEvent.java @@ -39,8 +39,6 @@ import com.jme3.export.InputCapsule; import com.jme3.export.JmeExporter; import com.jme3.export.JmeImporter; import com.jme3.export.OutputCapsule; -import com.jme3.system.NanoTimer; -import com.jme3.system.Timer; import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -59,12 +57,8 @@ public abstract class AbstractCinematicEvent implements CinematicEvent { protected float initialDuration = 10; protected LoopMode loopMode = LoopMode.DontLoop; protected float time = 0; - protected Timer timer; - protected float start = 0; - /** - * the last time the event was paused - */ - protected float elapsedTimePause = 0; + protected boolean resuming = false; + /** * the list of listeners */ @@ -108,12 +102,6 @@ public abstract class AbstractCinematicEvent implements CinematicEvent { public void play() { onPlay(); playState = PlayState.Playing; - if (timer == null) { - //only when used as a control - timer = new NanoTimer(); - } - start = timer.getTimeInSeconds(); - //timer.reset(); if (listeners != null) { for (int i = 0; i < listeners.size(); i++) { CinematicEventListener cel = listeners.get(i); @@ -133,7 +121,7 @@ public abstract class AbstractCinematicEvent implements CinematicEvent { */ public void internalUpdate(float tpf) { if (playState == PlayState.Playing) { - time = time+ (tpf * speed); + time = time + (tpf * speed); //time = elapsedTimePause + (timer.getTimeInSeconds() - start) * speed; onUpdate(tpf); @@ -157,7 +145,6 @@ public abstract class AbstractCinematicEvent implements CinematicEvent { onStop(); time = 0; playState = PlayState.Stopped; - elapsedTimePause = 0; if (listeners != null) { for (int i = 0; i < listeners.size(); i++) { CinematicEventListener cel = listeners.get(i); @@ -177,7 +164,6 @@ public abstract class AbstractCinematicEvent implements CinematicEvent { public void pause() { onPause(); playState = PlayState.Paused; - elapsedTimePause = time; if (listeners != null) { for (int i = 0; i < listeners.size(); i++) { CinematicEventListener cel = listeners.get(i); @@ -291,8 +277,6 @@ public abstract class AbstractCinematicEvent implements CinematicEvent { * @param cinematic */ public void initEvent(Application app, Cinematic cinematic) { - timer = app.getContext().getTimer(); - //timer = new NanoTimer(); } /** @@ -327,10 +311,7 @@ public abstract class AbstractCinematicEvent implements CinematicEvent { * @param time the time to fast forward to */ public void setTime(float time) { - elapsedTimePause = time / speed; - if (playState == PlayState.Playing) { - start = timer.getTimeInSeconds(); - } + this.time = time / speed; } public float getTime() { diff --git a/engine/src/core/com/jme3/cinematic/events/AnimationTrack.java b/engine/src/core/com/jme3/cinematic/events/AnimationTrack.java index fc27cdda3..e857706c5 100644 --- a/engine/src/core/com/jme3/cinematic/events/AnimationTrack.java +++ b/engine/src/core/com/jme3/cinematic/events/AnimationTrack.java @@ -122,6 +122,7 @@ public class AnimationTrack extends AbstractCinematicEvent { } channel.setTime(t); + channel.getControl().update(0); } @Override diff --git a/engine/src/core/com/jme3/cinematic/events/CinematicEvent.java b/engine/src/core/com/jme3/cinematic/events/CinematicEvent.java index 6d176ec04..37e70f920 100644 --- a/engine/src/core/com/jme3/cinematic/events/CinematicEvent.java +++ b/engine/src/core/com/jme3/cinematic/events/CinematicEvent.java @@ -131,8 +131,8 @@ public interface CinematicEvent extends Savable { * When this method is invoked, the event should fast forward to the given time according tim 0 is the start of the event. * @param time the time to fast forward to */ - public void setTime(float time); - + public void setTime(float time); + /** * returns the current time of the cinematic event * @return the time diff --git a/engine/src/core/com/jme3/cinematic/events/MotionTrack.java b/engine/src/core/com/jme3/cinematic/events/MotionTrack.java index fd5e64fb0..29954525f 100644 --- a/engine/src/core/com/jme3/cinematic/events/MotionTrack.java +++ b/engine/src/core/com/jme3/cinematic/events/MotionTrack.java @@ -165,10 +165,12 @@ public class MotionTrack extends AbstractCinematicEvent implements Control { if (isControl) { if (playState == PlayState.Playing) { - time = (elapsedTimePause + timer.getTimeInSeconds() - start) * speed; - onUpdate(tpf); + time = time + (tpf * speed); + if (time >= initialDuration && loopMode == loopMode.DontLoop) { stop(); + } else { + onUpdate(tpf); } } } @@ -183,40 +185,12 @@ public class MotionTrack extends AbstractCinematicEvent implements Control { @Override public void setTime(float time) { super.setTime(time); - - //computing traveled distance according to new time - traveledDistance = time * (path.getLength() / initialDuration); - - TempVars vars = TempVars.get(); - Vector3f temp = vars.vect1; - //getting waypoint index and current value from new traveled distance - Vector2f v = path.getWayPointIndexForDistance(traveledDistance); - //setting values - currentWayPoint = (int) v.x; - setCurrentValue(v.y); - //interpolating new position - path.getSpline().interpolate(getCurrentValue(), getCurrentWayPoint(), temp); - //setting new position to the spatial - spatial.setLocalTranslation(temp); - vars.release(); + onUpdate(0); } - public void onUpdate(float tpf) { + public void onUpdate(float tpf) { traveledDistance = path.interpolatePath(time, this); computeTargetDirection(); - - if (currentValue >= 1.0f) { - currentValue = 0; - currentWayPoint++; - path.triggerWayPointReach(currentWayPoint, this); - } - if (currentWayPoint == path.getNbWayPoints() - 1) { - if (loopMode == LoopMode.Loop) { - currentWayPoint = 0; - } else { - stop(); - } - } } @Override @@ -346,7 +320,10 @@ public class MotionTrack extends AbstractCinematicEvent implements Control { * */ public void setCurrentWayPoint(int currentWayPoint) { - this.currentWayPoint = currentWayPoint; + if (this.currentWayPoint != currentWayPoint) { + this.currentWayPoint = currentWayPoint; + path.triggerWayPointReach(currentWayPoint, this); + } } /** diff --git a/engine/src/core/com/jme3/cinematic/events/SoundTrack.java b/engine/src/core/com/jme3/cinematic/events/SoundTrack.java index 477cfa234..77aae312b 100644 --- a/engine/src/core/com/jme3/cinematic/events/SoundTrack.java +++ b/engine/src/core/com/jme3/cinematic/events/SoundTrack.java @@ -48,7 +48,7 @@ import java.io.IOException; public class SoundTrack extends AbstractCinematicEvent { protected String path; - protected AudioNode audioNode; + protected AudioNode audioNode; protected boolean stream = false; /** @@ -82,7 +82,7 @@ public class SoundTrack extends AbstractCinematicEvent { } public SoundTrack(String path, boolean stream, float initialDuration, LoopMode loopMode) { - super(initialDuration, loopMode); + super(initialDuration, loopMode); this.path = path; this.stream = stream; } @@ -93,12 +93,12 @@ public class SoundTrack extends AbstractCinematicEvent { } public SoundTrack(String path, LoopMode loopMode) { - super(loopMode); + super(loopMode); this.path = path; } public SoundTrack(String path, float initialDuration, LoopMode loopMode) { - super(initialDuration, loopMode); + super(initialDuration, loopMode); this.path = path; } @@ -106,7 +106,7 @@ public class SoundTrack extends AbstractCinematicEvent { } @Override - public void initEvent(Application app, Cinematic cinematic) { + public void initEvent(Application app, Cinematic cinematic) { super.initEvent(app, cinematic); audioNode = new AudioNode(app.getAssetManager(), path, stream); setLoopMode(loopMode); @@ -115,23 +115,27 @@ public class SoundTrack extends AbstractCinematicEvent { @Override public void setTime(float time) { super.setTime(time); - //TODO has to be implemented in the audioRenderer + //can occur on rewind + if (time < 0) { + stop(); + } + audioNode.setTimeOffset(time); } @Override public void onPlay() { - audioNode.play(); + audioNode.play(); } @Override public void onStop() { audioNode.stop(); - + } @Override public void onPause() { - audioNode.pause(); + audioNode.pause(); } @Override @@ -152,7 +156,7 @@ public class SoundTrack extends AbstractCinematicEvent { @Override public void setLoopMode(LoopMode loopMode) { super.setLoopMode(loopMode); - + if (loopMode != LoopMode.DontLoop) { audioNode.setLooping(true); } else {