- Use quaternions and slerp for rotation track

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8432 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
rem..om 13 years ago
parent 2e5a0fda75
commit 298c052d24
  1. 39
      engine/src/core/com/jme3/cinematic/events/RotationTrack.java
  2. 8
      engine/src/test/jme3test/animation/TestCinematic.java

@ -11,9 +11,9 @@ 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 com.jme3.math.FastMath;
import com.jme3.math.Quaternion; import com.jme3.math.Quaternion;
import com.jme3.scene.Spatial; import com.jme3.scene.Spatial;
import com.jme3.util.TempVars;
import java.io.IOException; import java.io.IOException;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -25,8 +25,8 @@ import java.util.logging.Logger;
public class RotationTrack extends AbstractCinematicEvent { public class RotationTrack extends AbstractCinematicEvent {
private static final Logger log = Logger.getLogger(RotationTrack.class.getName()); private static final Logger log = Logger.getLogger(RotationTrack.class.getName());
private float[] startRotation; private Quaternion startRotation = new Quaternion();
private float[] endRotation; private Quaternion endRotation = new Quaternion();
private Spatial spatial; private Spatial spatial;
private String spatialName = ""; private String spatialName = "";
private float value = 0; private float value = 0;
@ -46,29 +46,29 @@ public class RotationTrack extends AbstractCinematicEvent {
public RotationTrack() { public RotationTrack() {
} }
public RotationTrack(Spatial spatial, float[] endRotation) { public RotationTrack(Spatial spatial, Quaternion endRotation) {
this.endRotation = endRotation; this.endRotation.set(endRotation);
this.spatial = spatial; this.spatial = spatial;
spatialName = spatial.getName(); spatialName = spatial.getName();
} }
public RotationTrack(Spatial spatial, float[] endRotation, float initialDuration, LoopMode loopMode) { public RotationTrack(Spatial spatial, Quaternion endRotation, float initialDuration, LoopMode loopMode) {
super(initialDuration, loopMode); super(initialDuration, loopMode);
this.endRotation = endRotation; this.endRotation.set(endRotation);
this.spatial = spatial; this.spatial = spatial;
spatialName = spatial.getName(); spatialName = spatial.getName();
} }
public RotationTrack(Spatial spatial, float[] endRotation, LoopMode loopMode) { public RotationTrack(Spatial spatial, Quaternion endRotation, LoopMode loopMode) {
super(loopMode); super(loopMode);
this.endRotation = endRotation; this.endRotation.set(endRotation);
this.spatial = spatial; this.spatial = spatial;
spatialName = spatial.getName(); spatialName = spatial.getName();
} }
public RotationTrack(Spatial spatial, float[] endRotation, float initialDuration) { public RotationTrack(Spatial spatial, Quaternion endRotation, float initialDuration) {
super(initialDuration); super(initialDuration);
this.endRotation = endRotation; this.endRotation.set(endRotation);
this.spatial = spatial; this.spatial = spatial;
spatialName = spatial.getName(); spatialName = spatial.getName();
} }
@ -76,10 +76,10 @@ public class RotationTrack extends AbstractCinematicEvent {
@Override @Override
public void onPlay() { public void onPlay() {
if (playState != playState.Paused) { if (playState != playState.Paused) {
startRotation = spatial.getWorldRotation().toAngles(null); startRotation.set(spatial.getWorldRotation());
} }
if (duration == 0 && spatial != null) { if (duration == 0 && spatial != null) {
spatial.setLocalRotation(new Quaternion().fromAngles(endRotation)); spatial.setLocalRotation(endRotation);
stop(); stop();
} }
} }
@ -88,11 +88,12 @@ public class RotationTrack extends AbstractCinematicEvent {
public void onUpdate(float tpf) { public void onUpdate(float tpf) {
if (spatial != null) { if (spatial != null) {
value += Math.min(tpf * speed / duration, 1.0f); value += Math.min(tpf * speed / duration, 1.0f);
float[] rot = new float[3]; TempVars vars = TempVars.get();
rot[0] = FastMath.interpolateLinear(value, startRotation[0], endRotation[0]); Quaternion q = vars.quat1;
rot[1] = FastMath.interpolateLinear(value, startRotation[1], endRotation[1]); q.set(startRotation).slerp(endRotation, value);
rot[2] = FastMath.interpolateLinear(value, startRotation[2], endRotation[2]);
spatial.setLocalRotation(new Quaternion().fromAngles(rot)); spatial.setLocalRotation(q);
vars.release();
} }
} }
@ -118,6 +119,6 @@ public class RotationTrack extends AbstractCinematicEvent {
super.read(im); super.read(im);
InputCapsule ic = im.getCapsule(this); InputCapsule ic = im.getCapsule(this);
spatialName = ic.readString("spatialName", ""); spatialName = ic.readString("spatialName", "");
endRotation = ic.readFloatArray("endRotation", null); endRotation = (Quaternion) ic.readSavable("endRotation", null);
} }
} }

@ -53,6 +53,7 @@ import com.jme3.light.DirectionalLight;
import com.jme3.material.Material; import com.jme3.material.Material;
import com.jme3.math.ColorRGBA; import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath; import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f; import com.jme3.math.Vector3f;
import com.jme3.post.FilterPostProcessor; import com.jme3.post.FilterPostProcessor;
import com.jme3.post.filters.FadeFilter; import com.jme3.post.filters.FadeFilter;
@ -123,13 +124,14 @@ public class TestCinematic extends SimpleApplication {
}); });
cinematic.addCinematicEvent(0, new PositionTrack(teapot, new Vector3f(10, 0, 10), 0)); cinematic.addCinematicEvent(0, new PositionTrack(teapot, new Vector3f(10, 0, 10), 0));
cinematic.addCinematicEvent(0, new ScaleTrack(teapot, new Vector3f(1, 1, 1), 0)); cinematic.addCinematicEvent(0, new ScaleTrack(teapot, new Vector3f(1, 1, 1), 0));
float[] rotation = {0, 0, 0}; Quaternion q = new Quaternion();
cinematic.addCinematicEvent(0, new RotationTrack(teapot, rotation, 0)); q.loadIdentity();
cinematic.addCinematicEvent(0, new RotationTrack(teapot, q, 0));
cinematic.addCinematicEvent(0, new PositionTrack(teapot, new Vector3f(10, 0, -10), 20)); cinematic.addCinematicEvent(0, new PositionTrack(teapot, new Vector3f(10, 0, -10), 20));
cinematic.addCinematicEvent(0, new ScaleTrack(teapot, new Vector3f(4, 4, 4), 10)); cinematic.addCinematicEvent(0, new ScaleTrack(teapot, new Vector3f(4, 4, 4), 10));
cinematic.addCinematicEvent(10, new ScaleTrack(teapot, new Vector3f(1, 1, 1), 10)); cinematic.addCinematicEvent(10, new ScaleTrack(teapot, new Vector3f(1, 1, 1), 10));
float[] rotation2 = {0, FastMath.TWO_PI, 0}; Quaternion rotation2 = new Quaternion().fromAngleAxis(FastMath.PI, Vector3f.UNIT_Y);
cinematic.addCinematicEvent(0, new RotationTrack(teapot, rotation2, 20)); cinematic.addCinematicEvent(0, new RotationTrack(teapot, rotation2, 20));
cinematic.activateCamera(0, "aroundCam"); cinematic.activateCamera(0, "aroundCam");

Loading…
Cancel
Save