Animation system revamp

* Track is no longer generic and doesn't need to be
 * Removed implementation specific methods from Track 
 * Animation class no longer casts the track to a specific type to call setTime(). The specific Track.setTime() implementation makes the appropriate operations.
 * TempVars instance is now passed down from the AnimControl to the tracks to get rid of all temp members in the tracks 
 * Misc docs and comment changes
 * J3O files that reference BoneAnimation or SpatialAnimation class are automatically redirected to Animation class
 * MeshAnimation, previously unused, is now completely obsolete and has been deleted 
 * PoseTrack, previously unused, is now deprecated until pose loading support is added 
 * Proper formatting for SpatialTrack

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8419 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
sha..rd 13 years ago
parent be7f7764cc
commit e3366f14b8
  1. 19
      engine/src/blender/com/jme3/scene/plugins/blender/animations/ArmatureHelper.java
  2. 16
      engine/src/blender/com/jme3/scene/plugins/blender/animations/Ipo.java
  3. 9
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/Constraint.java
  4. 3
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintDistLimit.java
  5. 3
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintLocLike.java
  6. 3
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintLocLimit.java
  7. 3
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintRotLike.java
  8. 3
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintRotLimit.java
  9. 3
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintShrinkWrap.java
  10. 3
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintSizeLike.java
  11. 3
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintSizeLimit.java
  12. 7
      engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialHelper.java
  13. 5
      engine/src/blender/com/jme3/scene/plugins/blender/modifiers/ArmatureModifier.java
  14. 5
      engine/src/blender/com/jme3/scene/plugins/blender/modifiers/ObjectAnimationModifier.java
  15. 9
      engine/src/core/com/jme3/animation/AnimChannel.java
  16. 20
      engine/src/core/com/jme3/animation/AnimControl.java
  17. 107
      engine/src/core/com/jme3/animation/Animation.java
  18. 25
      engine/src/core/com/jme3/animation/Bone.java
  19. 143
      engine/src/core/com/jme3/animation/BoneAnimation.java
  20. 49
      engine/src/core/com/jme3/animation/BoneTrack.java
  21. 101
      engine/src/core/com/jme3/animation/MeshAnimation.java
  22. 74
      engine/src/core/com/jme3/animation/PoseTrack.java
  23. 1
      engine/src/core/com/jme3/animation/Skeleton.java
  24. 2
      engine/src/core/com/jme3/animation/SkeletonControl.java
  25. 57
      engine/src/core/com/jme3/animation/SpatialTrack.java
  26. 66
      engine/src/core/com/jme3/animation/Track.java
  27. 3
      engine/src/core/com/jme3/export/SavableClassUtil.java

@ -39,6 +39,7 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import com.jme3.animation.Bone;
import com.jme3.animation.BoneTrack;
import com.jme3.animation.Track;
import com.jme3.math.Matrix4f;
import com.jme3.math.Quaternion;
@ -325,7 +326,7 @@ public class ArmatureHelper extends AbstractBlenderHelper {
* an exception is thrown when there are problems with the blend
* file
*/
public Track<?>[] getTracks(Structure actionStructure, BlenderContext blenderContext) throws BlenderFileException {
public BoneTrack[] getTracks(Structure actionStructure, BlenderContext blenderContext) throws BlenderFileException {
if (blenderVersion < 250) {
return this.getTracks249(actionStructure, blenderContext);
} else {
@ -345,7 +346,7 @@ public class ArmatureHelper extends AbstractBlenderHelper {
* an exception is thrown when there are problems with the blend
* file
*/
private Track<?>[] getTracks250(Structure actionStructure, BlenderContext blenderContext) throws BlenderFileException {
private BoneTrack[] getTracks250(Structure actionStructure, BlenderContext blenderContext) throws BlenderFileException {
LOGGER.log(Level.INFO, "Getting tracks!");
int fps = blenderContext.getBlenderKey().getFps();
Structure groups = (Structure) actionStructure.getFieldValue("groups");
@ -354,7 +355,7 @@ public class ArmatureHelper extends AbstractBlenderHelper {
throw new IllegalStateException("No bones found! Cannot proceed to calculating tracks!");
}
List<Track<?>> tracks = new ArrayList<Track<?>>();
List<BoneTrack> tracks = new ArrayList<BoneTrack>();
for (Structure actionGroup : actionGroups) {
String name = actionGroup.getFieldValue("name").toString();
Integer boneIndex = bonesMap.get(name);
@ -380,10 +381,10 @@ public class ArmatureHelper extends AbstractBlenderHelper {
}
Ipo ipo = new Ipo(bezierCurves);
tracks.add(ipo.calculateTrack(boneIndex.intValue(), 0, ipo.getLastFrame(), fps));
tracks.add( (BoneTrack) ipo.calculateTrack(boneIndex.intValue(), 0, ipo.getLastFrame(), fps) );
}
}
return tracks.toArray(new Track<?>[tracks.size()]);
return tracks.toArray(new BoneTrack[tracks.size()]);
}
/**
@ -398,7 +399,7 @@ public class ArmatureHelper extends AbstractBlenderHelper {
* an exception is thrown when there are problems with the blend
* file
*/
private Track<?>[] getTracks249(Structure actionStructure, BlenderContext blenderContext) throws BlenderFileException {
private BoneTrack[] getTracks249(Structure actionStructure, BlenderContext blenderContext) throws BlenderFileException {
LOGGER.log(Level.INFO, "Getting tracks!");
IpoHelper ipoHelper = blenderContext.getHelper(IpoHelper.class);
int fps = blenderContext.getBlenderKey().getFps();
@ -407,7 +408,7 @@ public class ArmatureHelper extends AbstractBlenderHelper {
if (actionChannels != null && actionChannels.size() > 0 && (bonesMap == null || bonesMap.size() == 0)) {
throw new IllegalStateException("No bones found! Cannot proceed to calculating tracks!");
}
List<Track<?>> tracks = new ArrayList<Track<?>>();
List<BoneTrack> tracks = new ArrayList<BoneTrack>();
for (Structure bActionChannel : actionChannels) {
String name = bActionChannel.getFieldValue("name").toString();
Integer boneIndex = bonesMap.get(name);
@ -416,11 +417,11 @@ public class ArmatureHelper extends AbstractBlenderHelper {
if (!p.isNull()) {
Structure ipoStructure = p.fetchData(blenderContext.getInputStream()).get(0);
Ipo ipo = ipoHelper.createIpo(ipoStructure, blenderContext);
tracks.add(ipo.calculateTrack(boneIndex.intValue(), 0, ipo.getLastFrame(), fps));
tracks.add( (BoneTrack) ipo.calculateTrack(boneIndex.intValue(), 0, ipo.getLastFrame(), fps));
}
}
}
return tracks.toArray(new Track<?>[tracks.size()]);
return tracks.toArray(new BoneTrack[tracks.size()]);
}
/**

@ -27,10 +27,16 @@ public class Ipo {
public static final int AC_QUAT_X = 26;
public static final int AC_QUAT_Y = 27;
public static final int AC_QUAT_Z = 28;
/** A list of bezier curves for this interpolation object. */
/**
* A list of bezier curves for this interpolation object.
*/
private BezierCurve[] bezierCurves;
/** Each ipo contains one bone track. */
private Track<?> calculatedTrack;
/**
* Each ipo contains one bone track.
*/
private Track calculatedTrack;
/**
* Constructor. Stores the bezier curves.
@ -87,6 +93,7 @@ public class Ipo {
return result;
}
/*
public void modifyTranslation(int frame, Vector3f translation) {
if (calculatedTrack != null) {
calculatedTrack.getTranslations()[frame].set(translation);
@ -104,6 +111,7 @@ public class Ipo {
calculatedTrack.getScales()[frame].set(scale);
}
}
*/
/**
* This method calculates the value of the curves as a bone track between the specified frames.
@ -118,7 +126,7 @@ public class Ipo {
* frame rate (frames per second)
* @return bone track for the specified bone
*/
public Track<?> calculateTrack(int targetIndex, int startFrame, int stopFrame, int fps) {
public Track calculateTrack(int targetIndex, int startFrame, int stopFrame, int fps) {
if(calculatedTrack == null) {
//preparing data for track
int framesAmount = stopFrame - startFrame;

@ -1,6 +1,7 @@
package com.jme3.scene.plugins.blender.constraints;
import com.jme3.animation.Animation;
import com.jme3.animation.BoneTrack;
import com.jme3.animation.Track;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
@ -99,10 +100,10 @@ public abstract class Constraint {
* the bone animation that affects the skeleton
* @return the bone track for the bone that is being affected by the constraint
*/
protected Track<?> getTrack(Animation animation, int targetIndex) {
if(boneOMA >= 0) {//bone animation
for(Track<?> track : animation.getTracks()) {
if(track.getTargetIndex() == targetIndex) {
protected Track getTrack(Animation animation, int targetIndex) {
if (boneOMA >= 0) {//bone animation
for (Track track : animation.getTracks()) {
if (((BoneTrack) track).getTargetBoneIndex() == targetIndex) {
return track;
}
}

@ -1,6 +1,7 @@
package com.jme3.scene.plugins.blender.constraints;
import com.jme3.animation.Animation;
import com.jme3.animation.BoneTrack;
import com.jme3.animation.Track;
import com.jme3.math.Vector3f;
import com.jme3.scene.plugins.blender.BlenderContext;
@ -40,7 +41,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
@Override
public void affectAnimation(Animation animation, int targetIndex) {
Vector3f targetLocation = this.getTargetLocation();
Track<?> boneTrack = this.getTrack(animation, targetIndex);
BoneTrack boneTrack = (BoneTrack) this.getTrack(animation, targetIndex);
if (boneTrack != null) {
//TODO: target vertex group !!!
float dist = ((Number) data.getFieldValue("dist")).floatValue();

@ -1,6 +1,7 @@
package com.jme3.scene.plugins.blender.constraints;
import com.jme3.animation.Animation;
import com.jme3.animation.BoneTrack;
import com.jme3.animation.Track;
import com.jme3.math.Vector3f;
import com.jme3.scene.plugins.blender.BlenderContext;
@ -45,7 +46,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
@Override
public void affectAnimation(Animation animation, int targetIndex) {
Track<?> track = this.getTrack(animation, targetIndex);
BoneTrack track = (BoneTrack) this.getTrack(animation, targetIndex);
if (track != null) {
Vector3f targetLocation = this.getTargetLocation();
int flag = ((Number) data.getFieldValue("flag")).intValue();

@ -1,6 +1,7 @@
package com.jme3.scene.plugins.blender.constraints;
import com.jme3.animation.Animation;
import com.jme3.animation.BoneTrack;
import com.jme3.animation.Track;
import com.jme3.math.Vector3f;
import com.jme3.scene.plugins.blender.BlenderContext;
@ -42,7 +43,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
@Override
public void affectAnimation(Animation animation, int targetIndex) {
Track<?> track = this.getTrack(animation, targetIndex);
BoneTrack track = (BoneTrack) this.getTrack(animation, targetIndex);
if (track != null) {
int flag = ((Number) data.getFieldValue("flag")).intValue();
Vector3f[] translations = track.getTranslations();

@ -1,6 +1,7 @@
package com.jme3.scene.plugins.blender.constraints;
import com.jme3.animation.Animation;
import com.jme3.animation.BoneTrack;
import com.jme3.animation.Track;
import com.jme3.math.Quaternion;
import com.jme3.scene.plugins.blender.BlenderContext;
@ -43,7 +44,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
@Override
public void affectAnimation(Animation animation, int targetIndex) {
Track<?> track = this.getTrack(animation, targetIndex);
BoneTrack track = (BoneTrack) this.getTrack(animation, targetIndex);
if (track != null) {
Quaternion targetRotation = this.getTargetRotation();
int flag = ((Number) data.getFieldValue("flag")).intValue();

@ -1,6 +1,7 @@
package com.jme3.scene.plugins.blender.constraints;
import com.jme3.animation.Animation;
import com.jme3.animation.BoneTrack;
import com.jme3.animation.Track;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
@ -40,7 +41,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
@Override
public void affectAnimation(Animation animation, int targetIndex) {
Track<?> track = this.getTrack(animation, targetIndex);
BoneTrack track = (BoneTrack) this.getTrack(animation, targetIndex);
if (track != null) {
int flag = ((Number) data.getFieldValue("flag")).intValue();
Quaternion[] rotations = track.getRotations();

@ -6,6 +6,7 @@ import java.util.List;
import java.util.logging.Logger;
import com.jme3.animation.Animation;
import com.jme3.animation.BoneTrack;
import com.jme3.animation.Track;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
@ -64,7 +65,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
}
//modifying traces
Track<?> track = this.getTrack(animation, targetIndex);
BoneTrack track = (BoneTrack) this.getTrack(animation, targetIndex);
if (track != null) {
Vector3f[] translations = track.getTranslations();
Quaternion[] rotations = track.getRotations();

@ -1,6 +1,7 @@
package com.jme3.scene.plugins.blender.constraints;
import com.jme3.animation.Animation;
import com.jme3.animation.BoneTrack;
import com.jme3.animation.Track;
import com.jme3.math.Vector3f;
import com.jme3.scene.plugins.blender.BlenderContext;
@ -41,7 +42,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
@Override
public void affectAnimation(Animation animation, int targetIndex) {
Vector3f targetScale = this.getTargetLocation();
Track<?> track = this.getTrack(animation, targetIndex);
BoneTrack track = (BoneTrack) this.getTrack(animation, targetIndex);
if (track != null) {
int flag = ((Number) data.getFieldValue("flag")).intValue();
Vector3f[] scales = track.getScales();

@ -1,6 +1,7 @@
package com.jme3.scene.plugins.blender.constraints;
import com.jme3.animation.Animation;
import com.jme3.animation.BoneTrack;
import com.jme3.animation.Track;
import com.jme3.math.Vector3f;
import com.jme3.scene.plugins.blender.BlenderContext;
@ -42,7 +43,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
@Override
public void affectAnimation(Animation animation, int targetIndex) {
Track<?> track = this.getTrack(animation, targetIndex);
BoneTrack track = (BoneTrack) this.getTrack(animation, targetIndex);
if (track != null) {
int flag = ((Number) data.getFieldValue("flag")).intValue();
Vector3f[] scales = track.getScales();

@ -219,9 +219,10 @@ public class MaterialHelper extends AbstractBlenderHelper {
}
if(texture.getType()==Type.TwoDimensional) {//so far only 2D textures can be mapped in other way than color
if ((mapto & MaterialContext.MTEX_NOR) != 0 && !materialContext.shadeless) {
Structure mTex = materialContext.getMTex(texture);
Texture normalMapTexture = textureHelper.convertToNormalMapTexture(texture, ((Number) mTex.getFieldValue("norfac")).floatValue());
texturesMap.put(TEXTURE_TYPE_NORMAL, normalMapTexture);
//Structure mTex = materialContext.getMTex(texture);
//Texture normalMapTexture = textureHelper.convertToNormalMapTexture(texture, ((Number) mTex.getFieldValue("norfac")).floatValue());
//texturesMap.put(TEXTURE_TYPE_NORMAL, normalMapTexture);
texturesMap.put(TEXTURE_TYPE_NORMAL, texture);
}
if ((mapto & MaterialContext.MTEX_EMIT) != 0) {
texturesMap.put(TEXTURE_TYPE_GLOW, texture);

@ -12,6 +12,7 @@ import java.util.logging.Logger;
import com.jme3.animation.AnimControl;
import com.jme3.animation.Animation;
import com.jme3.animation.Bone;
import com.jme3.animation.BoneTrack;
import com.jme3.animation.Skeleton;
import com.jme3.animation.SkeletonControl;
import com.jme3.animation.Track;
@ -123,10 +124,10 @@ import com.jme3.util.BufferUtils;
Structure actionStructure = header.getStructure(blenderContext);
String actionName = actionStructure.getName();
Track<?>[] tracks = armatureHelper.getTracks(actionStructure, blenderContext);
BoneTrack[] tracks = armatureHelper.getTracks(actionStructure, blenderContext);
//determining the animation time
float maximumTrackLength = 0;
for(Track<?> track : tracks) {
for(BoneTrack track : tracks) {
float length = track.getLength();
if(length > maximumTrackLength) {
maximumTrackLength = length;

@ -8,6 +8,7 @@ import java.util.logging.Logger;
import com.jme3.animation.AnimControl;
import com.jme3.animation.Animation;
import com.jme3.animation.BoneTrack;
import com.jme3.animation.Track;
import com.jme3.scene.Node;
import com.jme3.scene.plugins.blender.BlenderContext;
@ -82,10 +83,10 @@ import com.jme3.scene.plugins.ogre.AnimData;
int fps = blenderContext.getBlenderKey().getFps();
// calculating track for the only bone in this skeleton
Track<?> track = ipo.calculateTrack(-1, 0, ipo.getLastFrame(), fps);
BoneTrack track = (BoneTrack) ipo.calculateTrack(-1, 0, ipo.getLastFrame(), fps);
Animation animation = new Animation(objectAnimationName, ipo.getLastFrame() / fps);
animation.setTracks(new Track<?>[] { track });
animation.setTracks(new BoneTrack[] { track });
ArrayList<Animation> animations = new ArrayList<Animation>(1);
animations.add(animation);

@ -33,6 +33,7 @@
package com.jme3.animation;
import com.jme3.math.FastMath;
import com.jme3.util.TempVars;
import java.util.BitSet;
/**
@ -52,7 +53,6 @@ public final class AnimChannel {
private AnimControl control;
// private ArrayList<Integer> affectedBones;
private BitSet affectedBones;
private Animation animation;
@ -101,6 +101,7 @@ public final class AnimChannel {
/**
* Returns the parent control of this AnimChannel.
*
* @return the parent control of this AnimChannel.
* @see AnimControl
*/
@ -316,12 +317,12 @@ public final class AnimChannel {
return affectedBones;
}
void update(float tpf) {
void update(float tpf, TempVars vars) {
if (animation == null)
return;
if (blendFrom != null){
blendFrom.setTime(timeBlendFrom, 1f - blendAmount, control, this);
blendFrom.setTime(timeBlendFrom, 1f - blendAmount, control, this, vars);
//blendFrom.setTime(timeBlendFrom, control.skeleton, 1f - blendAmount, affectedBones);
timeBlendFrom += tpf * speedBlendFrom;
timeBlendFrom = clampWrapTime(timeBlendFrom,
@ -339,7 +340,7 @@ public final class AnimChannel {
}
}
animation.setTime(time, blendAmount, control, this);
animation.setTime(time, blendAmount, control, this, vars);
//animation.setTime(time, control.skeleton, blendAmount, affectedBones);
time += tpf * speed;

@ -42,6 +42,7 @@ import com.jme3.scene.Mesh;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.AbstractControl;
import com.jme3.scene.control.Control;
import com.jme3.util.TempVars;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
@ -101,9 +102,6 @@ public final class AnimControl extends AbstractControl implements Cloneable {
* @param skeleton The skeleton to animate
*/
public AnimControl(Skeleton skeleton) {
//if (skeleton == null)
// throw new IllegalArgumentException("skeleton cannot be null");
this.skeleton = skeleton;
reset();
}
@ -121,10 +119,11 @@ public final class AnimControl extends AbstractControl implements Cloneable {
try {
AnimControl clone = (AnimControl) super.clone();
clone.spatial = spatial;
clone.channels = new ArrayList<AnimChannel>();
if (skeleton != null){
clone.skeleton = new Skeleton(skeleton);
}
clone.channels = new ArrayList<AnimChannel>();
// animationMap is reference-copied, animation data should be shared
// to reduce memory usage.
@ -327,9 +326,11 @@ public final class AnimControl extends AbstractControl implements Cloneable {
skeleton.reset(); // reset skeleton to bind pose
}
TempVars vars = TempVars.get();
for (int i = 0; i < channels.size(); i++) {
channels.get(i).update(tpf);
channels.get(i).update(tpf, vars);
}
vars.release();
if (skeleton != null){
skeleton.updateWorldVectors();
@ -359,9 +360,12 @@ public final class AnimControl extends AbstractControl implements Cloneable {
animationMap = (HashMap<String, Animation>) in.readStringSavableMap("animations", null);
if (im.getFormatVersion() == 0){
//changed for backward compatibility with j3o files generated before the AnimControl/SkeletonControl split
//if we find a target mesh array the AnimControl creates the SkeletonControl for old files and add it to the spatial.
//When backward compatibility won't be needed anymore this can deleted
// Changed for backward compatibility with j3o files generated
// before the AnimControl/SkeletonControl split.
// If we find a target mesh array the AnimControl creates the
// SkeletonControl for old files and add it to the spatial.
// When backward compatibility won't be needed anymore this can deleted
Savable[] sav = in.readSavableArray("targets", null);
if (sav != null) {
Mesh[] targets = new Mesh[sav.length];

@ -32,32 +32,35 @@
package com.jme3.animation;
import java.io.IOException;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collection;
import java.util.List;
import com.jme3.export.InputCapsule;
import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.export.OutputCapsule;
import com.jme3.export.Savable;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.util.TempVars;
/**
* The animation class updates the animation target with the tracks of a given type.
*
* @author Kirill Vainer, Marcin Roguski (Kaelthas)
*/
public class Animation implements Savable, Cloneable {
/** The name of the animation. */
/**
* The name of the animation.
*/
private String name;
/** The length of the animation. */
/**
* The length of the animation.
*/
private float length;
/** The tracks of the animation. */
private Track<?>[] tracks;
/**
* The tracks of the animation.
*/
private Track[] tracks;
/**
* Serialization-only. Do not use.
@ -65,10 +68,10 @@ public class Animation implements Savable, Cloneable {
public Animation() {}
/**
* Creates a new BoneAnimation with the given name and length.
* Creates a new <code>Animation</code> with the given name and length.
*
* @param name The name of the bone animation.
* @param length Length in seconds of the bone animation.
* @param name The name of the animation.
* @param length Length in seconds of the animation.
*/
public Animation(String name, float length) {
this.name = name;
@ -76,14 +79,17 @@ public class Animation implements Savable, Cloneable {
}
/**
* @return the name of the animation
* The name of the bone animation
* @return name of the bone animation
*/
public String getName() {
return name;
}
/**
* @return the length of the animation
* Returns the length in seconds of this animation
*
* @return the length in seconds of this animation
*/
public float getLength() {
return length;
@ -93,72 +99,67 @@ public class Animation implements Savable, Cloneable {
* This method sets the current time of the animation.
* This method behaves differently for every known track type.
* Override this method if you have your own type of track.
*
* @param time the time of the animation
* @param blendAmount the blend amount factor
* @param control the nimation control
* @param control the animation control
* @param channel the animation channel
*/
void setTime(float time, float blendAmount, AnimControl control, AnimChannel channel) {
if(tracks != null && tracks.length > 0) {
void setTime(float time, float blendAmount, AnimControl control, AnimChannel channel, TempVars vars) {
for (int i = 0; i < tracks.length; i++){
tracks[i].setTime(time, blendAmount, control, channel, vars);
}
/*
if (tracks != null && tracks.length > 0) {
Track<?> trackInstance = tracks[0];
if(trackInstance instanceof SpatialTrack) {
if (trackInstance instanceof SpatialTrack) {
Spatial spatial = control.getSpatial();
if (spatial != null) {
((SpatialTrack)tracks[0]).setTime(time, spatial, blendAmount);
((SpatialTrack) tracks[0]).setTime(time, spatial, blendAmount);
}
} else if(trackInstance instanceof BoneTrack) {
} else if (trackInstance instanceof BoneTrack) {
BitSet affectedBones = channel.getAffectedBones();
Skeleton skeleton = control.getSkeleton();
for (int i = 0; i < tracks.length; ++i) {
if (affectedBones == null || affectedBones.get(((BoneTrack)tracks[i]).getTargetIndex())) {
((BoneTrack)tracks[i]).setTime(time, skeleton, blendAmount);
if (affectedBones == null || affectedBones.get(((BoneTrack) tracks[i]).getTargetIndex())) {
((BoneTrack) tracks[i]).setTime(time, skeleton, blendAmount);
}
}
} else if(trackInstance instanceof PoseTrack) {
} else if (trackInstance instanceof PoseTrack) {
Spatial spatial = control.getSpatial();
List<Mesh> meshes = new ArrayList<Mesh>();
this.getMeshes(spatial, meshes);
if(meshes.size() > 0) {
if (meshes.size() > 0) {
Mesh[] targets = meshes.toArray(new Mesh[meshes.size()]);
for (int i = 0; i < tracks.length; ++i){
((PoseTrack)tracks[i]).setTime(time, targets, blendAmount);
}
for (int i = 0; i < tracks.length; ++i) {
((PoseTrack) tracks[i]).setTime(time, targets, blendAmount);
}
}
}
}
/**
* This method returns the meshes within the given spatial.
* @param spatial the spatial to search the meshes from
* @param meshes the collection that will have the found meshes
*/
private void getMeshes(Spatial spatial, Collection<Mesh> meshes) {
if(spatial instanceof Geometry) {
meshes.add(((Geometry) spatial).getMesh());
} else if(spatial instanceof Node) {
for(Spatial child : ((Node) spatial).getChildren()) {
this.getMeshes(child, meshes);
}
}
}
/**
* Set the {@link Track}s to be used by this animation.
* <p>
* The array should be organized so that the appropriate BoneTrack can
* The array should be organized so that the appropriate Track can
* be retrieved based on a bone index.
*
* @param tracks the tracks to set
* @param tracks The tracks to set.
*/
public void setTracks(Track<?>[] tracks){
public void setTracks(Track[] tracks){
this.tracks = tracks;
}
/**
* @return the tracks of the animation
* Returns the tracks set in {@link #setTracks(com.jme3.animation.Track[]) }.
*
* @return the tracks set previously
*/
public Track<?>[] getTracks() {
public Track[] getTracks() {
return tracks;
}
@ -166,15 +167,14 @@ public class Animation implements Savable, Cloneable {
* This method creates a clone of the current object.
* @return a clone of the current object
*/
@Override
public Animation clone() {
try {
Animation result = (Animation) super.clone();
if (tracks != null) {
result.tracks = tracks.clone();
for (int i = 0; i < tracks.length; ++i) {
result.tracks[i] = this.tracks[i].clone();
}
}
return result;
} catch (CloneNotSupportedException e) {
throw new AssertionError();
@ -183,7 +183,7 @@ public class Animation implements Savable, Cloneable {
@Override
public String toString() {
return "Animation[name=" + name + ", length=" + length + ']';
return getClass().getSimpleName() + "[name=" + name + ", length=" + length + ']';
}
@Override
@ -199,8 +199,9 @@ public class Animation implements Savable, Cloneable {
InputCapsule in = im.getCapsule(this);
name = in.readString("name", null);
length = in.readFloat("length", 0f);
Object[] arr = in.readSavableArray("tracks", null);
tracks = new Track<?>[arr.length];
Savable[] arr = in.readSavableArray("tracks", null);
tracks = new Track[arr.length];
System.arraycopy(arr, 0, tracks, 0, arr.length);
}
}

@ -416,24 +416,27 @@ public final class Bone implements Savable {
/**
* Stores the skinning transform in the specified Matrix4f.
* The skinning transform applies the animation of the bone to a vertex.
* @param m
*
* This assumes that the world transforms for the entire bone hierarchy
* have already been computed, otherwise this method will return undefined
* results.
*
* @param outTransform
*/
void getOffsetTransform(Matrix4f m, Quaternion tmp1, Vector3f tmp2, Vector3f tmp3, Matrix3f rotMat) {
//Computing scale
void getOffsetTransform(Matrix4f outTransform, Quaternion tmp1, Vector3f tmp2, Vector3f tmp3, Matrix3f tmp4) {
// Computing scale
Vector3f scale = worldScale.mult(worldBindInverseScale, tmp3);
//computing rotation
// Computing rotation
Quaternion rotate = worldRot.mult(worldBindInverseRot, tmp1);
//computing translation
//translation depend on rotation and scale
// Computing translation
// Translation depend on rotation and scale
Vector3f translate = worldPos.add(rotate.mult(scale.mult(worldBindInversePos, tmp2), tmp2), tmp2);
//populating the matrix
m.loadIdentity();
m.setTransform(translate, scale, rotate.toRotationMatrix(rotMat));
// Populating the matrix
outTransform.loadIdentity();
outTransform.setTransform(translate, scale, rotate.toRotationMatrix(tmp4));
}
/**

@ -31,153 +31,14 @@
*/
package com.jme3.animation;
import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.export.InputCapsule;
import com.jme3.export.OutputCapsule;
import com.jme3.export.Savable;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import java.io.IOException;
import java.util.BitSet;
/**
* <code>BoneAnimation</code> updates each of its tracks with the skeleton and time
* to apply the animation.
*
* @author Kirill Vainer
* @deprecated use Animation instead with tracks of selected type (ie. BoneTrack, SpatialTrack, MeshTrack)
*/
@Deprecated
public final class BoneAnimation extends Animation {
private String name;
private float length;
private BoneTrack[] tracks;
/**
* Creates a new BoneAnimation with the given name and length.
*
* @param name The name of the bone animation.
* @param length Length in seconds of the bone animation.
*/
@Deprecated
public BoneAnimation(String name, float length) {
this.name = name;
this.length = length;
}
/**
* Serialization-only. Do not use.
*/
public BoneAnimation() {
}
/**
* The name of the bone animation
* @return name of the bone animation
*/
public String getName(){
return name;
}
/**
* Returns the length in seconds of this animation
*
* @return the length in seconds of this animation
*/
public float getLength(){
return length;
}
/**
* Set the {@link BoneTrack}s to be used by this animation.
* <p>
* The array should be organized so that the appropriate BoneTrack can
* be retrieved based on a bone index.
*
* @param tracks The tracks to set.
*/
public void setTracks(BoneTrack[] tracks){
this.tracks = tracks;
}
/**
* Returns the tracks set in {@link #setTracks(com.jme3.animation.BoneTrack[]) }.
*
* @return the tracks set previously
*/
public BoneTrack[] getTracks(){
return tracks;
}
public void setTime(float time, float blendAmount, AnimControl control, AnimChannel channel){
BitSet affectedBones = channel.getAffectedBones();
Skeleton skeleton = control.getSkeleton();
if (tracks == null)
return;
for (int i = 0; i < tracks.length; i++) {
if (affectedBones == null
|| affectedBones.get(tracks[i].getTargetIndex())) {
tracks[i].setTime(time, skeleton, blendAmount);
}
}
}
@Override
public String toString() {
return "BoneAnim[name=" + name + ", length=" + length + "]";
}
@Override
public BoneAnimation clone() {
BoneAnimation result = (BoneAnimation) super.clone();
if (result.tracks == null) {
result.tracks = new BoneTrack[tracks.length];
}
for (int i = 0; i < tracks.length; ++i) {
int tablesLength = tracks[i].getTimes().length;
float[] times = tracks[i].getTimes().clone();
Vector3f[] sourceTranslations = tracks[i].getTranslations();
Quaternion[] sourceRotations = tracks[i].getRotations();
Vector3f[] sourceScales = tracks[i].getScales();
Vector3f[] translations = new Vector3f[tablesLength];
Quaternion[] rotations = new Quaternion[tablesLength];
Vector3f[] scales = new Vector3f[tablesLength];
for (int j = 0; j < tablesLength; ++j) {
translations[j] = sourceTranslations[j].clone();
rotations[j] = sourceRotations[j].clone();
scales[j] = sourceScales != null ? sourceScales[j].clone() : new Vector3f(1.0f, 1.0f, 1.0f);
}
// times do not change, no need to clone them
result.tracks[i] = new BoneTrack(tracks[i].getTargetIndex(), times,
translations, rotations, scales);
}
return result;
}
@Override
public void write(JmeExporter e) throws IOException {
OutputCapsule out = e.getCapsule(this);
out.write(name, "name", null);
out.write(length, "length", 0f);
out.write(tracks, "tracks", null);
}
@Override
public void read(JmeImporter i) throws IOException {
InputCapsule in = i.getCapsule(this);
name = in.readString("name", null);
length = in.readFloat("length", 0f);
Savable[] sav = in.readSavableArray("tracks", null);
if (sav != null) {
tracks = new BoneTrack[sav.length];
System.arraycopy(sav, 0, tracks, 0, sav.length);
}
super(name, length);
}
}

@ -38,19 +38,22 @@ import com.jme3.export.OutputCapsule;
import com.jme3.export.Savable;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.util.TempVars;
import java.io.IOException;
import java.util.BitSet;
/**
* Contains a list of transforms and times for each keyframe.
*
* @author Kirill Vainer
*/
public final class BoneTrack implements Track<Skeleton> {
public final class BoneTrack implements Track {
/**
* Bone index in the skeleton which this track effects.
*/
private int targetBoneIndex;
/**
* Transforms and times for track.
*/
@ -58,13 +61,6 @@ public final class BoneTrack implements Track<Skeleton> {
private CompactQuaternionArray rotations;
private CompactVector3Array scales;
private float[] times;
// temp vectors for interpolation
private transient final Vector3f tempV = new Vector3f();
private transient final Quaternion tempQ = new Quaternion();
private transient final Vector3f tempS = new Vector3f();
private transient final Vector3f tempV2 = new Vector3f();
private transient final Quaternion tempQ2 = new Quaternion();
private transient final Vector3f tempS2 = new Vector3f();
/**
* Serialization-only. Do not use.
@ -106,21 +102,12 @@ public final class BoneTrack implements Track<Skeleton> {
}
/**
* @return the bone index of this bone track
* @deprecated use getTargetIndex() instead
* @return the bone index of this bone track.
*/
@Deprecated
public int getTargetBoneIndex() {
return targetBoneIndex;
}
/**
* @return the bone index of this bone track
*/
public int getTargetIndex() {
return targetBoneIndex;
}
/**
* return the array of rotations of this track
* @return
@ -202,8 +189,20 @@ public final class BoneTrack implements Track<Skeleton> {
* @param skeleton the skeleton to which the bone belong
* @param weight the weight of the animation
*/
public void setTime(float time, Skeleton skeleton, float weight) {
Bone target = skeleton.getBone(targetBoneIndex);
public void setTime(float time, float weight, AnimControl control, AnimChannel channel, TempVars vars) {
BitSet affectedBones = channel.getAffectedBones();
if (affectedBones != null && !affectedBones.get(targetBoneIndex)) {
return;
}
Bone target = control.getSkeleton().getBone(targetBoneIndex);
Vector3f tempV = vars.vect1;
Vector3f tempS = vars.vect2;
Quaternion tempQ = vars.quat1;
Vector3f tempV2 = vars.vect3;
Vector3f tempS2 = vars.vect4;
Quaternion tempQ2 = vars.quat2;
int lastFrame = times.length - 1;
if (time < 0 || lastFrame == 0) {
@ -264,6 +263,7 @@ public final class BoneTrack implements Track<Skeleton> {
* This method creates a clone of the current object.
* @return a clone of the current object
*/
@Override
public BoneTrack clone() {
int tablesLength = times.length;
@ -280,7 +280,8 @@ public final class BoneTrack implements Track<Skeleton> {
rotations[i] = sourceRotations[i].clone();
scales[i] = sourceScales != null ? sourceScales[i].clone() : new Vector3f(1.0f, 1.0f, 1.0f);
}
//need to use the constructor here because of the final fields used in this class
// Need to use the constructor here because of the final fields used in this class
return new BoneTrack(targetBoneIndex, times, translations, rotations, scales);
}
@ -300,12 +301,10 @@ public final class BoneTrack implements Track<Skeleton> {
targetBoneIndex = ic.readInt("boneIndex", 0);
translations = (CompactVector3Array) ic.readSavable("translations", null);
rotations = (CompactQuaternionArray) ic.readSavable("rotations", null);
times = ic.readFloatArray("times", null);
scales = (CompactVector3Array) ic.readSavable("scales", null);
//Backward compatibility for old j3o files generated before revision 6807
if (im.getFormatVersion() == 0){
if (translations == null) {
@ -330,4 +329,8 @@ public final class BoneTrack implements Track<Skeleton> {
}
}
}
public void setTime(float time, float weight, AnimControl control, AnimChannel channel) {
throw new UnsupportedOperationException("Not supported yet.");
}
}

@ -1,101 +0,0 @@
/*
* Copyright (c) 2009-2010 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 java.io.IOException;
import com.jme3.export.InputCapsule;
import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.export.OutputCapsule;
import com.jme3.scene.Mesh;
/**
*
* @author Kirill Vainer
* @deprecated use Animation instead with tracks of selected type (ie. BoneTrack, SpatialTrack, MeshTrack)
*/
@Deprecated
public class MeshAnimation extends Animation {
private String name;
private float length;
private PoseTrack[] tracks;
public MeshAnimation(String name, float length){
this.name = name;
this.length = length;
}
public String getName(){
return name;
}
public float getLength(){
return length;
}
public void setTracks(PoseTrack[] tracks){
this.tracks = tracks;
}
public PoseTrack[] getTracks(){
return tracks;
}
public void setTime(float time, Mesh[] targets, float weight){
for (int i = 0; i < tracks.length; i++){
tracks[i].setTime(time, targets, weight);
}
}
@Override
public void setTime(float time, float blendAmount, AnimControl control, AnimChannel channel) {
// TODO: ...
}
public void write(JmeExporter e) throws IOException {
OutputCapsule out = e.getCapsule(this);
out.write(name, "name", "");
out.write(length, "length", -1f);
out.write(tracks, "tracks", null);
}
public void read(JmeImporter i) throws IOException {
InputCapsule in = i.getCapsule(this);
name = in.readString("name", "");
length = in.readFloat("length", -1f);
tracks = (PoseTrack[]) in.readSavableArray("tracks", null);
}
}

@ -37,20 +37,20 @@ import com.jme3.export.JmeImporter;
import com.jme3.export.InputCapsule;
import com.jme3.export.OutputCapsule;
import com.jme3.export.Savable;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.scene.Mesh;
import com.jme3.scene.VertexBuffer;
import com.jme3.scene.VertexBuffer.Type;
import com.jme3.util.TempVars;
import java.io.IOException;
import java.nio.FloatBuffer;
/**
* A single track of pose animation associated with a certain mesh.
*/
public final class PoseTrack implements Track<Mesh[]> {
@Deprecated
public final class PoseTrack implements Track {
protected int targetMeshIndex;
private int targetMeshIndex;
private PoseFrame[] frames;
private float[] times;
@ -59,7 +59,7 @@ public final class PoseTrack implements Track<Mesh[]> {
Pose[] poses;
float[] weights;
public PoseFrame(Pose[] poses, float[] weights){
public PoseFrame(Pose[] poses, float[] weights) {
this.poses = poses;
this.weights = weights;
}
@ -68,13 +68,14 @@ public final class PoseTrack implements Track<Mesh[]> {
* This method creates a clone of the current object.
* @return a clone of the current object
*/
@Override
public PoseFrame clone() {
try {
PoseFrame result = (PoseFrame) super.clone();
result.weights = this.weights.clone();
if(this.poses != null) {
if (this.poses != null) {
result.poses = new Pose[this.poses.length];
for(int i=0;i<this.poses.length;++i) {
for (int i = 0; i < this.poses.length; ++i) {
result.poses[i] = this.poses[i].clone();
}
}
@ -103,13 +104,6 @@ public final class PoseTrack implements Track<Mesh[]> {
this.frames = frames;
}
/**
* @return the index of the target object for this track
*/
public int getTargetIndex() {
return targetMeshIndex;
}
private void applyFrame(Mesh target, int frameIndex, float weight){
PoseFrame frame = frames[frameIndex];
VertexBuffer pb = target.getBuffer(Type.Position);
@ -124,24 +118,30 @@ public final class PoseTrack implements Track<Mesh[]> {
pb.updateData(pb.getData());
}
public void setTime(float time, Mesh[] targets, float weight) {
public void setTime(float time, float weight, AnimControl control, AnimChannel channel, TempVars vars) {
// TODO: When MeshControl is created, it will gather targets
// list automatically which is then retrieved here.
/*
Mesh target = targets[targetMeshIndex];
if (time < times[0]){
if (time < times[0]) {
applyFrame(target, 0, weight);
}else if (time > times[times.length-1]){
applyFrame(target, times.length-1, weight);
} else{
} else if (time > times[times.length - 1]) {
applyFrame(target, times.length - 1, weight);
} else {
int startFrame = 0;
for (int i = 0; i < times.length; i++){
if (times[i] < time)
for (int i = 0; i < times.length; i++) {
if (times[i] < time) {
startFrame = i;
}
}
int endFrame = startFrame + 1;
float blend = (time - times[startFrame]) / (times[endFrame] - times[startFrame]);
applyFrame(target, startFrame, blend * weight);
applyFrame(target, endFrame, (1f-blend) * weight);
applyFrame(target, endFrame, (1f - blend) * weight);
}
*/
}
/**
@ -155,13 +155,14 @@ public final class PoseTrack implements Track<Mesh[]> {
* This method creates a clone of the current object.
* @return a clone of the current object
*/
@Override
public PoseTrack clone() {
try {
PoseTrack result = (PoseTrack) super.clone();
result.times = this.times.clone();
if(this.frames!=null) {
if (this.frames != null) {
result.frames = new PoseFrame[this.frames.length];
for(int i=0;i<this.frames.length;++i) {
for (int i = 0; i < this.frames.length; ++i) {
result.frames[i] = this.frames[i].clone();
}
}
@ -186,29 +187,4 @@ public final class PoseTrack implements Track<Mesh[]> {
frames = (PoseFrame[]) in.readSavableArray("frames", null);
times = in.readFloatArray("times", null);
}
@Override
public Quaternion[] getRotations() {
return null;
}
@Override
public Vector3f[] getScales() {
return null;
}
@Override
public float[] getTimes() {
return null;
}
@Override
public Vector3f[] getTranslations() {
return null;
}
@Override
public void setKeyframes(float[] times, Vector3f[] translations,
Quaternion[] rotations, Vector3f[] scales) {
}
}

@ -54,6 +54,7 @@ public final class Skeleton implements Savable {
private Bone[] rootBones;
private Bone[] boneList;
/**
* Contains the skinning matrices, multiplying it by a vertex effected by a bone
* will cause it to go to the animated position.

@ -75,7 +75,7 @@ public class SkeletonControl extends AbstractControl implements Cloneable {
* @param skeleton the skeleton
*/
@Deprecated
public SkeletonControl(Mesh[] targets, Skeleton skeleton){
SkeletonControl(Mesh[] targets, Skeleton skeleton){
this.skeleton = skeleton;
this.targets = targets;
}

@ -9,29 +9,34 @@ import com.jme3.export.OutputCapsule;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.scene.Spatial;
import com.jme3.util.TempVars;
/**
* This class represents the track for spatial animation.
*
* @author Marcin Roguski (Kaelthas)
*/
public class SpatialTrack implements Track<Spatial> {
/** Translations of the track. */
public class SpatialTrack implements Track {
/**
* Translations of the track.
*/
private CompactVector3Array translations;
/** Rotations of the track. */
/**
* Rotations of the track.
*/
private CompactQuaternionArray rotations;
/** Scales of the track. */
/**
* Scales of the track.
*/
private CompactVector3Array scales;
/** The times of the animations frames. */
private float[] times;
// temp vectors for interpolation
private transient final Vector3f tempV = new Vector3f();
private transient final Quaternion tempQ = new Quaternion();
private transient final Vector3f tempS = new Vector3f();
private transient final Vector3f tempV2 = new Vector3f();
private transient final Quaternion tempQ2 = new Quaternion();
private transient final Vector3f tempS2 = new Vector3f();
/**
* The times of the animations frames.
*/
private float[] times;
public SpatialTrack() {
}
@ -50,7 +55,7 @@ public class SpatialTrack implements Track<Spatial> {
*/
public SpatialTrack(float[] times, Vector3f[] translations,
Quaternion[] rotations, Vector3f[] scales) {
this.setKeyframes(times, translations, rotations, scales);
setKeyframes(times, translations, rotations, scales);
}
/**
@ -62,7 +67,16 @@ public class SpatialTrack implements Track<Spatial> {
* @param spatial
* the spatial that should be animated with this track
*/
public void setTime(float time, Spatial spatial, float weight) {
public void setTime(float time, float weight, AnimControl control, AnimChannel channel, TempVars vars) {
Spatial spatial = control.getSpatial();
Vector3f tempV = vars.vect1;
Vector3f tempS = vars.vect2;
Quaternion tempQ = vars.quat1;
Vector3f tempV2 = vars.vect3;
Vector3f tempS2 = vars.vect4;
Quaternion tempQ2 = vars.quat2;
int lastFrame = times.length - 1;
if (time < 0 || lastFrame == 0) {
rotations.get(0, tempQ);
@ -101,6 +115,7 @@ public class SpatialTrack implements Track<Spatial> {
tempV.interpolate(tempV2, blend);
tempS.interpolate(tempS2, blend);
}
spatial.setLocalTranslation(tempV);
spatial.setLocalRotation(tempQ);
if (scales != null) {
@ -137,20 +152,15 @@ public class SpatialTrack implements Track<Spatial> {
this.rotations.add(rotations);
this.rotations.freeze();
if (scales != null) {
assert times.length == scales.length;
if (scales != null) {
this.scales = new CompactVector3Array();
this.scales.add(scales);
this.scales.freeze();
}
}
/**
* @return the index of the target object for this track
*/
public int getTargetIndex() {
return 0;
}
}
/**
@ -192,6 +202,7 @@ public class SpatialTrack implements Track<Spatial> {
* This method creates a clone of the current object.
* @return a clone of the current object
*/
@Override
public SpatialTrack clone() {
int tablesLength = times.length;

@ -32,70 +32,32 @@
package com.jme3.animation;
import com.jme3.export.Savable;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.util.TempVars;
/**
* A single track of mesh animation (either morph or pose based).
* Currently morph animations are not supported (only pose).
*/
public interface Track<T> extends Savable, Cloneable {
/**
* sets time for this track
* @param time
* @param target
* @param weight
*/
void setTime(float time, T target, float weight);
public interface Track extends Savable, Cloneable {
/**
* Set the translations, rotations and scales for this track.
* Sets the time of the animation.
*
* @param times
* a float array with the time of each frame
* @param translations
* the translation of the bone for each frame
* @param rotations
* the rotation of the bone for each frame
* @param scales
* the scale of the bone for each frame
*/
void setKeyframes(float[] times, Vector3f[] translations,
Quaternion[] rotations, Vector3f[] scales);
/**
* @return the index of the target object for this track
*/
int getTargetIndex();
/**
* @return the array of rotations of this track
*/
Quaternion[] getRotations();
/**
* @return the array of scales for this track
*/
Vector3f[] getScales();
/**
* @return the arrays of time for this track
*/
float[] getTimes();
/**
* @return the array of translations of this track
* Internally, the track will retrieve objects from the control
* and modify them according to the properties of the channel and the
* given parameters.
*
* @param time The time in the animation
* @param weight The weight from 0 to 1 on how much to apply the track
* @param control The control which the track should effect
* @param channel The channel which the track should effect
*/
Vector3f[] getTranslations();
public void setTime(float time, float weight, AnimControl control, AnimChannel channel, TempVars vars);
/**
* @return the length of the track
*/
float getLength();
public float getLength();
/**
* This method creates a clone of the current object.
* @return a clone of the current object
*/
Track<T> clone();
public Track clone();
}

@ -31,6 +31,7 @@
*/
package com.jme3.export;
import com.jme3.animation.Animation;
import com.jme3.effect.shapes.EmitterBoxShape;
import com.jme3.effect.shapes.EmitterMeshConvexHullShape;
import com.jme3.effect.shapes.EmitterMeshFaceShape;
@ -73,6 +74,8 @@ public class SavableClassUtil {
addRemapping("com.jme3.effect.EmitterMeshVertexShape", EmitterMeshVertexShape.class);
addRemapping("com.jme3.effect.EmitterPointShape", EmitterPointShape.class);
addRemapping("com.jme3.material.Material$MatParamTexture", MatParamTexture.class);
addRemapping("com.jme3.animation.BoneAnimation", Animation.class);
addRemapping("com.jme3.animation.SpatialAnimation", Animation.class);
}
private static String remapClass(String className) throws ClassNotFoundException {

Loading…
Cancel
Save