Browse Source

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

sha..rd 14 years ago
parent
commit
e3366f14b8
27 changed files with 493 additions and 747 deletions
  1. 10 9
      engine/src/blender/com/jme3/scene/plugins/blender/animations/ArmatureHelper.java
  2. 12 4
      engine/src/blender/com/jme3/scene/plugins/blender/animations/Ipo.java
  3. 13 12
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/Constraint.java
  4. 2 1
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintDistLimit.java
  5. 2 1
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintLocLike.java
  6. 2 1
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintLocLimit.java
  7. 2 1
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintRotLike.java
  8. 2 1
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintRotLimit.java
  9. 2 1
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintShrinkWrap.java
  10. 2 1
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintSizeLike.java
  11. 2 1
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintSizeLimit.java
  12. 4 3
      engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialHelper.java
  13. 3 2
      engine/src/blender/com/jme3/scene/plugins/blender/modifiers/ArmatureModifier.java
  14. 3 2
      engine/src/blender/com/jme3/scene/plugins/blender/modifiers/ObjectAnimationModifier.java
  15. 5 4
      engine/src/core/com/jme3/animation/AnimChannel.java
  16. 12 8
      engine/src/core/com/jme3/animation/AnimControl.java
  17. 88 87
      engine/src/core/com/jme3/animation/Animation.java
  18. 15 12
      engine/src/core/com/jme3/animation/Bone.java
  19. 2 141
      engine/src/core/com/jme3/animation/BoneAnimation.java
  20. 36 33
      engine/src/core/com/jme3/animation/BoneTrack.java
  21. 0 101
      engine/src/core/com/jme3/animation/MeshAnimation.java
  22. 45 69
      engine/src/core/com/jme3/animation/PoseTrack.java
  23. 1 0
      engine/src/core/com/jme3/animation/Skeleton.java
  24. 1 1
      engine/src/core/com/jme3/animation/SkeletonControl.java
  25. 204 193
      engine/src/core/com/jme3/animation/SpatialTrack.java
  26. 20 58
      engine/src/core/com/jme3/animation/Track.java
  27. 3 0
      engine/src/core/com/jme3/export/SavableClassUtil.java

+ 10 - 9
engine/src/blender/com/jme3/scene/plugins/blender/animations/ArmatureHelper.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()]);
     }
 
     /**

+ 12 - 4
engine/src/blender/com/jme3/scene/plugins/blender/animations/Ipo.java

@@ -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;

+ 13 - 12
engine/src/blender/com/jme3/scene/plugins/blender/constraints/Constraint.java

@@ -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;
@@ -91,7 +92,7 @@ public abstract class Constraint {
 	 */
 	public abstract ConstraintType getType();
 
-	/**
+    /**
      * This method returns the bone traces for the bone that is affected by the given constraint.
      * @param skeleton
      *        the skeleton containing bones
@@ -99,17 +100,17 @@ 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) {
-    				return track;
-    			}
-    		}
-    	} else {//spatial animation
-    		return animation.getTracks()[0];
-    	}
-    	return null;
+    protected Track getTrack(Animation animation, int targetIndex) {
+        if (boneOMA >= 0) {//bone animation
+            for (Track track : animation.getTracks()) {
+                if (((BoneTrack) track).getTargetBoneIndex() == targetIndex) {
+                    return track;
+                }
+            }
+        } else {//spatial animation
+            return animation.getTracks()[0];
+        }
+        return null;
     }
     
     /**

+ 2 - 1
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintDistLimit.java

@@ -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();

+ 2 - 1
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintLocLike.java

@@ -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();

+ 2 - 1
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintLocLimit.java

@@ -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();

+ 2 - 1
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintRotLike.java

@@ -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();

+ 2 - 1
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintRotLimit.java

@@ -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();

+ 2 - 1
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintShrinkWrap.java

@@ -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();

+ 2 - 1
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintSizeLike.java

@@ -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();

+ 2 - 1
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintSizeLimit.java

@@ -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();

+ 4 - 3
engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialHelper.java

@@ -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);

+ 3 - 2
engine/src/blender/com/jme3/scene/plugins/blender/modifiers/ArmatureModifier.java

@@ -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;

+ 3 - 2
engine/src/blender/com/jme3/scene/plugins/blender/modifiers/ObjectAnimationModifier.java

@@ -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);
 

+ 5 - 4
engine/src/core/com/jme3/animation/AnimChannel.java

@@ -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;
 

+ 12 - 8
engine/src/core/com/jme3/animation/AnimControl.java

@@ -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];

+ 88 - 87
engine/src/core/com/jme3/animation/Animation.java

@@ -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. */
-	private String name;
-	/** The length of the animation. */
+    
+    /** 
+     * The name of the animation. 
+     */
+    private String name;
+    
+    /** 
+     * 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) {
-    		Track<?> trackInstance = tracks[0];
-    		if(trackInstance instanceof SpatialTrack) {
-    			Spatial spatial = control.getSpatial();
-    			if (spatial != null) {
-    				((SpatialTrack)tracks[0]).setTime(time, spatial, blendAmount);
-    			}
-    		} 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);
-    	            }
-    	        }
-    		} else if(trackInstance instanceof PoseTrack) {
-    			Spatial spatial = control.getSpatial();
-    			List<Mesh> meshes = new ArrayList<Mesh>();
-    			this.getMeshes(spatial, meshes);
-    			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);
-        	        }
-    			}
-    		}
-    	}
-    }
-    
-    /**
-     * 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);
-			}
-		}
+    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) {
+                Spatial spatial = control.getSpatial();
+                if (spatial != null) {
+                    ((SpatialTrack) tracks[0]).setTime(time, spatial, blendAmount);
+                }
+            } 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);
+                    }
+                }
+            } else if (trackInstance instanceof PoseTrack) {
+                Spatial spatial = control.getSpatial();
+                List<Mesh> meshes = new ArrayList<Mesh>();
+                this.getMeshes(spatial, meshes);
+                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);
+                    }
+                }
+            }
+        }
+        */
     }
     
     /**
      * 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,16 +167,15 @@ public class Animation implements Savable, Cloneable {
      * This method creates a clone of the current object.
      * @return a clone of the current object
      */
-	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();
-                }
+   @Override
+   public Animation clone() {
+        try {
+            Animation result = (Animation) super.clone();
+            result.tracks = tracks.clone();
+            for (int i = 0; i < tracks.length; ++i) {
+                result.tracks[i] = this.tracks[i].clone();
             }
-    		return result;
+            return result;
         } catch (CloneNotSupportedException e) {
             throw new AssertionError();
         }
@@ -183,24 +183,25 @@ public class Animation implements Savable, Cloneable {
 
     @Override
     public String toString() {
-        return "Animation[name=" + name + ", length=" + length + ']';
+        return getClass().getSimpleName() + "[name=" + name + ", length=" + length + ']';
     }
     
-	@Override
-	public void write(JmeExporter ex) throws IOException {
-		OutputCapsule out = ex.getCapsule(this);
+   @Override
+    public void write(JmeExporter ex) throws IOException {
+        OutputCapsule out = ex.getCapsule(this);
         out.write(name, "name", null);
         out.write(length, "length", 0f);
         out.write(tracks, "tracks", null);
-	}
+    }
 
-	@Override
-	public void read(JmeImporter im) throws IOException {
-		InputCapsule in = im.getCapsule(this);
+    @Override
+    public void read(JmeImporter im) throws IOException {
+        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);
-	}
+    }
 }

+ 15 - 12
engine/src/core/com/jme3/animation/Bone.java

@@ -413,27 +413,30 @@ 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));
     }
 
     /**

+ 2 - 141
engine/src/core/com/jme3/animation/BoneAnimation.java

@@ -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);
     }
 }

+ 36 - 33
engine/src/core/com/jme3/animation/BoneTrack.java

@@ -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,14 +61,7 @@ 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.
      */
@@ -105,22 +101,13 @@ public final class BoneTrack implements Track<Skeleton> {
         this.targetBoneIndex = targetBoneIndex;
     }
 
-	/**
-     * @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 
@@ -176,7 +163,7 @@ public final class BoneTrack implements Track<Skeleton> {
     }
 
     /**
-     *  Set the translations, rotations and scales for this bone track
+     * Set the translations, rotations and scales for this bone track
      * @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
@@ -202,9 +189,21 @@ 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) {
             rotations.get(0, tempQ);
@@ -254,17 +253,18 @@ public final class BoneTrack implements Track<Skeleton> {
     }
     
     /**
-	 * @return the length of the track
-	 */
-	public float getLength() {
-		return times == null ? 0 : times[times.length - 1] - times[0];
-	}
+     * @return the length of the track
+     */
+    public float getLength() {
+        return times == null ? 0 : times[times.length - 1] - times[0];
+    }
 
     /**
      * This method creates a clone of the current object.
      * @return a clone of the current object
      */
-	public BoneTrack clone() {
+    @Override
+    public BoneTrack clone() {
         int tablesLength = times.length;
 
         float[] times = this.times.clone();
@@ -280,9 +280,10 @@ 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);
-	}
+    }
     
     @Override
     public void write(JmeExporter ex) throws IOException {
@@ -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.");
+    }
 }

+ 0 - 101
engine/src/core/com/jme3/animation/MeshAnimation.java

@@ -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);
-    }
-}

+ 45 - 69
engine/src/core/com/jme3/animation/PoseTrack.java

@@ -37,29 +37,29 @@ 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;
+    private float[] times;
 
     public static class PoseFrame implements Savable, Cloneable {
 
         Pose[] poses;
         float[] weights;
 
-        public PoseFrame(Pose[] poses, float[] weights){
+        public PoseFrame(Pose[] poses, float[] weights) {
             this.poses = poses;
             this.weights = weights;
         }
@@ -68,21 +68,22 @@ 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();
+            try {
+                PoseFrame result = (PoseFrame) super.clone();
                 result.weights = this.weights.clone();
-                if(this.poses != null) {
-                	result.poses = new Pose[this.poses.length];
-                	for(int i=0;i<this.poses.length;++i) {
-                		result.poses[i] = this.poses[i].clone();
-                	}
+                if (this.poses != null) {
+                    result.poses = new Pose[this.poses.length];
+                    for (int i = 0; i < this.poses.length; ++i) {
+                        result.poses[i] = this.poses[i].clone();
+                    }
                 }
-        		return result;
+                return result;
             } catch (CloneNotSupportedException e) {
                 throw new AssertionError();
             }
-    	}
+        }
 
         public void write(JmeExporter e) throws IOException {
             OutputCapsule out = e.getCapsule(this);
@@ -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,52 +118,59 @@ 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);
         }
+        */
     }
 
     /**
-	 * @return the length of the track
-	 */
-	public float getLength() {
-		return times == null ? 0 : times[times.length - 1] - times[0];
-	}
+     * @return the length of the track
+     */
+    public float getLength() {
+        return times == null ? 0 : times[times.length - 1] - times[0];
+    }
     
     /**
      * 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();
+        try {
+            PoseTrack result = (PoseTrack) super.clone();
             result.times = this.times.clone();
-            if(this.frames!=null) {
-            	result.frames = new PoseFrame[this.frames.length];
-            	for(int i=0;i<this.frames.length;++i) {
-            		result.frames[i] = this.frames[i].clone();
-            	}
+            if (this.frames != null) {
+                result.frames = new PoseFrame[this.frames.length];
+                for (int i = 0; i < this.frames.length; ++i) {
+                    result.frames[i] = this.frames[i].clone();
+                }
             }
-    		return result;
+            return result;
         } catch (CloneNotSupportedException e) {
             throw new AssertionError();
         }
-	}
+    }
     
     @Override
     public void write(JmeExporter e) throws IOException {
@@ -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) {
-	}
 }

+ 1 - 0
engine/src/core/com/jme3/animation/Skeleton.java

@@ -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.

+ 1 - 1
engine/src/core/com/jme3/animation/SkeletonControl.java

@@ -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;
     }

+ 204 - 193
engine/src/core/com/jme3/animation/SpatialTrack.java

@@ -9,190 +9,201 @@ 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. */
-	private CompactVector3Array translations;
-	/** Rotations of the track. */
-	private CompactQuaternionArray rotations;
-	/** 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();
-
-	public SpatialTrack() {
-	}
-
-	/**
-	 * Creates a spatial track for the given track data.
-	 * 
-	 * @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
-	 */
-	public SpatialTrack(float[] times, Vector3f[] translations,
-						Quaternion[] rotations, Vector3f[] scales) {
-		this.setKeyframes(times, translations, rotations, scales);
-	}
-
-	/**
-	 * 
-	 * Modify the spatial which this track modifies.
-	 * 
-	 * @param time
-	 *            the current time of the animation
-	 * @param spatial
-	 *            the spatial that should be animated with this track
-	 */
-	public void setTime(float time, Spatial spatial, float weight) {
-		int lastFrame = times.length - 1;
-		if (time < 0 || lastFrame == 0) {
-			rotations.get(0, tempQ);
-			translations.get(0, tempV);
-			if (scales != null) {
-				scales.get(0, tempS);
-			}
-		} else if (time >= times[lastFrame]) {
-			rotations.get(lastFrame, tempQ);
-			translations.get(lastFrame, tempV);
-			if (scales != null) {
-				scales.get(lastFrame, tempS);
-			}
-		} else {
-			int startFrame = 0;
-			int endFrame = 1;
-			// use lastFrame so we never overflow the array
-			for (int i = 0; i < lastFrame && times[i] < time; ++i) {
-				startFrame = i;
-				endFrame = i + 1;
-			}
-
-			float blend = (time - times[startFrame]) / (times[endFrame] - times[startFrame]);
-
-			rotations.get(startFrame, tempQ);
-			translations.get(startFrame, tempV);
-			if (scales != null) {
-				scales.get(startFrame, tempS);
-			}
-			rotations.get(endFrame, tempQ2);
-			translations.get(endFrame, tempV2);
-			if (scales != null) {
-				scales.get(endFrame, tempS2);
-			}
-			tempQ.nlerp(tempQ2, blend);
-			tempV.interpolate(tempV2, blend);
-			tempS.interpolate(tempS2, blend);
-		}
-		spatial.setLocalTranslation(tempV);
-		spatial.setLocalRotation(tempQ);
-		if (scales != null) {
-			spatial.setLocalScale(tempS);
-		}
-	}
-
-	/**
-	 * Set the translations, rotations and scales for this track.
-	 * 
-	 * @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
-	 */
-	public void setKeyframes(float[] times, Vector3f[] translations,
-							 Quaternion[] rotations, Vector3f[] scales) {
-		if (times.length == 0) {
-			throw new RuntimeException("BoneTrack with no keyframes!");
-		}
-
-		assert times.length == translations.length
-				&& times.length == rotations.length;
-
-		this.times = times;
-		this.translations = new CompactVector3Array();
-		this.translations.add(translations);
-		this.translations.freeze();
-		this.rotations = new CompactQuaternionArray();
-		this.rotations.add(rotations);
-		this.rotations.freeze();
-
-		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;
-	}
-	
-	/**
-	 * @return the array of rotations of this track
-	 */
-	public Quaternion[] getRotations() {
-		return rotations.toObjectArray();
-	}
-
-	/**
-	 * @return the array of scales for this track
-	 */
-	public Vector3f[] getScales() {
-		return scales == null ? null : scales.toObjectArray();
-	}
-
-	/**
-	 * @return the arrays of time for this track
-	 */
-	public float[] getTimes() {
-		return times;
-	}
-
-	/**
-	 * @return the array of translations of this track
-	 */
-	public Vector3f[] getTranslations() {
-		return translations.toObjectArray();
-	}
-	
-	/**
-	 * @return the length of the track
-	 */
-	public float getLength() {
-		return times == null ? 0 : times[times.length - 1] - times[0];
-	}
-
-	/**
+public class SpatialTrack implements Track {
+    
+    /** 
+     * Translations of the track. 
+     */
+    private CompactVector3Array translations;
+    
+    /** 
+     * Rotations of the track. 
+     */
+    private CompactQuaternionArray rotations;
+    
+    /**
+     * Scales of the track. 
+     */
+    private CompactVector3Array scales;
+    
+    /** 
+     * The times of the animations frames. 
+     */
+    private float[] times;
+
+    public SpatialTrack() {
+    }
+
+    /**
+     * Creates a spatial track for the given track data.
+     * 
+     * @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
+     */
+    public SpatialTrack(float[] times, Vector3f[] translations,
+                        Quaternion[] rotations, Vector3f[] scales) {
+        setKeyframes(times, translations, rotations, scales);
+    }
+
+    /**
+     * 
+     * Modify the spatial which this track modifies.
+     * 
+     * @param time
+     *            the current time of the animation
+     * @param spatial
+     *            the spatial that should be animated with this track
+     */
+    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);
+            translations.get(0, tempV);
+            if (scales != null) {
+                scales.get(0, tempS);
+            }
+        } else if (time >= times[lastFrame]) {
+            rotations.get(lastFrame, tempQ);
+            translations.get(lastFrame, tempV);
+            if (scales != null) {
+                scales.get(lastFrame, tempS);
+            }
+        } else {
+            int startFrame = 0;
+            int endFrame = 1;
+            // use lastFrame so we never overflow the array
+            for (int i = 0; i < lastFrame && times[i] < time; ++i) {
+                startFrame = i;
+                endFrame = i + 1;
+            }
+
+            float blend = (time - times[startFrame]) / (times[endFrame] - times[startFrame]);
+
+            rotations.get(startFrame, tempQ);
+            translations.get(startFrame, tempV);
+            if (scales != null) {
+                scales.get(startFrame, tempS);
+            }
+            rotations.get(endFrame, tempQ2);
+            translations.get(endFrame, tempV2);
+            if (scales != null) {
+                scales.get(endFrame, tempS2);
+            }
+            tempQ.nlerp(tempQ2, blend);
+            tempV.interpolate(tempV2, blend);
+            tempS.interpolate(tempS2, blend);
+        }
+        
+        spatial.setLocalTranslation(tempV);
+        spatial.setLocalRotation(tempQ);
+        if (scales != null) {
+            spatial.setLocalScale(tempS);
+        }
+    }
+
+    /**
+     * Set the translations, rotations and scales for this track.
+     * 
+     * @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
+     */
+    public void setKeyframes(float[] times, Vector3f[] translations,
+                             Quaternion[] rotations, Vector3f[] scales) {
+        if (times.length == 0) {
+            throw new RuntimeException("BoneTrack with no keyframes!");
+        }
+
+        assert times.length == translations.length
+                && times.length == rotations.length;
+
+        this.times = times;
+        this.translations = new CompactVector3Array();
+        this.translations.add(translations);
+        this.translations.freeze();
+        this.rotations = new CompactQuaternionArray();
+        this.rotations.add(rotations);
+        this.rotations.freeze();
+
+        if (scales != null) {
+            assert times.length == scales.length;
+            
+            this.scales = new CompactVector3Array();
+            this.scales.add(scales);
+            this.scales.freeze();
+            
+            
+        }
+    }
+
+    /**
+     * @return the array of rotations of this track
+     */
+    public Quaternion[] getRotations() {
+            return rotations.toObjectArray();
+    }
+
+    /**
+     * @return the array of scales for this track
+     */
+    public Vector3f[] getScales() {
+            return scales == null ? null : scales.toObjectArray();
+    }
+
+    /**
+     * @return the arrays of time for this track
+     */
+    public float[] getTimes() {
+            return times;
+    }
+
+    /**
+     * @return the array of translations of this track
+     */
+    public Vector3f[] getTranslations() {
+            return translations.toObjectArray();
+    }
+
+    /**
+     * @return the length of the track
+     */
+    public float getLength() {
+            return times == null ? 0 : times[times.length - 1] - times[0];
+    }
+
+    /**
      * This method creates a clone of the current object.
      * @return a clone of the current object
      */
-	public SpatialTrack clone() {
+    @Override
+    public SpatialTrack clone() {
         int tablesLength = times.length;
 
         float[] times = this.times.clone();
@@ -210,23 +221,23 @@ public class SpatialTrack implements Track<Spatial> {
         }
         //need to use the constructor here because of the final fields used in this class
         return new SpatialTrack(times, translations, rotations, scales);
-	}
+    }
 	
-	@Override
-	public void write(JmeExporter ex) throws IOException {
-		OutputCapsule oc = ex.getCapsule(this);
-		oc.write(translations, "translations", null);
-		oc.write(rotations, "rotations", null);
-		oc.write(times, "times", null);
-		oc.write(scales, "scales", null);
-	}
-
-	@Override
-	public void read(JmeImporter im) throws IOException {
-		InputCapsule ic = im.getCapsule(this);
-		translations = (CompactVector3Array) ic.readSavable("translations", null);
-		rotations = (CompactQuaternionArray) ic.readSavable("rotations", null);
-		times = ic.readFloatArray("times", null);
-		scales = (CompactVector3Array) ic.readSavable("scales", null);
-	}
+    @Override
+    public void write(JmeExporter ex) throws IOException {
+        OutputCapsule oc = ex.getCapsule(this);
+        oc.write(translations, "translations", null);
+        oc.write(rotations, "rotations", null);
+        oc.write(times, "times", null);
+        oc.write(scales, "scales", null);
+    }
+
+    @Override
+    public void read(JmeImporter im) throws IOException {
+        InputCapsule ic = im.getCapsule(this);
+        translations = (CompactVector3Array) ic.readSavable("translations", null);
+        rotations = (CompactQuaternionArray) ic.readSavable("rotations", null);
+        times = ic.readFloatArray("times", null);
+        scales = (CompactVector3Array) ic.readSavable("scales", null);
+    }
 }

+ 20 - 58
engine/src/core/com/jme3/animation/Track.java

@@ -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;
+
+public interface Track extends Savable, Cloneable {
 
-/**
- * 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 
+     * Sets the time of the animation.
+     * 
+     * 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
      */
-    void setTime(float time, T target, float weight);
-    
-    /**
-	 * Set the translations, rotations and scales for this track.
-	 * 
-	 * @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();
+    public void setTime(float time, float weight, AnimControl control, AnimChannel channel, TempVars vars);
 
-	/**
-	 * @return the array of scales for this track
-	 */
-	Vector3f[] getScales();
-
-	/**
-	 * @return the arrays of time for this track
-	 */
-	float[] getTimes();
+    /**
+     * @return the length of the track
+     */
+    public float getLength();
 
-	/**
-	 * @return the array of translations of this track
-	 */
-	Vector3f[] getTranslations();
-	
-	/**
-	 * @return the length of the track
-	 */
-	float getLength();
-	
-	/**
+    /**
      * This method creates a clone of the current object.
      * @return a clone of the current object
      */
-	Track<T> clone();
+    public Track clone();
 }

+ 3 - 0
engine/src/core/com/jme3/export/SavableClassUtil.java

@@ -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 {