Cinematics :
- One can now shift time forward an backward in a cinematic with the setTime(float) method, all sub cinematic events support it except soundtrack (has to be implemented) - Enhanced MotionPath calculation to allow time shifting, and made speed more constant - changed test cases accordingly - some more javadoc - fixed some problems in GUITrack git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8913 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
6152155c61
commit
08af19ec5b
@ -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<String, CameraNode> cameras = new HashMap<String, CameraNode>();
|
||||
private CameraNode currentCam;
|
||||
private boolean initialized = false;
|
||||
// private Nifty nifty = null;
|
||||
private Map<String, Map<String, Object>> 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<String, CameraNode>) 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<String, Map<String, Object>> getEventsData() {
|
||||
if (eventsData == null) {
|
||||
eventsData = new HashMap<String, Map<String, Object>>();
|
||||
|
@ -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());
|
||||
control.setCurrentValue(control.getCurrentValue() + eps);
|
||||
spline.interpolate(control.getCurrentValue(), control.getCurrentWayPoint(), temp);
|
||||
float dist = getDist(control,temp, tmpVector);
|
||||
//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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -89,6 +89,10 @@ public class TimeLine extends HashMap<Integer, KeyFrame> 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<KeyFrame> getAllKeyFrames() {
|
||||
return values();
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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() {
|
||||
//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() {
|
||||
// }
|
||||
// });
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<nifty xmlns="http://nifty-gui.sourceforge.net/nifty.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://nifty-gui.sourceforge.net/nifty.xsd http://nifty-gui.sourceforge.net/nifty.xsd">
|
||||
<screen id="start" controller="de.lessvoid.nifty.examples.helloworld.HelloWorldStartScreen">
|
||||
<nifty>
|
||||
<screen id="start" controller="jme3test.niftygui.TestNiftyGui">
|
||||
<layer id="layer" backgroundColor="#0000" childLayout="center">
|
||||
<panel id="panel" width="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" />
|
||||
</panel>
|
||||
</layer>
|
||||
|
Loading…
x
Reference in New Issue
Block a user