Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # This patch file was generated by NetBeans IDE
- # Following Index: paths are relative to: D:\SHARE\jMonkeyProjects\trunk\engine\src
- # This patch can be applied using context Tools: Patch action on respective folder.
- # It uses platform neutral UTF-8 encoding and \n newlines.
- # Above lines and this line are ignored by the patching process.
- Index: core/com/jme3/animation/AnimationBuilder.java
- --- core/com/jme3/animation/AnimationBuilder.java Nenhuma Revisão de Base
- +++ core/com/jme3/animation/AnimationBuilder.java Novo Localmente
- @@ -0,0 +1,496 @@
- +/*
- + * Copyright (c) 2009-2012 jMonkeyEngine
- + * All rights reserved.
- + *
- + * Redistribution and use in source and binary forms, with or without
- + * modification, are permitted provided that the following conditions are
- + * met:
- + *
- + * * Redistributions of source code must retain the above copyright
- + * notice, this list of conditions and the following disclaimer.
- + *
- + * * Redistributions in binary form must reproduce the above copyright
- + * notice, this list of conditions and the following disclaimer in the
- + * documentation and/or other materials provided with the distribution.
- + *
- + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- + * may be used to endorse or promote products derived from this software
- + * without specific prior written permission.
- + *
- + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- + */
- +package com.jme3.animation;
- +
- +import com.jme3.math.FastMath;
- +import com.jme3.math.Quaternion;
- +import com.jme3.math.Transform;
- +import com.jme3.math.Vector3f;
- +
- +/**
- + * A convenience class to easily setup a spatial keyframed animation
- + * you can add some keyFrames for a given time or a given keyFrameIndex, for translation rotation and scale.
- + * The animationBuilder will then generate an appropriate SpatialAnimation by interpolating values between the keyFrames.
- + * <br><br>
- + * Usage is : <br>
- + * - Create the AnimationBuilder<br>
- + * - add some keyFrames<br>
- + * - call the build() method that will return new Animation<br>
- + * - add the generated Animation to any existing AnimationControl<br>
- + * <br><br>
- + * Note that the first keyFrame (index 0) is defaulted with the identy transforms.
- + * If you want to change that you have to replace this keyFrame with any transform you want.
- + *
- + * @author Nehon
- + */
- +public class AnimationBuilder {
- +
- + /**
- + * step for splitting rotation that have a n angle above PI/2
- + */
- + private final static float EULER_STEP = FastMath.QUARTER_PI * 3;
- +
- + /**
- + * enum to determine the type of interpolation
- + */
- + private enum Type {
- +
- + Translation, Rotation, Scale;
- + }
- +
- + /**
- + * Inner Rotation type class to keep track on a rotation Euler angle
- + */
- + protected class Rotation {
- +
- + /**
- + * The rotation Quaternion
- + */
- + Quaternion rotation = new Quaternion();
- + /**
- + * This rotation expressed in Euler angles
- + */
- + Vector3f eulerAngles = new Vector3f();
- + /**
- + * the index of the parent key frame is this keyFrame is a splitted rotation
- + */
- + int masterKeyFrame = -1;
- +
- + public Rotation() {
- + rotation.loadIdentity();
- + }
- +
- + void set(Quaternion rot) {
- + rotation.set(rot);
- + float[] a = new float[3];
- + rotation.toAngles(a);
- + eulerAngles.set(a[0], a[1], a[2]);
- + }
- +
- + void set(float x, float y, float z) {
- + float[] a = {x, y, z};
- + rotation.fromAngles(a);
- + eulerAngles.set(x, y, z);
- + }
- + }
- + /**
- + * Name of the animation
- + */
- + protected String name;
- + /**
- + * frames per seconds
- + */
- + protected int fps;
- + /**
- + * Animation duration in seconds
- + */
- + protected float duration;
- + /**
- + * total number of frames
- + */
- + protected int totalFrames;
- + /**
- + * time per frame
- + */
- + protected float tpf;
- + /**
- + * Time array for this animation
- + */
- + protected float[] times;
- + /**
- + * Translation array for this animation
- + */
- + protected Vector3f[] translations;
- + /**
- + * rotation array for this animation
- + */
- + protected Quaternion[] rotations;
- + /**
- + * scales array for this animation
- + */
- + protected Vector3f[] scales;
- + /**
- + * The map of keyFrames to compute the animation. The key is the index of the frame
- + */
- + protected Vector3f[] keyFramesTranslation;
- + protected Vector3f[] keyFramesScale;
- + protected Rotation[] keyFramesRotation;
- +
- + /**
- + * Creates an AnimationBuilder
- + * @param duration the desired duration for the resulting animation
- + * @param name the name of the resulting animation
- + */
- + public AnimationBuilder(float duration, String name) {
- + this(duration, name, 30);
- + }
- +
- + /**
- + * Creates an AnimationBuilder
- + * @param duration the desired duration for the resulting animation
- + * @param name the name of the resulting animation
- + * @param fps the number of frames per second for this animation (default is 30)
- + */
- + public AnimationBuilder(float duration, String name, int fps) {
- + this.name = name;
- + this.duration = duration;
- + this.fps = fps;
- + totalFrames = (int) (fps * duration) + 1;
- + tpf = 1 / (float) fps;
- + times = new float[totalFrames];
- + translations = new Vector3f[totalFrames];
- + rotations = new Quaternion[totalFrames];
- + scales = new Vector3f[totalFrames];
- + keyFramesTranslation = new Vector3f[totalFrames];
- + keyFramesTranslation[0] = new Vector3f();
- + keyFramesScale = new Vector3f[totalFrames];
- + keyFramesScale[0] = new Vector3f(1, 1, 1);
- + keyFramesRotation = new Rotation[totalFrames];
- + keyFramesRotation[0] = new Rotation();
- +
- + }
- +
- + /**
- + * Adds a key frame for the given Transform at the given time
- + * @param time the time at which the keyFrame must be inserted
- + * @param transform the transforms to use for this keyFrame
- + */
- + public void addTimeTransform(float time, Transform transform) {
- + addKeyFrameTransform((int) (time / tpf), transform);
- + }
- +
- + /**
- + * Adds a key frame for the given Transform at the given keyFrame index
- + * @param keyFrameIndex the index at which the keyFrame must be inserted
- + * @param transform the transforms to use for this keyFrame
- + */
- + public void addKeyFrameTransform(int keyFrameIndex, Transform transform) {
- + addKeyFrameTranslation(keyFrameIndex, transform.getTranslation());
- + addKeyFrameScale(keyFrameIndex, transform.getScale());
- + addKeyFrameRotation(keyFrameIndex, transform.getRotation());
- + }
- +
- + /**
- + * Adds a key frame for the given translation at the given time
- + * @param time the time at which the keyFrame must be inserted
- + * @param translation the translation to use for this keyFrame
- + */
- + public void addTimeTranslation(float time, Vector3f translation) {
- + addKeyFrameTranslation((int) (time / tpf), translation);
- + }
- +
- + /**
- + * Adds a key frame for the given translation at the given keyFrame index
- + * @param keyFrameIndex the index at which the keyFrame must be inserted
- + * @param translation the translation to use for this keyFrame
- + */
- + public void addKeyFrameTranslation(int keyFrameIndex, Vector3f translation) {
- + Vector3f t = getTranslationForFrame(keyFrameIndex);
- + t.set(translation);
- + }
- +
- + /**
- + * Adds a key frame for the given rotation at the given time<br>
- + * This can't be used if the interpolated angle is higher than PI (180°)<br>
- + * Use {@link #addTimeRotationAngles(float time, float x, float y, float z)} instead that uses Euler angles rotations.<br> *
- + * @param time the time at which the keyFrame must be inserted
- + * @param rotation the rotation Quaternion to use for this keyFrame
- + * @see #addTimeRotationAngles(float time, float x, float y, float z)
- + */
- + public void addTimeRotation(float time, Quaternion rotation) {
- + addKeyFrameRotation((int) (time / tpf), rotation);
- + }
- +
- + /**
- + * Adds a key frame for the given rotation at the given keyFrame index<br>
- + * This can't be used if the interpolated angle is higher than PI (180°)<br>
- + * Use {@link #addKeyFrameRotationAngles(int keyFrameIndex, float x, float y, float z)} instead that uses Euler angles rotations.
- + * @param keyFrameIndex the index at which the keyFrame must be inserted
- + * @param rotation the rotation Quaternion to use for this keyFrame
- + * @see #addKeyFrameRotationAngles(int keyFrameIndex, float x, float y, float z)
- + */
- + public void addKeyFrameRotation(int keyFrameIndex, Quaternion rotation) {
- + Rotation r = getRotationForFrame(keyFrameIndex);
- + r.set(rotation);
- + }
- +
- + /**
- + * Adds a key frame for the given rotation at the given time.<br>
- + * Rotation is expressed by Euler angles values in radians.<br>
- + * Note that the generated rotation will be stored as a quaternion and interpolated using a spherical linear interpolation (slerp)<br>
- + * Hence, this method may create intermediate keyFrames if the interpolation angle is higher than PI to ensure continuity in animation<br>
- + *
- + * @param time the time at which the keyFrame must be inserted
- + * @param x the rotation around the x axis (aka yaw) in radians
- + * @param y the rotation around the y axis (aka roll) in radians
- + * @param z the rotation around the z axis (aka pitch) in radians
- + */
- + public void addTimeRotationAngles(float time, float x, float y, float z) {
- + addKeyFrameRotationAngles((int) (time / tpf), x, y, z);
- + }
- +
- + /**
- + * Adds a key frame for the given rotation at the given key frame index.<br>
- + * Rotation is expressed by Euler angles values in radians.<br>
- + * Note that the generated rotation will be stored as a quaternion and interpolated using a spherical linear interpolation (slerp)<br>
- + * Hence, this method may create intermediate keyFrames if the interpolation angle is higher than PI to ensure continuity in animation<br>
- + *
- + * @param keyFrameIndex the index at which the keyFrame must be inserted
- + * @param x the rotation around the x axis (aka yaw) in radians
- + * @param y the rotation around the y axis (aka roll) in radians
- + * @param z the rotation around the z axis (aka pitch) in radians
- + */
- + public void addKeyFrameRotationAngles(int keyFrameIndex, float x, float y, float z) {
- + Rotation r = getRotationForFrame(keyFrameIndex);
- + r.set(x, y, z);
- +
- + // if the delta of euler angles is higher than PI, we create intermediate keyframes
- + // since we are using quaternions and slerp for rotation interpolation, we cannot interpolate over an angle higher than PI
- + int prev = getPreviousKeyFrame(keyFrameIndex, keyFramesRotation);
- + if (prev != -1) {
- + //previous rotation keyframe
- + Rotation prevRot = keyFramesRotation[prev];
- + //the maximum delta angle (x,y or z)
- + float delta = Math.max(Math.abs(x - prevRot.eulerAngles.x), Math.abs(y - prevRot.eulerAngles.y));
- + delta = Math.max(delta, Math.abs(z - prevRot.eulerAngles.z));
- + //if delta > PI we have to create intermediates key frames
- + if (delta >= FastMath.PI) {
- + //frames delta
- + int dF = keyFrameIndex - prev;
- + //angle per frame for x,y ,z
- + float dXAngle = (x - prevRot.eulerAngles.x) / (float) dF;
- + float dYAngle = (y - prevRot.eulerAngles.y) / (float) dF;
- + float dZAngle = (z - prevRot.eulerAngles.z) / (float) dF;
- +
- + // the keyFrame step
- + int keyStep = (int) (((float) (dF)) / delta * (float) EULER_STEP);
- + // the current keyFrame
- + int cursor = prev + keyStep;
- + while (cursor < keyFrameIndex) {
- + //for each step we create a new rotation by interpolating the angles
- + Rotation dr = getRotationForFrame(cursor);
- + dr.masterKeyFrame = keyFrameIndex;
- + dr.set(prevRot.eulerAngles.x + cursor * dXAngle, prevRot.eulerAngles.y + cursor * dYAngle, prevRot.eulerAngles.z + cursor * dZAngle);
- + cursor += keyStep;
- + }
- +
- + }
- + }
- +
- + }
- +
- + /**
- + * Adds a key frame for the given scale at the given time
- + * @param time the time at which the keyFrame must be inserted
- + * @param scale the scale to use for this keyFrame
- + */
- + public void addTimeScale(float time, Vector3f scale) {
- + addKeyFrameScale((int) (time / tpf), scale);
- + }
- +
- + /**
- + * Adds a key frame for the given scale at the given keyFrame index
- + * @param keyFrameIndex the index at which the keyFrame must be inserted
- + * @param scale the scale to use for this keyFrame
- + */
- + public void addKeyFrameScale(int keyFrameIndex, Vector3f scale) {
- + Vector3f s = getScaleForFrame(keyFrameIndex);
- + s.set(scale);
- + }
- +
- + /**
- + * returns the translation for a given frame index
- + * creates the translation if it doesn't exists
- + * @param keyFrameIndex index
- + * @return the translation
- + */
- + private Vector3f getTranslationForFrame(int keyFrameIndex) {
- + if (keyFrameIndex < 0 || keyFrameIndex > totalFrames) {
- + throw new ArrayIndexOutOfBoundsException("keyFrameIndex must be between 0 and " + totalFrames + " (received " + keyFrameIndex + ")");
- + }
- + Vector3f v = keyFramesTranslation[keyFrameIndex];
- + if (v == null) {
- + v = new Vector3f();
- + keyFramesTranslation[keyFrameIndex] = v;
- + }
- + return v;
- + }
- +
- + /**
- + * returns the scale for a given frame index
- + * creates the scale if it doesn't exists
- + * @param keyFrameIndex index
- + * @return the scale
- + */
- + private Vector3f getScaleForFrame(int keyFrameIndex) {
- + if (keyFrameIndex < 0 || keyFrameIndex > totalFrames) {
- + throw new ArrayIndexOutOfBoundsException("keyFrameIndex must be between 0 and " + totalFrames + " (received " + keyFrameIndex + ")");
- + }
- + Vector3f v = keyFramesScale[keyFrameIndex];
- + if (v == null) {
- + v = new Vector3f();
- + keyFramesScale[keyFrameIndex] = v;
- + }
- + return v;
- + }
- +
- + /**
- + * returns the rotation for a given frame index
- + * creates the rotation if it doesn't exists
- + * @param keyFrameIndex index
- + * @return the rotation
- + */
- + private Rotation getRotationForFrame(int keyFrameIndex) {
- + if (keyFrameIndex < 0 || keyFrameIndex > totalFrames) {
- + throw new ArrayIndexOutOfBoundsException("keyFrameIndex must be between 0 and " + totalFrames + " (received " + keyFrameIndex + ")");
- + }
- + Rotation v = keyFramesRotation[keyFrameIndex];
- + if (v == null) {
- + v = new Rotation();
- + keyFramesRotation[keyFrameIndex] = v;
- + }
- + return v;
- + }
- +
- + /**
- + * Creates an Animation based on the keyFrames previously added to the helper.
- + * @return the generated animation
- + */
- + public Animation build() {
- + interpolateTime();
- + interpolate(keyFramesTranslation, Type.Translation);
- + interpolate(keyFramesRotation, Type.Rotation);
- + interpolate(keyFramesScale, Type.Scale);
- +
- + SpatialTrack spatialTrack = new SpatialTrack(times, translations, rotations, scales);
- +
- + //creating the animation
- + Animation spatialAnimation = new Animation(name, duration);
- + spatialAnimation.setTracks(new SpatialTrack[]{spatialTrack});
- +
- + return spatialAnimation;
- + }
- +
- + /**
- + * interpolates time values
- + */
- + private void interpolateTime() {
- + for (int i = 0; i < totalFrames; i++) {
- + times[i] = i * tpf;
- + }
- + }
- +
- + /**
- + * Interpolates over the key frames for the given keyFrame array and the given type of transform
- + * @param keyFrames the keyFrames array
- + * @param type the type of transforms
- + */
- + private void interpolate(Object[] keyFrames, Type type) {
- + int i = 0;
- + while (i < totalFrames) {
- + //fetching the next keyFrame index transform in the array
- + int key = getNextKeyFrame(i, keyFrames);
- + if (key != -1) {
- + //computing the frame span to interpolate over
- + int span = key - i;
- + //interating over the frames
- + for (int j = i; j <= key; j++) {
- + // computing interpolation value
- + float val = (float) (j - i) / (float) span;
- + //interpolationg depending on the transform type
- + switch (type) {
- + case Translation:
- + translations[j] = FastMath.interpolateLinear(val, (Vector3f) keyFrames[i], (Vector3f) keyFrames[key]);
- + break;
- + case Rotation:
- + Quaternion rot = new Quaternion();
- + rotations[j] = rot.slerp(((Rotation) keyFrames[i]).rotation, ((Rotation) keyFrames[key]).rotation, val);
- + break;
- + case Scale:
- + scales[j] = FastMath.interpolateLinear(val, (Vector3f) keyFrames[i], (Vector3f) keyFrames[key]);
- + break;
- + }
- + }
- + //jumping to the next keyFrame
- + i = key;
- + } else {
- + //No more key frame, filling the array witht he last transform computed.
- + for (int j = i; j < totalFrames; j++) {
- +
- + switch (type) {
- + case Translation:
- + translations[j] = ((Vector3f) keyFrames[i]).clone();
- + break;
- + case Rotation:
- + rotations[j] = ((Quaternion) ((Rotation) keyFrames[i]).rotation).clone();
- + break;
- + case Scale:
- + scales[j] = ((Vector3f) keyFrames[i]).clone();
- + break;
- + }
- + }
- + //we're done
- + i = totalFrames;
- + }
- + }
- + }
- +
- + /**
- + * Get the index of the next keyFrame that as a transform
- + * @param index the start index
- + * @param keyFrames the keyFrames array
- + * @return the index of the next keyFrame
- + */
- + private int getNextKeyFrame(int index, Object[] keyFrames) {
- + for (int i = index + 1; i < totalFrames; i++) {
- + if (keyFrames[i] != null) {
- + return i;
- + }
- + }
- + return -1;
- + }
- +
- + /**
- + * Get the index of the previous keyFrame that as a transform
- + * @param index the start index
- + * @param keyFrames the keyFrames array
- + * @return the index of the previous keyFrame
- + */
- + private int getPreviousKeyFrame(int index, Object[] keyFrames) {
- + for (int i = index - 1; i >= 0; i--) {
- + if (keyFrames[i] != null) {
- + return i;
- + }
- + }
- + return -1;
- + }
- +}
- Index: core/com/jme3/animation/AnimationFactory.java
- --- core/com/jme3/animation/AnimationFactory.java Base (BASE)
- +++ core/com/jme3/animation/AnimationFactory.java Deletado Localmente
- @@ -1,496 +0,0 @@
- -/*
- - * Copyright (c) 2009-2012 jMonkeyEngine
- - * All rights reserved.
- - *
- - * Redistribution and use in source and binary forms, with or without
- - * modification, are permitted provided that the following conditions are
- - * met:
- - *
- - * * Redistributions of source code must retain the above copyright
- - * notice, this list of conditions and the following disclaimer.
- - *
- - * * Redistributions in binary form must reproduce the above copyright
- - * notice, this list of conditions and the following disclaimer in the
- - * documentation and/or other materials provided with the distribution.
- - *
- - * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- - * may be used to endorse or promote products derived from this software
- - * without specific prior written permission.
- - *
- - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- - */
- -package com.jme3.animation;
- -
- -import com.jme3.math.FastMath;
- -import com.jme3.math.Quaternion;
- -import com.jme3.math.Transform;
- -import com.jme3.math.Vector3f;
- -
- -/**
- - * A convenience class to easily setup a spatial keyframed animation
- - * you can add some keyFrames for a given time or a given keyFrameIndex, for translation rotation and scale.
- - * The animationHelper will then generate an appropriate SpatialAnimation by interpolating values between the keyFrames.
- - * <br><br>
- - * Usage is : <br>
- - * - Create the AnimationHelper<br>
- - * - add some keyFrames<br>
- - * - call the buildAnimation() method that will retruna new Animation<br>
- - * - add the generated Animation to any existing AnimationControl<br>
- - * <br><br>
- - * Note that the first keyFrame (index 0) is defaulted with the identy transforms.
- - * If you want to change that you have to replace this keyFrame with any transform you want.
- - *
- - * @author Nehon
- - */
- -public class AnimationFactory {
- -
- - /**
- - * step for splitting rotation that have a n ange above PI/2
- - */
- - private final static float EULER_STEP = FastMath.QUARTER_PI * 3;
- -
- - /**
- - * enum to determine the type of interpolation
- - */
- - private enum Type {
- -
- - Translation, Rotation, Scale;
- - }
- -
- - /**
- - * Inner Rotation type class to kep track on a rotation Euler angle
- - */
- - protected class Rotation {
- -
- - /**
- - * The rotation Quaternion
- - */
- - Quaternion rotation = new Quaternion();
- - /**
- - * This rotation expressed in Euler angles
- - */
- - Vector3f eulerAngles = new Vector3f();
- - /**
- - * the index of the parent key frame is this keyFrame is a splitted rotation
- - */
- - int masterKeyFrame = -1;
- -
- - public Rotation() {
- - rotation.loadIdentity();
- - }
- -
- - void set(Quaternion rot) {
- - rotation.set(rot);
- - float[] a = new float[3];
- - rotation.toAngles(a);
- - eulerAngles.set(a[0], a[1], a[2]);
- - }
- -
- - void set(float x, float y, float z) {
- - float[] a = {x, y, z};
- - rotation.fromAngles(a);
- - eulerAngles.set(x, y, z);
- - }
- - }
- - /**
- - * Name of the animation
- - */
- - protected String name;
- - /**
- - * frames per seconds
- - */
- - protected int fps;
- - /**
- - * Animation duration in seconds
- - */
- - protected float duration;
- - /**
- - * total number of frames
- - */
- - protected int totalFrames;
- - /**
- - * time per frame
- - */
- - protected float tpf;
- - /**
- - * Time array for this animation
- - */
- - protected float[] times;
- - /**
- - * Translation array for this animation
- - */
- - protected Vector3f[] translations;
- - /**
- - * rotation array for this animation
- - */
- - protected Quaternion[] rotations;
- - /**
- - * scales array for this animation
- - */
- - protected Vector3f[] scales;
- - /**
- - * The map of keyFrames to compute the animation. The key is the index of the frame
- - */
- - protected Vector3f[] keyFramesTranslation;
- - protected Vector3f[] keyFramesScale;
- - protected Rotation[] keyFramesRotation;
- -
- - /**
- - * Creates and AnimationHelper
- - * @param duration the desired duration for the resulting animation
- - * @param name the name of the resulting animation
- - */
- - public AnimationFactory(float duration, String name) {
- - this(duration, name, 30);
- - }
- -
- - /**
- - * Creates and AnimationHelper
- - * @param duration the desired duration for the resulting animation
- - * @param name the name of the resulting animation
- - * @param fps the number of frames per second for this animation (default is 30)
- - */
- - public AnimationFactory(float duration, String name, int fps) {
- - this.name = name;
- - this.duration = duration;
- - this.fps = fps;
- - totalFrames = (int) (fps * duration) + 1;
- - tpf = 1 / (float) fps;
- - times = new float[totalFrames];
- - translations = new Vector3f[totalFrames];
- - rotations = new Quaternion[totalFrames];
- - scales = new Vector3f[totalFrames];
- - keyFramesTranslation = new Vector3f[totalFrames];
- - keyFramesTranslation[0] = new Vector3f();
- - keyFramesScale = new Vector3f[totalFrames];
- - keyFramesScale[0] = new Vector3f(1, 1, 1);
- - keyFramesRotation = new Rotation[totalFrames];
- - keyFramesRotation[0] = new Rotation();
- -
- - }
- -
- - /**
- - * Adds a key frame for the given Transform at the given time
- - * @param time the time at which the keyFrame must be inserted
- - * @param transform the transforms to use for this keyFrame
- - */
- - public void addTimeTransform(float time, Transform transform) {
- - addKeyFrameTransform((int) (time / tpf), transform);
- - }
- -
- - /**
- - * Adds a key frame for the given Transform at the given keyFrame index
- - * @param keyFrameIndex the index at which the keyFrame must be inserted
- - * @param transform the transforms to use for this keyFrame
- - */
- - public void addKeyFrameTransform(int keyFrameIndex, Transform transform) {
- - addKeyFrameTranslation(keyFrameIndex, transform.getTranslation());
- - addKeyFrameScale(keyFrameIndex, transform.getScale());
- - addKeyFrameRotation(keyFrameIndex, transform.getRotation());
- - }
- -
- - /**
- - * Adds a key frame for the given translation at the given time
- - * @param time the time at which the keyFrame must be inserted
- - * @param translation the translation to use for this keyFrame
- - */
- - public void addTimeTranslation(float time, Vector3f translation) {
- - addKeyFrameTranslation((int) (time / tpf), translation);
- - }
- -
- - /**
- - * Adds a key frame for the given translation at the given keyFrame index
- - * @param keyFrameIndex the index at which the keyFrame must be inserted
- - * @param translation the translation to use for this keyFrame
- - */
- - public void addKeyFrameTranslation(int keyFrameIndex, Vector3f translation) {
- - Vector3f t = getTranslationForFrame(keyFrameIndex);
- - t.set(translation);
- - }
- -
- - /**
- - * Adds a key frame for the given rotation at the given time<br>
- - * This can't be used if the interpolated angle is higher than PI (180°)<br>
- - * Use {@link #addTimeRotationAngles(float time, float x, float y, float z)} instead that uses Euler angles rotations.<br> *
- - * @param time the time at which the keyFrame must be inserted
- - * @param rotation the rotation Quaternion to use for this keyFrame
- - * @see #addTimeRotationAngles(float time, float x, float y, float z)
- - */
- - public void addTimeRotation(float time, Quaternion rotation) {
- - addKeyFrameRotation((int) (time / tpf), rotation);
- - }
- -
- - /**
- - * Adds a key frame for the given rotation at the given keyFrame index<br>
- - * This can't be used if the interpolated angle is higher than PI (180°)<br>
- - * Use {@link #addKeyFrameRotationAngles(int keyFrameIndex, float x, float y, float z)} instead that uses Euler angles rotations.
- - * @param keyFrameIndex the index at which the keyFrame must be inserted
- - * @param rotation the rotation Quaternion to use for this keyFrame
- - * @see #addKeyFrameRotationAngles(int keyFrameIndex, float x, float y, float z)
- - */
- - public void addKeyFrameRotation(int keyFrameIndex, Quaternion rotation) {
- - Rotation r = getRotationForFrame(keyFrameIndex);
- - r.set(rotation);
- - }
- -
- - /**
- - * Adds a key frame for the given rotation at the given time.<br>
- - * Rotation is expressed by Euler angles values in radians.<br>
- - * Note that the generated rotation will be stored as a quaternion and interpolated using a spherical linear interpolation (slerp)<br>
- - * Hence, this method may create intermediate keyFrames if the interpolation angle is higher than PI to ensure continuity in animation<br>
- - *
- - * @param time the time at which the keyFrame must be inserted
- - * @param x the rotation around the x axis (aka yaw) in radians
- - * @param y the rotation around the y axis (aka roll) in radians
- - * @param z the rotation around the z axis (aka pitch) in radians
- - */
- - public void addTimeRotationAngles(float time, float x, float y, float z) {
- - addKeyFrameRotationAngles((int) (time / tpf), x, y, z);
- - }
- -
- - /**
- - * Adds a key frame for the given rotation at the given key frame index.<br>
- - * Rotation is expressed by Euler angles values in radians.<br>
- - * Note that the generated rotation will be stored as a quaternion and interpolated using a spherical linear interpolation (slerp)<br>
- - * Hence, this method may create intermediate keyFrames if the interpolation angle is higher than PI to ensure continuity in animation<br>
- - *
- - * @param keyFrameIndex the index at which the keyFrame must be inserted
- - * @param x the rotation around the x axis (aka yaw) in radians
- - * @param y the rotation around the y axis (aka roll) in radians
- - * @param z the rotation around the z axis (aka pitch) in radians
- - */
- - public void addKeyFrameRotationAngles(int keyFrameIndex, float x, float y, float z) {
- - Rotation r = getRotationForFrame(keyFrameIndex);
- - r.set(x, y, z);
- -
- - // if the delta of euler angles is higher than PI, we create intermediate keyframes
- - // since we are using quaternions and slerp for rotation interpolation, we cannot interpolate over an angle higher than PI
- - int prev = getPreviousKeyFrame(keyFrameIndex, keyFramesRotation);
- - if (prev != -1) {
- - //previous rotation keyframe
- - Rotation prevRot = keyFramesRotation[prev];
- - //the maximum delta angle (x,y or z)
- - float delta = Math.max(Math.abs(x - prevRot.eulerAngles.x), Math.abs(y - prevRot.eulerAngles.y));
- - delta = Math.max(delta, Math.abs(z - prevRot.eulerAngles.z));
- - //if delta > PI we have to create intermediates key frames
- - if (delta >= FastMath.PI) {
- - //frames delta
- - int dF = keyFrameIndex - prev;
- - //angle per frame for x,y ,z
- - float dXAngle = (x - prevRot.eulerAngles.x) / (float) dF;
- - float dYAngle = (y - prevRot.eulerAngles.y) / (float) dF;
- - float dZAngle = (z - prevRot.eulerAngles.z) / (float) dF;
- -
- - // the keyFrame step
- - int keyStep = (int) (((float) (dF)) / delta * (float) EULER_STEP);
- - // the current keyFrame
- - int cursor = prev + keyStep;
- - while (cursor < keyFrameIndex) {
- - //for each step we create a new rotation by interpolating the angles
- - Rotation dr = getRotationForFrame(cursor);
- - dr.masterKeyFrame = keyFrameIndex;
- - dr.set(prevRot.eulerAngles.x + cursor * dXAngle, prevRot.eulerAngles.y + cursor * dYAngle, prevRot.eulerAngles.z + cursor * dZAngle);
- - cursor += keyStep;
- - }
- -
- - }
- - }
- -
- - }
- -
- - /**
- - * Adds a key frame for the given scale at the given time
- - * @param time the time at which the keyFrame must be inserted
- - * @param scale the scale to use for this keyFrame
- - */
- - public void addTimeScale(float time, Vector3f scale) {
- - addKeyFrameScale((int) (time / tpf), scale);
- - }
- -
- - /**
- - * Adds a key frame for the given scale at the given keyFrame index
- - * @param keyFrameIndex the index at which the keyFrame must be inserted
- - * @param scale the scale to use for this keyFrame
- - */
- - public void addKeyFrameScale(int keyFrameIndex, Vector3f scale) {
- - Vector3f s = getScaleForFrame(keyFrameIndex);
- - s.set(scale);
- - }
- -
- - /**
- - * returns the translation for a given frame index
- - * creates the translation if it doesn't exists
- - * @param keyFrameIndex index
- - * @return the translation
- - */
- - private Vector3f getTranslationForFrame(int keyFrameIndex) {
- - if (keyFrameIndex < 0 || keyFrameIndex > totalFrames) {
- - throw new ArrayIndexOutOfBoundsException("keyFrameIndex must be between 0 and " + totalFrames + " (received " + keyFrameIndex + ")");
- - }
- - Vector3f v = keyFramesTranslation[keyFrameIndex];
- - if (v == null) {
- - v = new Vector3f();
- - keyFramesTranslation[keyFrameIndex] = v;
- - }
- - return v;
- - }
- -
- - /**
- - * returns the scale for a given frame index
- - * creates the scale if it doesn't exists
- - * @param keyFrameIndex index
- - * @return the scale
- - */
- - private Vector3f getScaleForFrame(int keyFrameIndex) {
- - if (keyFrameIndex < 0 || keyFrameIndex > totalFrames) {
- - throw new ArrayIndexOutOfBoundsException("keyFrameIndex must be between 0 and " + totalFrames + " (received " + keyFrameIndex + ")");
- - }
- - Vector3f v = keyFramesScale[keyFrameIndex];
- - if (v == null) {
- - v = new Vector3f();
- - keyFramesScale[keyFrameIndex] = v;
- - }
- - return v;
- - }
- -
- - /**
- - * returns the rotation for a given frame index
- - * creates the rotation if it doesn't exists
- - * @param keyFrameIndex index
- - * @return the rotation
- - */
- - private Rotation getRotationForFrame(int keyFrameIndex) {
- - if (keyFrameIndex < 0 || keyFrameIndex > totalFrames) {
- - throw new ArrayIndexOutOfBoundsException("keyFrameIndex must be between 0 and " + totalFrames + " (received " + keyFrameIndex + ")");
- - }
- - Rotation v = keyFramesRotation[keyFrameIndex];
- - if (v == null) {
- - v = new Rotation();
- - keyFramesRotation[keyFrameIndex] = v;
- - }
- - return v;
- - }
- -
- - /**
- - * Creates an Animation based on the keyFrames previously added to the helper.
- - * @return the generated animation
- - */
- - public Animation buildAnimation() {
- - interpolateTime();
- - interpolate(keyFramesTranslation, Type.Translation);
- - interpolate(keyFramesRotation, Type.Rotation);
- - interpolate(keyFramesScale, Type.Scale);
- -
- - SpatialTrack spatialTrack = new SpatialTrack(times, translations, rotations, scales);
- -
- - //creating the animation
- - Animation spatialAnimation = new Animation(name, duration);
- - spatialAnimation.setTracks(new SpatialTrack[]{spatialTrack});
- -
- - return spatialAnimation;
- - }
- -
- - /**
- - * interpolates time values
- - */
- - private void interpolateTime() {
- - for (int i = 0; i < totalFrames; i++) {
- - times[i] = i * tpf;
- - }
- - }
- -
- - /**
- - * Interpolates over the key frames for the given keyFrame array and the given type of transform
- - * @param keyFrames the keyFrames array
- - * @param type the type of transforms
- - */
- - private void interpolate(Object[] keyFrames, Type type) {
- - int i = 0;
- - while (i < totalFrames) {
- - //fetching the next keyFrame index transform in the array
- - int key = getNextKeyFrame(i, keyFrames);
- - if (key != -1) {
- - //computing the frame span to interpolate over
- - int span = key - i;
- - //interating over the frames
- - for (int j = i; j <= key; j++) {
- - // computing interpolation value
- - float val = (float) (j - i) / (float) span;
- - //interpolationg depending on the transform type
- - switch (type) {
- - case Translation:
- - translations[j] = FastMath.interpolateLinear(val, (Vector3f) keyFrames[i], (Vector3f) keyFrames[key]);
- - break;
- - case Rotation:
- - Quaternion rot = new Quaternion();
- - rotations[j] = rot.slerp(((Rotation) keyFrames[i]).rotation, ((Rotation) keyFrames[key]).rotation, val);
- - break;
- - case Scale:
- - scales[j] = FastMath.interpolateLinear(val, (Vector3f) keyFrames[i], (Vector3f) keyFrames[key]);
- - break;
- - }
- - }
- - //jumping to the next keyFrame
- - i = key;
- - } else {
- - //No more key frame, filling the array witht he last transform computed.
- - for (int j = i; j < totalFrames; j++) {
- -
- - switch (type) {
- - case Translation:
- - translations[j] = ((Vector3f) keyFrames[i]).clone();
- - break;
- - case Rotation:
- - rotations[j] = ((Quaternion) ((Rotation) keyFrames[i]).rotation).clone();
- - break;
- - case Scale:
- - scales[j] = ((Vector3f) keyFrames[i]).clone();
- - break;
- - }
- - }
- - //we're done
- - i = totalFrames;
- - }
- - }
- - }
- -
- - /**
- - * Get the index of the next keyFrame that as a transform
- - * @param index the start index
- - * @param keyFrames the keyFrames array
- - * @return the index of the next keyFrame
- - */
- - private int getNextKeyFrame(int index, Object[] keyFrames) {
- - for (int i = index + 1; i < totalFrames; i++) {
- - if (keyFrames[i] != null) {
- - return i;
- - }
- - }
- - return -1;
- - }
- -
- - /**
- - * Get the index of the previous keyFrame that as a transform
- - * @param index the start index
- - * @param keyFrames the keyFrames array
- - * @return the index of the previous keyFrame
- - */
- - private int getPreviousKeyFrame(int index, Object[] keyFrames) {
- - for (int i = index - 1; i >= 0; i--) {
- - if (keyFrames[i] != null) {
- - return i;
- - }
- - }
- - return -1;
- - }
- -}
- Index: test/jme3test/animation/TestCinematic.java
- --- test/jme3test/animation/TestCinematic.java Base (BASE)
- +++ test/jme3test/animation/TestCinematic.java Modificado Localmente (Baseado em LOCAL)
- @@ -32,7 +32,7 @@
- package jme3test.animation;
- import com.jme3.animation.AnimControl;
- -import com.jme3.animation.AnimationFactory;
- +import com.jme3.animation.AnimationBuilder;
- import com.jme3.animation.LoopMode;
- import com.jme3.app.SimpleApplication;
- import com.jme3.cinematic.Cinematic;
- @@ -107,14 +107,14 @@
- createCameraMotion();
- //creating spatial animation for the teapot
- - AnimationFactory factory = new AnimationFactory(20, "teapotAnim");
- - factory.addTimeTranslation(0, new Vector3f(10, 0, 10));
- - factory.addTimeTranslation(20, new Vector3f(10, 0, -10));
- - factory.addTimeScale(10, new Vector3f(4, 4, 4));
- - factory.addTimeScale(20, new Vector3f(1, 1, 1));
- - factory.addTimeRotationAngles(20, 0, 4 * FastMath.TWO_PI, 0);
- + AnimationBuilder builder = new AnimationBuilder(20, "teapotAnim");
- + builder.addTimeTranslation(0, new Vector3f(10, 0, 10));
- + builder.addTimeTranslation(20, new Vector3f(10, 0, -10));
- + builder.addTimeScale(10, new Vector3f(4, 4, 4));
- + builder.addTimeScale(20, new Vector3f(1, 1, 1));
- + builder.addTimeRotationAngles(20, 0, 4 * FastMath.TWO_PI, 0);
- AnimControl control = new AnimControl();
- - control.addAnim(factory.buildAnimation());
- + control.addAnim(builder.build());
- teapot.addControl(control);
- //fade in
- Index: test/jme3test/animation/TestJaime.java
- --- test/jme3test/animation/TestJaime.java Base (BASE)
- +++ test/jme3test/animation/TestJaime.java Modificado Localmente (Baseado em LOCAL)
- @@ -32,7 +32,7 @@
- package jme3test.animation;
- import com.jme3.animation.AnimControl;
- -import com.jme3.animation.AnimationFactory;
- +import com.jme3.animation.AnimationBuilder;
- import com.jme3.animation.LoopMode;
- import com.jme3.app.DebugKeysAppState;
- import com.jme3.app.FlyCamAppState;
- @@ -149,11 +149,11 @@
- stateManager.attach(cinematic);
- jaime.move(0, 0, -3);
- - AnimationFactory af = new AnimationFactory(0.7f, "JumpForward");
- - af.addTimeTranslation(0, new Vector3f(0, 0, -3));
- - af.addTimeTranslation(0.35f, new Vector3f(0, 1, -1.5f));
- - af.addTimeTranslation(0.7f, new Vector3f(0, 0, 0));
- - jaime.getControl(AnimControl.class).addAnim(af.buildAnimation());
- + AnimationBuilder ab = new AnimationBuilder(0.7f, "JumpForward");
- + ab.addTimeTranslation(0, new Vector3f(0, 0, -3));
- + ab.addTimeTranslation(0.35f, new Vector3f(0, 1, -1.5f));
- + ab.addTimeTranslation(0.7f, new Vector3f(0, 0, 0));
- + jaime.getControl(AnimControl.class).addAnim(ab.build());
- cinematic.enqueueCinematicEvent(new AnimationEvent(jaime, "Idle",3, LoopMode.DontLoop));
- float jumpStart = cinematic.enqueueCinematicEvent(new AnimationEvent(jaime, "JumpStart", LoopMode.DontLoop));
- Index: test/jme3test/model/anim/TestAnimationBuilder.java
- --- test/jme3test/model/anim/TestAnimationBuilder.java Nenhuma Revisão de Base
- +++ test/jme3test/model/anim/TestAnimationBuilder.java Novo Localmente
- @@ -0,0 +1,85 @@
- +package jme3test.model.anim;
- +
- +import com.jme3.animation.AnimControl;
- +import com.jme3.animation.AnimationBuilder;
- +import com.jme3.app.SimpleApplication;
- +import com.jme3.light.AmbientLight;
- +import com.jme3.light.DirectionalLight;
- +import com.jme3.math.FastMath;
- +import com.jme3.math.Quaternion;
- +import com.jme3.math.Vector3f;
- +import com.jme3.scene.Geometry;
- +import com.jme3.scene.Node;
- +import com.jme3.scene.shape.Box;
- +import com.jme3.util.TangentBinormalGenerator;
- +
- +public class TestAnimationBuilder extends SimpleApplication {
- +
- + public static void main(String[] args) {
- + TestAnimationBuilder app = new TestAnimationBuilder();
- + app.start();
- + }
- +
- + @Override
- + public void simpleInitApp() {
- +
- + AmbientLight al = new AmbientLight();
- + rootNode.addLight(al);
- +
- + DirectionalLight dl = new DirectionalLight();
- + dl.setDirection(Vector3f.UNIT_XYZ.negate());
- + rootNode.addLight(dl);
- +
- + // Create model
- + Box box = new Box(1, 1, 1);
- + Geometry geom = new Geometry("box", box);
- + geom.setMaterial(assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWall.j3m"));
- + Node model = new Node("model");
- + model.attachChild(geom);
- +
- + Box child = new Box(0.5f, 0.5f, 0.5f);
- + Geometry childGeom = new Geometry("box", child);
- + childGeom.setMaterial(assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWall.j3m"));
- + Node childModel = new Node("childmodel");
- + childModel.setLocalTranslation(2, 2, 2);
- + childModel.attachChild(childGeom);
- + model.attachChild(childModel);
- + TangentBinormalGenerator.generate(model);
- +
- + //creating quite complex animation witht the AnimationBuilder
- + // animation of 6 seconds named "anim" and with 25 frames per second
- + AnimationBuilder animationBuilder = new AnimationBuilder(6, "anim", 25);
- +
- + //creating a translation keyFrame at time = 3 with a translation on the x axis of 5 WU
- + animationBuilder.addTimeTranslation(3, new Vector3f(5, 0, 0));
- + //reseting the translation to the start position at time = 6
- + animationBuilder.addTimeTranslation(6, new Vector3f(0, 0, 0));
- +
- + //Creating a scale keyFrame at time = 2 with the unit scale.
- + animationBuilder.addTimeScale(2, new Vector3f(1, 1, 1));
- + //Creating a scale keyFrame at time = 4 scaling to 1.5
- + animationBuilder.addTimeScale(4, new Vector3f(1.5f, 1.5f, 1.5f));
- + //reseting the scale to the start value at time = 5
- + animationBuilder.addTimeScale(5, new Vector3f(1, 1, 1));
- +
- +
- + //Creating a rotation keyFrame at time = 0.5 of quarter PI around the Z axis
- + animationBuilder.addTimeRotation(0.5f,new Quaternion().fromAngleAxis(FastMath.QUARTER_PI, Vector3f.UNIT_Z));
- + //rotating back to initial rotation value at time = 1
- + animationBuilder.addTimeRotation(1,Quaternion.IDENTITY);
- + //Creating a rotation keyFrame at time = 2. Note that i used the Euler angle version because the angle is higher than PI
- + //this should result in a complete revolution of the spatial around the x axis in 1 second (from 1 to 2)
- + animationBuilder.addTimeRotationAngles(2, FastMath.TWO_PI,0, 0);
- +
- +
- + AnimControl control = new AnimControl();
- + control.addAnim(animationBuilder.build());
- +
- + model.addControl(control);
- +
- + rootNode.attachChild(model);
- +
- + //run animation
- + control.createChannel().setAnim("anim");
- + }
- +}
- Index: test/jme3test/model/anim/TestAnimationFactory.java
- --- test/jme3test/model/anim/TestAnimationFactory.java Base (BASE)
- +++ test/jme3test/model/anim/TestAnimationFactory.java Deletado Localmente
- @@ -1,85 +0,0 @@
- -package jme3test.model.anim;
- -
- -import com.jme3.animation.AnimControl;
- -import com.jme3.animation.AnimationFactory;
- -import com.jme3.app.SimpleApplication;
- -import com.jme3.light.AmbientLight;
- -import com.jme3.light.DirectionalLight;
- -import com.jme3.math.FastMath;
- -import com.jme3.math.Quaternion;
- -import com.jme3.math.Vector3f;
- -import com.jme3.scene.Geometry;
- -import com.jme3.scene.Node;
- -import com.jme3.scene.shape.Box;
- -import com.jme3.util.TangentBinormalGenerator;
- -
- -public class TestAnimationFactory extends SimpleApplication {
- -
- - public static void main(String[] args) {
- - TestSpatialAnim app = new TestSpatialAnim();
- - app.start();
- - }
- -
- - @Override
- - public void simpleInitApp() {
- -
- - AmbientLight al = new AmbientLight();
- - rootNode.addLight(al);
- -
- - DirectionalLight dl = new DirectionalLight();
- - dl.setDirection(Vector3f.UNIT_XYZ.negate());
- - rootNode.addLight(dl);
- -
- - // Create model
- - Box box = new Box(1, 1, 1);
- - Geometry geom = new Geometry("box", box);
- - geom.setMaterial(assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWall.j3m"));
- - Node model = new Node("model");
- - model.attachChild(geom);
- -
- - Box child = new Box(0.5f, 0.5f, 0.5f);
- - Geometry childGeom = new Geometry("box", child);
- - childGeom.setMaterial(assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWall.j3m"));
- - Node childModel = new Node("childmodel");
- - childModel.setLocalTranslation(2, 2, 2);
- - childModel.attachChild(childGeom);
- - model.attachChild(childModel);
- - TangentBinormalGenerator.generate(model);
- -
- - //creating quite complex animation witht the AnimationHelper
- - // animation of 6 seconds named "anim" and with 25 frames per second
- - AnimationFactory animationFactory = new AnimationFactory(6, "anim", 25);
- -
- - //creating a translation keyFrame at time = 3 with a translation on the x axis of 5 WU
- - animationFactory.addTimeTranslation(3, new Vector3f(5, 0, 0));
- - //reseting the translation to the start position at time = 6
- - animationFactory.addTimeTranslation(6, new Vector3f(0, 0, 0));
- -
- - //Creating a scale keyFrame at time = 2 with the unit scale.
- - animationFactory.addTimeScale(2, new Vector3f(1, 1, 1));
- - //Creating a scale keyFrame at time = 4 scaling to 1.5
- - animationFactory.addTimeScale(4, new Vector3f(1.5f, 1.5f, 1.5f));
- - //reseting the scale to the start value at time = 5
- - animationFactory.addTimeScale(5, new Vector3f(1, 1, 1));
- -
- -
- - //Creating a rotation keyFrame at time = 0.5 of quarter PI around the Z axis
- - animationFactory.addTimeRotation(0.5f,new Quaternion().fromAngleAxis(FastMath.QUARTER_PI, Vector3f.UNIT_Z));
- - //rotating back to initial rotation value at time = 1
- - animationFactory.addTimeRotation(1,Quaternion.IDENTITY);
- - //Creating a rotation keyFrame at time = 2. Note that i used the Euler angle version because the angle is higher than PI
- - //this should result in a complete revolution of the spatial around the x axis in 1 second (from 1 to 2)
- - animationFactory.addTimeRotationAngles(2, FastMath.TWO_PI,0, 0);
- -
- -
- - AnimControl control = new AnimControl();
- - control.addAnim(animationFactory.buildAnimation());
- -
- - model.addControl(control);
- -
- - rootNode.attachChild(model);
- -
- - //run animation
- - control.createChannel().setAnim("anim");
- - }
- -}
Advertisement
Add Comment
Please, Sign In to add comment