diff --git a/engine/src/core/com/jme3/cinematic/Cinematic.java b/engine/src/core/com/jme3/cinematic/Cinematic.java index ed05b9b2e..6a2746c80 100644 --- a/engine/src/core/com/jme3/cinematic/Cinematic.java +++ b/engine/src/core/com/jme3/cinematic/Cinematic.java @@ -37,11 +37,13 @@ import com.jme3.app.state.AppState; import com.jme3.app.state.AppStateManager; import com.jme3.cinematic.events.AbstractCinematicEvent; import com.jme3.cinematic.events.CinematicEvent; +import com.jme3.cinematic.events.CinematicEventListener; import com.jme3.export.*; import com.jme3.renderer.Camera; import com.jme3.renderer.RenderManager; import com.jme3.scene.CameraNode; import com.jme3.scene.Node; +import com.jme3.scene.control.CameraControl; import com.jme3.scene.control.CameraControl.ControlDirection; import java.io.IOException; import java.util.ArrayList; @@ -58,7 +60,6 @@ import java.util.logging.Logger; public class Cinematic extends AbstractCinematicEvent implements AppState { private static final Logger logger = Logger.getLogger(Application.class.getName()); - private String niftyXmlPath = null; private Node scene; protected TimeLine timeLine = new TimeLine(); private int lastFetchedKeyFrame = -1; @@ -66,8 +67,8 @@ public class Cinematic extends AbstractCinematicEvent implements AppState { private Map cameras = new HashMap(); private CameraNode currentCam; private boolean initialized = false; -// private Nifty nifty = null; private Map> eventsData; + private int scheduledPause = -1; public Cinematic() { } @@ -94,7 +95,8 @@ public class Cinematic extends AbstractCinematicEvent implements AppState { @Override public void onPlay() { if (isInitialized()) { - enableCurrentCam(true); + scheduledPause = -1; + //enableCurrentCam(true); if (playState == PlayState.Paused) { for (int i = 0; i < cinematicEvents.size(); i++) { CinematicEvent ce = cinematicEvents.get(i); @@ -125,7 +127,6 @@ public class Cinematic extends AbstractCinematicEvent implements AppState { ce.pause(); } } - enableCurrentCam(false); } @Override @@ -136,8 +137,6 @@ public class Cinematic extends AbstractCinematicEvent implements AppState { oc.writeSavableArrayList((ArrayList) cinematicEvents, "cinematicEvents", null); oc.writeStringSavableMap(cameras, "cameras", null); oc.write(timeLine, "timeLine", null); - oc.write(niftyXmlPath, "niftyXmlPath", null); - } @@ -149,12 +148,6 @@ public class Cinematic extends AbstractCinematicEvent implements AppState { cinematicEvents = ic.readSavableArrayList("cinematicEvents", null); cameras = (Map) ic.readStringSavableMap("cameras", null); timeLine = (TimeLine) ic.readSavable("timeLine", null); - niftyXmlPath = ic.readString("niftyXmlPath", null); - - } - - public void bindUi(String xmlPath) { - niftyXmlPath = xmlPath; } @Override @@ -169,22 +162,11 @@ public class Cinematic extends AbstractCinematicEvent implements AppState { } public void initialize(AppStateManager stateManager, Application app) { - if (niftyXmlPath != null) { -// NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(app.getAssetManager(), -// app.getInputManager(), -// app.getAudioRenderer(), -// app.getGuiViewPort()); -// nifty = niftyDisplay.getNifty(); -// nifty.fromXmlWithoutStartScreen(niftyXmlPath); -// app.getGuiViewPort().addProcessor(niftyDisplay); - } initEvent(app, this); for (CinematicEvent cinematicEvent : cinematicEvents) { cinematicEvent.initEvent(app, this); } - - initialized = true; } @@ -215,8 +197,22 @@ public class Cinematic extends AbstractCinematicEvent implements AppState { } } + private void step() { + if (playState != PlayState.Playing) { + play(); + scheduledPause = 2; + } + } + @Override public void onUpdate(float tpf) { + if (scheduledPause >= 0) { + if (scheduledPause == 0) { + pause(); + } + scheduledPause--; + } + for (int i = 0; i < cinematicEvents.size(); i++) { CinematicEvent ce = cinematicEvents.get(i); ce.internalUpdate(tpf); @@ -235,6 +231,28 @@ public class Cinematic extends AbstractCinematicEvent implements AppState { lastFetchedKeyFrame = keyFrameIndex; } + @Override + public void setTime(float time) { + super.setTime(time); + int keyFrameIndex = timeLine.getKeyFrameIndexFromTime(time); + + //triggering all the event from start to "time" + //then computing timeOffset for each event + for (int i = 0; i <= keyFrameIndex; i++) { + KeyFrame keyFrame = timeLine.get(i); + if (keyFrame != null) { + for (CinematicEvent ce : keyFrame.getCinematicEvents()) { + if (playState == PlayState.Playing) { + ce.play(); + } + ce.setTime(time - timeLine.getKeyFrameTime(keyFrame)); + } + } + } + + step(); + } + public KeyFrame addCinematicEvent(float timeStamp, CinematicEvent cinematicEvent) { KeyFrame keyFrame = timeLine.getKeyFrameAtTime(timeStamp); if (keyFrame == null) { @@ -255,6 +273,9 @@ public class Cinematic extends AbstractCinematicEvent implements AppState { public void cleanup() { } + /** + * fits the duration of the cinamatic to the duration of all its child cinematic events + */ public void fitDuration() { KeyFrame kf = timeLine.getKeyFrameAtTime(timeLine.getLastKeyFrameIndex()); float d = 0; @@ -271,7 +292,7 @@ public class Cinematic extends AbstractCinematicEvent implements AppState { public CameraNode bindCamera(String cameraName, Camera cam) { CameraNode node = new CameraNode(cameraName, cam); node.setControlDir(ControlDirection.SpatialToCamera); - node.getControl(0).setEnabled(false); + node.getControl(CameraControl.class).setEnabled(false); cameras.put(cameraName, node); scene.attachChild(node); return node; @@ -283,7 +304,7 @@ public class Cinematic extends AbstractCinematicEvent implements AppState { private void enableCurrentCam(boolean enabled) { if (currentCam != null) { - currentCam.getControl(0).setEnabled(enabled); + currentCam.getControl(CameraControl.class).setEnabled(enabled); } } @@ -296,13 +317,18 @@ public class Cinematic extends AbstractCinematicEvent implements AppState { enableCurrentCam(true); } - public void activateCamera(float timeStamp, final String cameraName) { + 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); - stop(); } @Override @@ -316,6 +342,11 @@ public class Cinematic extends AbstractCinematicEvent implements AppState { @Override public void onPause() { } + + @Override + public void setTime(float time) { + play(); + } }); } @@ -323,10 +354,6 @@ public class Cinematic extends AbstractCinematicEvent implements AppState { this.scene = scene; } -// public Nifty getNifty() { -// return nifty; -// } - private Map> getEventsData() { if (eventsData == null) { eventsData = new HashMap>(); diff --git a/engine/src/core/com/jme3/cinematic/MotionPath.java b/engine/src/core/com/jme3/cinematic/MotionPath.java index 7c2584c16..1f7cdc9ce 100644 --- a/engine/src/core/com/jme3/cinematic/MotionPath.java +++ b/engine/src/core/com/jme3/cinematic/MotionPath.java @@ -38,6 +38,7 @@ import com.jme3.material.Material; import com.jme3.math.ColorRGBA; import com.jme3.math.Spline; import com.jme3.math.Spline.SplineType; +import com.jme3.math.Vector2f; import com.jme3.math.Vector3f; import com.jme3.scene.Geometry; import com.jme3.scene.Node; @@ -68,39 +69,60 @@ public class MotionPath implements Savable { } /** - * interpolate the path giving the tpf and the motionControl + * interpolate the path giving the time since the beginnin and the motionControl * this methods sets the new localTranslation to the spatial of the motionTrack control. - * @param tpf - * @param control + * @param time the time since the animation started + * @param control the ocntrol over the moving spatial */ - public void interpolatePath(float tpf, MotionTrack control) { + public float interpolatePath(float time, MotionTrack control) { float val; + float traveledDistance = 0; TempVars vars = TempVars.get(); Vector3f temp = vars.vect1; Vector3f tmpVector = vars.vect2; switch (spline.getType()) { case CatmullRom: - val = tpf * (spline.getTotalLength() / control.getDuration()); + //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); - float dist = getDist(control,temp, tmpVector); + //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); + 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: - val = control.getDuration() * spline.getSegmentsLength().get(control.getCurrentWayPoint()) / spline.getTotalLength(); - control.setCurrentValue(Math.min(control.getCurrentValue() + tpf / val, 1.0f)); + //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()); @@ -111,11 +133,19 @@ public class MotionPath implements Savable { } control.getSpatial().setLocalTranslation(temp); vars.release(); + return traveledDistance; } - private float getDist(MotionTrack control,Vector3f temp, Vector3f tmpVector) { - tmpVector.set(temp); - return tmpVector.subtractLocal(control.getSpatial().getLocalTranslation()).length(); + /** + * computes the distance between the spatial position and the temp vector. + * @param control the control holding the psatial + * @param temp the temp position + * @param store a temp vector3f to store the result + * @return + */ + private float getDist(MotionTrack control, Vector3f temp, Vector3f store) { + store.set(temp); + return store.subtractLocal(control.getSpatial().getLocalTranslation()).length(); } private void attachDebugNode(Node root) { @@ -178,6 +208,26 @@ public class MotionPath implements Savable { } + /** + * compute the index of the waypoint and the interpolation value according to a distance + * returns a vector 2 containing the index in the x field and the interpolation value in the y field + * @param distance the distance traveled on this path + * @return the waypoint index and the interpolation value in a vector2 + */ + public Vector2f getWayPointIndexForDistance(float distance) { + float sum = 0; + distance = distance % spline.getTotalLength(); + int i = 0; + for (Float len : spline.getSegmentsLength()) { + if (sum + len >= distance) { + return new Vector2f((float) i, (distance - sum) / len); + } + sum += len; + i++; + } + return new Vector2f((float) spline.getControlPoints().size() - 1, 1.0f); + } + /** * Addsa waypoint to the path * @param wayPoint a position in world space @@ -332,10 +382,10 @@ public class MotionPath implements Savable { } } - public void clearWayPoints(){ + public void clearWayPoints() { spline.clearControlPoints(); } - + /** * Sets the path to be a cycle * @param cycle @@ -360,4 +410,8 @@ public class MotionPath implements Savable { public boolean isCycle() { return spline.isCycle(); } + + public Spline getSpline() { + return spline; + } } diff --git a/engine/src/core/com/jme3/cinematic/TimeLine.java b/engine/src/core/com/jme3/cinematic/TimeLine.java index 70e1522e2..ae3e06dfe 100644 --- a/engine/src/core/com/jme3/cinematic/TimeLine.java +++ b/engine/src/core/com/jme3/cinematic/TimeLine.java @@ -89,6 +89,10 @@ public class TimeLine extends HashMap implements Savable { public int getKeyFrameIndexFromTime(float time) { return Math.round(time * keyFramesPerSeconds); } + + public float getKeyFrameTime(KeyFrame keyFrame) { + return (float)keyFrame.getIndex()/(float)keyFramesPerSeconds; + } public Collection getAllKeyFrames() { return values(); diff --git a/engine/src/core/com/jme3/cinematic/events/AbstractCinematicEvent.java b/engine/src/core/com/jme3/cinematic/events/AbstractCinematicEvent.java index 74e644843..8ceac9275 100644 --- a/engine/src/core/com/jme3/cinematic/events/AbstractCinematicEvent.java +++ b/engine/src/core/com/jme3/cinematic/events/AbstractCinematicEvent.java @@ -320,4 +320,23 @@ public abstract class AbstractCinematicEvent implements CinematicEvent { public void removeListener(CinematicEventListener listener) { getListeners().remove(listener); } + + /** + * 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) { + elapsedTimePause = time/speed; + if(playState == PlayState.Playing){ + start = timer.getTimeInSeconds(); + } + } + + public float getTime() { + return time; + } + + + + } diff --git a/engine/src/core/com/jme3/cinematic/events/AnimationTrack.java b/engine/src/core/com/jme3/cinematic/events/AnimationTrack.java index 3e4889e09..fb6ccf2ed 100644 --- a/engine/src/core/com/jme3/cinematic/events/AnimationTrack.java +++ b/engine/src/core/com/jme3/cinematic/events/AnimationTrack.java @@ -103,12 +103,33 @@ public class AnimationTrack extends AbstractCinematicEvent { } } + @Override + public void setTime(float time) { + super.setTime(time); + float t = time; + if(loopMode == loopMode.Loop){ + t = t % channel.getAnimMaxTime(); + } + if(loopMode == loopMode.Cycle){ + float parity = (float)Math.ceil(time / channel.getAnimMaxTime()); + if(parity >0 && parity%2 ==0){ + t = channel.getAnimMaxTime() - t % channel.getAnimMaxTime(); + }else{ + t = t % channel.getAnimMaxTime(); + } + + } + channel.setTime(t); + } + @Override public void onPlay() { channel.getControl().setEnabled(true); if (playState == PlayState.Stopped) { channel.setAnim(animationName); channel.setSpeed(speed); + channel.setLoopMode(loopMode); + channel.setTime(time); } } diff --git a/engine/src/core/com/jme3/cinematic/events/CinematicEvent.java b/engine/src/core/com/jme3/cinematic/events/CinematicEvent.java index 0cccac535..b9aebdab9 100644 --- a/engine/src/core/com/jme3/cinematic/events/CinematicEvent.java +++ b/engine/src/core/com/jme3/cinematic/events/CinematicEvent.java @@ -60,7 +60,7 @@ public interface CinematicEvent extends Savable { /** * Returns the actual duration of the animation - * @return + * @return the duration */ public float getDuration(); @@ -72,13 +72,13 @@ public interface CinematicEvent extends Savable { /** * returns the speed of the animation - * @return + * @return the speed */ public float getSpeed(); /** * returns the PlayState of the animation - * @return + * @return the plat state */ public PlayState getPlayState(); @@ -104,7 +104,7 @@ public interface CinematicEvent extends Savable { /** * returns the initial duration of the animation at speed = 1 in seconds. - * @return + * @return the initial duration */ public float getInitialDuration(); @@ -114,8 +114,30 @@ public interface CinematicEvent extends Savable { */ public void setInitialDuration(float initialDuration); + /** + * called internally in the update method, place here anything you want to run in the update loop + * @param tpf time per frame + */ public void internalUpdate(float tpf); + /** + * initialize this event + * @param app the application + * @param cinematic the cinematic + */ public void initEvent(Application app, Cinematic cinematic); - + + /** + * 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); + + /** + * returns the current time of the cinematic event + * @return the time + */ + public float getTime(); + + } diff --git a/engine/src/core/com/jme3/cinematic/events/MotionTrack.java b/engine/src/core/com/jme3/cinematic/events/MotionTrack.java index 50c17857d..6ffd7bac4 100644 --- a/engine/src/core/com/jme3/cinematic/events/MotionTrack.java +++ b/engine/src/core/com/jme3/cinematic/events/MotionTrack.java @@ -41,11 +41,13 @@ import com.jme3.export.JmeExporter; import com.jme3.export.JmeImporter; import com.jme3.export.OutputCapsule; import com.jme3.math.Quaternion; +import com.jme3.math.Vector2f; import com.jme3.math.Vector3f; import com.jme3.renderer.RenderManager; import com.jme3.renderer.ViewPort; import com.jme3.scene.Spatial; import com.jme3.scene.control.Control; +import com.jme3.util.TempVars; import java.io.IOException; /** @@ -67,6 +69,11 @@ public class MotionTrack extends AbstractCinematicEvent implements Control { protected Direction directionType = Direction.None; protected MotionPath path; private boolean isControl = true; + + /** + * the distance traveled by the spatial on the path + */ + protected float traveledDistance = 0; /** @@ -167,18 +174,39 @@ public class MotionTrack extends AbstractCinematicEvent implements Control { } } } - } @Override public void initEvent(Application app, Cinematic cinematic) { super.initEvent(app, cinematic); isControl = false; - // timer = null; } + @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(); + } + + + public void onUpdate(float tpf) { - path.interpolatePath(tpf * speed, this); + traveledDistance = path.interpolatePath(time, this); computeTargetDirection(); if (currentValue >= 1.0f) { @@ -192,7 +220,7 @@ public class MotionTrack extends AbstractCinematicEvent implements Control { } else { stop(); } - } + } } @Override @@ -423,4 +451,14 @@ public class MotionTrack extends AbstractCinematicEvent implements Control { public Spatial getSpatial() { return spatial; } + + /** + * return the distance traveled by the spatial on the path + * @return + */ + public float getTraveledDistance() { + return traveledDistance; + } + + } diff --git a/engine/src/core/com/jme3/cinematic/events/SoundTrack.java b/engine/src/core/com/jme3/cinematic/events/SoundTrack.java index b2761b84f..477cfa234 100644 --- a/engine/src/core/com/jme3/cinematic/events/SoundTrack.java +++ b/engine/src/core/com/jme3/cinematic/events/SoundTrack.java @@ -110,13 +110,17 @@ public class SoundTrack extends AbstractCinematicEvent { super.initEvent(app, cinematic); audioNode = new AudioNode(app.getAssetManager(), path, stream); setLoopMode(loopMode); + } + @Override + public void setTime(float time) { + super.setTime(time); + //TODO has to be implemented in the audioRenderer } @Override public void onPlay() { - audioNode.play(); - + audioNode.play(); } @Override diff --git a/engine/src/core/com/jme3/post/filters/FadeFilter.java b/engine/src/core/com/jme3/post/filters/FadeFilter.java index 902bc8901..1fb234074 100644 --- a/engine/src/core/com/jme3/post/filters/FadeFilter.java +++ b/engine/src/core/com/jme3/post/filters/FadeFilter.java @@ -136,6 +136,10 @@ public class FadeFilter extends Filter { } + public void pause() { + playing = false; + } + @Override public void write(JmeExporter ex) throws IOException { super.write(ex); @@ -165,6 +169,9 @@ public class FadeFilter extends Filter { * @param value */ public void setValue(float value) { - this.value = value; + this.value = value; + if (material != null) { + material.setFloat("Value", value); + } } } diff --git a/engine/src/niftygui/com/jme3/cinematic/events/GuiTrack.java b/engine/src/niftygui/com/jme3/cinematic/events/GuiTrack.java index 95372fdc0..281c4507b 100644 --- a/engine/src/niftygui/com/jme3/cinematic/events/GuiTrack.java +++ b/engine/src/niftygui/com/jme3/cinematic/events/GuiTrack.java @@ -52,36 +52,34 @@ public class GuiTrack extends AbstractCinematicEvent { public GuiTrack() { } - + public GuiTrack(Nifty nifty, String screen) { this.screen = screen; + this.nifty = nifty; } public GuiTrack(Nifty nifty, String screen, float initialDuration) { super(initialDuration); this.screen = screen; - + this.nifty = nifty; } public GuiTrack(Nifty nifty, String screen, LoopMode loopMode) { super(loopMode); this.screen = screen; + this.nifty = nifty; } public GuiTrack(Nifty nifty, String screen, float initialDuration, LoopMode loopMode) { super(initialDuration, loopMode); this.screen = screen; - } - - @Override - public void initEvent(Application app, Cinematic cinematic) { - super.initEvent(app, cinematic); -// nifty = cinematic.getNifty(); + this.nifty = nifty; } @Override public void onPlay() { - nifty.gotoScreen(screen); + System.out.println("screen should be "+screen); + nifty.gotoScreen(screen); } @Override diff --git a/engine/src/test/jme3test/animation/TestCinematic.java b/engine/src/test/jme3test/animation/TestCinematic.java index 1b3958575..978e23792 100644 --- a/engine/src/test/jme3test/animation/TestCinematic.java +++ b/engine/src/test/jme3test/animation/TestCinematic.java @@ -57,7 +57,6 @@ import com.jme3.scene.Geometry; import com.jme3.scene.Spatial; import com.jme3.scene.shape.Box; import com.jme3.shadow.PssmShadowRenderer; -import com.jme3.system.NanoTimer; import de.lessvoid.nifty.Nifty; public class TestCinematic extends SimpleApplication { @@ -70,6 +69,7 @@ public class TestCinematic extends SimpleApplication { private ChaseCamera chaseCam; private FilterPostProcessor fpp; private FadeFilter fade; + private float time = 0; public static void main(String[] args) { TestCinematic app = new TestCinematic(); @@ -101,33 +101,13 @@ public class TestCinematic extends SimpleApplication { createScene(); cinematic = new Cinematic(rootNode, 20); -// cinematic.bindUi("Interface/Nifty/CinematicTest.xml"); stateManager.attach(cinematic); createCameraMotion(); - cinematic.addCinematicEvent(0, new AbstractCinematicEvent() { - - @Override - public void onPlay() { - fade.setDuration(1f / cinematic.getSpeed()); - fade.setValue(0); - fade.fadeIn(); - } - - @Override - public void onUpdate(float tpf) { - } - - @Override - public void onStop() { - } - - @Override - public void onPause() { - } - }); + //fade in + cinematic.addCinematicEvent(0, new FadeEvent(true)); cinematic.addCinematicEvent(0, new PositionTrack(teapot, new Vector3f(10, 0, 10), 0)); cinematic.addCinematicEvent(0, new ScaleTrack(teapot, new Vector3f(1, 1, 1), 0)); Quaternion q = new Quaternion(); @@ -143,46 +123,45 @@ public class TestCinematic extends SimpleApplication { cinematic.activateCamera(0, "aroundCam"); cinematic.addCinematicEvent(0, cameraMotionTrack); cinematic.addCinematicEvent(0, new SoundTrack("Sound/Environment/Nature.ogg", LoopMode.Loop)); - cinematic.addCinematicEvent(3, new SoundTrack("Sound/Effects/kick.wav")); + cinematic.addCinematicEvent(3f, new SoundTrack("Sound/Effects/kick.wav")); cinematic.addCinematicEvent(3, new SubtitleTrack(nifty, "start", 3, "jMonkey engine really kicks A...")); - cinematic.addCinematicEvent(5.0f, new SoundTrack("Sound/Effects/Beep.ogg", 1)); - cinematic.addCinematicEvent(6, new AnimationTrack(model, "Walk", LoopMode.Loop)); + cinematic.addCinematicEvent(5.1f, new SoundTrack("Sound/Effects/Beep.ogg", 1)); + cinematic.addCinematicEvent(2, new AnimationTrack(model, "Walk", LoopMode.Loop)); cinematic.activateCamera(6, "topView"); cinematic.activateCamera(10, "aroundCam"); - cinematic.addCinematicEvent(19, new AbstractCinematicEvent() { - - @Override - public void onPlay() { - fade.setDuration(1f / cinematic.getSpeed()); - fade.fadeOut(); - } - - @Override - public void onUpdate(float tpf) { - } - - @Override - public void onStop() { - } - - @Override - public void onPause() { - } - }); + //fade out + cinematic.addCinematicEvent(19, new FadeEvent(false)); +// cinematic.addCinematicEvent(19, new AbstractCinematicEvent() { +// +// @Override +// public void onPlay() { +// fade.setDuration(1f / cinematic.getSpeed()); +// fade.fadeOut(); +// +// } +// +// @Override +// public void onUpdate(float tpf) { +// } +// +// @Override +// public void onStop() { +// } +// +// @Override +// public void onPause() { +// } +// }); - final NanoTimer myTimer = new NanoTimer(); cinematic.addListener(new CinematicEventListener() { public void onPlay(CinematicEvent cinematic) { chaseCam.setEnabled(false); - myTimer.reset(); - System.out.println("play"); } public void onPause(CinematicEvent cinematic) { - chaseCam.setEnabled(true); System.out.println("pause"); } @@ -190,12 +169,10 @@ public class TestCinematic extends SimpleApplication { chaseCam.setEnabled(true); fade.setValue(1); System.out.println("stop"); - System.out.println((float) myTimer.getTime() / (float) myTimer.getResolution()); - } }); - cinematic.setSpeed(2); + //cinematic.setSpeed(2); flyCam.setEnabled(false); chaseCam = new ChaseCamera(cam, model, inputManager); initInputs(); @@ -269,19 +246,90 @@ public class TestCinematic extends SimpleApplication { private void initInputs() { inputManager.addMapping("togglePause", new KeyTrigger(keyInput.KEY_RETURN)); + inputManager.addMapping("navFwd", new KeyTrigger(keyInput.KEY_RIGHT)); + inputManager.addMapping("navBack", new KeyTrigger(keyInput.KEY_LEFT)); 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(); + time = cinematic.getTime(); } else { cinematic.play(); } } + if (cinematic.getPlayState() != PlayState.Playing) { + if (name.equals("navFwd") && keyPressed) { + time += 0.25; + FastMath.clamp(time, 0, cinematic.getInitialDuration()); + cinematic.setTime(time); + } + if (name.equals("navBack") && keyPressed) { + time -= 0.25; + FastMath.clamp(time, 0, cinematic.getInitialDuration()); + cinematic.setTime(time); + } + + } } }; - inputManager.addListener(acl, "togglePause"); + inputManager.addListener(acl, "togglePause", "navFwd", "navBack"); + } + + private class FadeEvent extends AbstractCinematicEvent { + + boolean in = true; + float value = 0; + + public FadeEvent(boolean in) { + super(1); + this.in = in; + value = in ? 0 : 1; + } + + @Override + public void onPlay() { + + fade.setDuration(1f / cinematic.getSpeed()); + if (in) { + fade.fadeIn(); + } else { + fade.fadeOut(); + } + fade.setValue(value); + + } + + @Override + public void setTime(float time) { + super.setTime(time); + if (time >= fade.getDuration()) { + value = in ? 1 : 0; + fade.setValue(value); + } else { + value = time; + if (in) { + fade.setValue(time / cinematic.getSpeed()); + } else { + fade.setValue(1 - time / cinematic.getSpeed()); + } + } + } + + @Override + public void onUpdate(float tpf) { + } + + @Override + public void onStop() { + } + + @Override + public void onPause() { + value = fade.getValue(); + fade.pause(); + } } } diff --git a/engine/src/test/jme3test/animation/TestMotionPath.java b/engine/src/test/jme3test/animation/TestMotionPath.java index 3adcece6e..50cafb2bb 100644 --- a/engine/src/test/jme3test/animation/TestMotionPath.java +++ b/engine/src/test/jme3test/animation/TestMotionPath.java @@ -83,7 +83,7 @@ public class TestMotionPath extends SimpleApplication { motionControl.setDirectionType(MotionTrack.Direction.PathAndRotation); motionControl.setRotation(new Quaternion().fromAngleNormalAxis(-FastMath.HALF_PI, Vector3f.UNIT_Y)); motionControl.setInitialDuration(10f); - motionControl.setSpeed(0.1f); + motionControl.setSpeed(2f); guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt"); final BitmapText wayPointsText = new BitmapText(guiFont, false); diff --git a/engine/test-data/Interface/Nifty/CinematicTest.xml b/engine/test-data/Interface/Nifty/CinematicTest.xml index 46e681257..a4aaeaf5b 100644 --- a/engine/test-data/Interface/Nifty/CinematicTest.xml +++ b/engine/test-data/Interface/Nifty/CinematicTest.xml @@ -1,8 +1,8 @@ - - + + - +