jME3 Cinematics

JME3 cinematics (com.jme.cinematic) allow you to remote control nodes and cameras in a 3D game. You use cinematics to script and record scenes. Use it for example to create cutscenes of your game.

Cinematics are implemented as AppStates. Attach the scene that you want to be visible in the cinematic to one Node. You create a Cinematic object, and add individual CinematicEvents to it.

Overview

Cinematic cinematic = new Cinematic(sceneNode, duration);
cinematic.addCinematicEvent(triggerTime, cinematicEvent);
  1. Create one Cinematic per scene.
    • sceneNode is the node containing the scene
    • duration is the duration of the cinematic scene in seconds
  2. Create CinematicEvents to script your "movie". Each Cinematic is a set of CinematicEvents, that are triggered at a given time.
    • cinematicEvent is the cinematic event. More details below.
    • triggerTime is the time when this particular cinematic event starts. Specify the start time in seconds since the beginning of the scene.
  3. Play and pause the Cinematic using cinematic.pause() and cinematic.play();

CinematicEvents

There are several kinds of cinematic events:

CinematicEventDescription
MotionTrackUse this to move a Spatial non-linearly over time. A motionPath is a list of several waypoints added to a MotionPath. The path is interpolated using Catmull-Rom Splines between waypoints.
PositionTrackUse this to move a Spatial linearly over time. It translates the Spatial to a destination in the given amount of time by linearly interpolating the positions.
RotationTrackUse this to change the rotation of a Spatial over time. It rotates the Spatial in the given amount of time by linearly interpolating the rotation.
ScaleTrackUse this to change the size of a Spatial over time. It scales the Spatial in the given amount of time by linearly interpolating the scale.
SoundTrackUse this to play a sound at a given time for the given duration.
GuiTrackDisplays a Nifty GUI at a given time for the given duration. Use it to display subtitles or HUD elements. Bind the Nifty GUI XML to the cinematic using cinematic.bindUi("path/to/nifty/file.xml");
AnimationTrackUse this to start playing a model animation at a given time (a character walking animation for example)

We will add more types of track implementions over time.

Each CinematicEvent supports the following methods to control the event.

CinematicEvent methodUsage
play()Starts playing the cinematic.
stop()Stops playing the cinematic.
pause()Pauses the cinematic.

Those methods, must be called on the Cinematic and are propagated to the events. Don't use them directly on a sub cinematic event

MotionTrack & MotionPath

A motion track is made up of MotionPaths.

MotionPath path = new MotionPath();
MotionPath Method Usage
setCycle(true)Sets whether the motion along this path should be closed (true) or not (false).
addWayPoint(vector)Adds individual waypoints to this path. The order is relevant.
removeWayPoint(vector)
removeWayPoint(index)
Removes individual waypoints from this path. You can specify a vector or the integer index.
setCurveTension(0.83f)Sets the tension of the curve (only for Catmull Rom Spline). A value of 0.0f will give a straight linear line, 1.0 a round curve.
enableDebugShape(assetManager,rootNode)Shows a line to visualize the path. Used for debugging.
disableDebugShape()Hides the line that visualizes the path. Used for debugging.
getNbWayPoints()Returns the number of waypoints in this path.
MotionTrack thingMotionControl = new MotionTrack(thingNode, path);
MotionTrack methodUsage
setLoopMode(LoopMode.Loop)Sets whether the animation along this path should loop (true) or play only once (false).
setDirectionType(MotionTrack.Direction.None)Sets the direction behavior type of the controled node. Direction.None deactivates this feature. See the following options:
setDirectionType(MotionTrack.Direction.LookAt)Rotate to keep facing a point. Specify the point with setLookAt().
setDirectionType(MotionTrack.Direction.Path)Face the direction of the path.
setDirectionType(MotionTrack.Direction.PathAndRotation)Face the direction of the path, plus an added rotation. Use together with the setRotation() method.
setDirectionType(MotionTrack.Direction.Rotation)Rotate while moving. Use together with the setRotation() method.
setLookAt(teapot.getWorldTranslation(), Vector3f.UNIT_Y)Optional: Make the moving face towards a certain location. Use together with setDirectionType().
setRotation(quaternion)Optional: Sets the rotation. Use together with MotionTrack.Direction.Rotation or MotionTrack.Direction.PathAndRotation.

MotionPathListener

You can register a MotionPathListener to the MotionPath to track whether waypoints have been reached, and then trigger a custom action. In this example we just print the status. The onWayPointReach() method of the interface gives you access to the MotionTrack object control, and an integer value representing the current wayPointIndex.

path.addListener( new MotionPathListener() {
  public void onWayPointReach(MotionTrack control, int wayPointIndex) {
    if (path.getNbWayPoints() == wayPointIndex + 1) {
      println(control.getSpatial().getName() + "Finished!!! ");
    } else {
      println(control.getSpatial().getName() + " Reached way point " + wayPointIndex);
    }
  }
});

PositionTrack

PositionTrack thingPositionControl = new PositionTrack(
    thingNode, endPosition,  duration, loopMode);

Details of the constructor:

The start location is always the current location of the Spatial.

RotationTrack

RotationTrack thingRotationControl = new RotationTrack(
    thingNode, endRotation,  duration, loopMode);

Details of the constructor:

ScaleTrack

ScaleTrack thingScaleControl = new ScaleTrack(
    thingNode, endScale,  duration, loopMode);

Details of the constructor:

SoundTrack

SoundTrack( audioPath, isStream, duration, loopMode )

Details of the constructor:

GuiTrack

GuiTrack( screen, duration, loopMode )

You must use this together with bindUI() to specify the Nifty GUI XML file that you want to load:

cinematic.bindUi("Interface/subtitle.xml");

Details of the constructor:

AnimationTrack

AnimationTrack( thingNode, animationName, duration, loopMode )

Details of the constructor:

Customizations

You can extend individual CinematicEvents. The SubtitleTrack.java example shows how to extend a GuiTrack to script subtitles. See how the subtitles are used in the TestCinematic.java example.

You can also create new CinematicEvent by extending AbstractCinematicEvent. An AbstractCinematicEvent implements the CinematicEvent interface and provides duration, time, speed, etc… management. Look at the TestCinematic.java example is to use this for a custom fadeIn/fadeOut effect in combination with a com.jme3.post.filters.FadeFilter.

Camera Handling

The camera management is handled as follows:

  1. Create a camera Node and bind the camera object to the cinematic. Note that we also give the camera node a name in this step.
    CameraNode camNode = cinematic.bindCamera("topView", cam);
  2. Position the camera node in its start location.
  3. Use activateCamera() to give the control of the camera to this node. You now see the scene from this camera's point of view. For example to see through the camera node named "top view", 6 seconds after the start of the cinematic, you'd write
    cinematic.activateCamera(6, "topView");
  4. If desired, attach the camNode to a MotionTrack to let it travel along waypoints. This is demonstrated in the TestCameraMotionPath.java example.

Code samples:

flyCam.setEnabled(false);
 
CameraNode camNodeTop = cinematic.bindCamera("topView", cam);
camNodeTop.setControlDir(ControlDirection.SpatialToCamera);
camNodeTop.getControl(0).setEnabled(false);
 
CameraNode camNodeSide = cinematic.bindCamera("sideView", cam);
camNodeSide.setControlDir(ControlDirection.CameraToSpatial);
camNodeSide.getControl(0).setEnabled(false);

Physics Interaction

Upcoming.

More Information

See also: Cinematics by Nehon

view online version