From e3366f14b8531c4694db8c314254f5d3dd202b78 Mon Sep 17 00:00:00 2001 From: "sha..rd" Date: Sun, 16 Oct 2011 23:15:55 +0000 Subject: [PATCH] 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 --- .../blender/animations/ArmatureHelper.java | 19 +- .../scene/plugins/blender/animations/Ipo.java | 16 +- .../blender/constraints/Constraint.java | 25 +- .../constraints/ConstraintDistLimit.java | 3 +- .../constraints/ConstraintLocLike.java | 3 +- .../constraints/ConstraintLocLimit.java | 3 +- .../constraints/ConstraintRotLike.java | 3 +- .../constraints/ConstraintRotLimit.java | 3 +- .../constraints/ConstraintShrinkWrap.java | 3 +- .../constraints/ConstraintSizeLike.java | 3 +- .../constraints/ConstraintSizeLimit.java | 3 +- .../blender/materials/MaterialHelper.java | 7 +- .../blender/modifiers/ArmatureModifier.java | 5 +- .../modifiers/ObjectAnimationModifier.java | 5 +- .../core/com/jme3/animation/AnimChannel.java | 9 +- .../core/com/jme3/animation/AnimControl.java | 20 +- .../core/com/jme3/animation/Animation.java | 175 ++++---- engine/src/core/com/jme3/animation/Bone.java | 27 +- .../com/jme3/animation/BoneAnimation.java | 143 +------ .../core/com/jme3/animation/BoneTrack.java | 69 +-- .../com/jme3/animation/MeshAnimation.java | 101 ----- .../core/com/jme3/animation/PoseTrack.java | 114 ++--- .../src/core/com/jme3/animation/Skeleton.java | 1 + .../com/jme3/animation/SkeletonControl.java | 2 +- .../core/com/jme3/animation/SpatialTrack.java | 397 +++++++++--------- engine/src/core/com/jme3/animation/Track.java | 78 +--- .../com/jme3/export/SavableClassUtil.java | 3 + 27 files changed, 493 insertions(+), 747 deletions(-) delete mode 100644 engine/src/core/com/jme3/animation/MeshAnimation.java diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/animations/ArmatureHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/animations/ArmatureHelper.java index fc56a9d88..067dbd2b8 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/animations/ArmatureHelper.java +++ b/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> tracks = new ArrayList>(); + List tracks = new ArrayList(); 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> tracks = new ArrayList>(); + List tracks = new ArrayList(); 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()]); } /** diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/animations/Ipo.java b/engine/src/blender/com/jme3/scene/plugins/blender/animations/Ipo.java index cb5e330cc..bdc6a667b 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/animations/Ipo.java +++ b/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; diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/Constraint.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/Constraint.java index 1e1bf2f4b..5c96c195a 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/Constraint.java +++ b/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; } /** diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintDistLimit.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintDistLimit.java index 820a729cb..891898845 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintDistLimit.java +++ b/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(); diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintLocLike.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintLocLike.java index 380299c12..dac463dc5 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintLocLike.java +++ b/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(); diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintLocLimit.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintLocLimit.java index 4bb9a9a49..4e2df2241 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintLocLimit.java +++ b/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(); diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintRotLike.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintRotLike.java index 30b4dc0a9..397e349cf 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintRotLike.java +++ b/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(); diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintRotLimit.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintRotLimit.java index d251d2e64..a5447c68b 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintRotLimit.java +++ b/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(); diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintShrinkWrap.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintShrinkWrap.java index 1e245e32d..332405d0d 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintShrinkWrap.java +++ b/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(); diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintSizeLike.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintSizeLike.java index 35cc71b05..b8fa27836 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintSizeLike.java +++ b/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(); diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintSizeLimit.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintSizeLimit.java index 8ebb9d401..51796a8c0 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintSizeLimit.java +++ b/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(); diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialHelper.java index 7b53bd75b..d172216da 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialHelper.java +++ b/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); diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/modifiers/ArmatureModifier.java b/engine/src/blender/com/jme3/scene/plugins/blender/modifiers/ArmatureModifier.java index dec836874..62e383e5b 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/modifiers/ArmatureModifier.java +++ b/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; diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/modifiers/ObjectAnimationModifier.java b/engine/src/blender/com/jme3/scene/plugins/blender/modifiers/ObjectAnimationModifier.java index dd6e92e7c..3d0737019 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/modifiers/ObjectAnimationModifier.java +++ b/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 animations = new ArrayList(1); animations.add(animation); diff --git a/engine/src/core/com/jme3/animation/AnimChannel.java b/engine/src/core/com/jme3/animation/AnimChannel.java index 0ae5ec0f9..a2fae7ccc 100644 --- a/engine/src/core/com/jme3/animation/AnimChannel.java +++ b/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 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; diff --git a/engine/src/core/com/jme3/animation/AnimControl.java b/engine/src/core/com/jme3/animation/AnimControl.java index 0717406da..ad56f3096 100644 --- a/engine/src/core/com/jme3/animation/AnimControl.java +++ b/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(); + if (skeleton != null){ clone.skeleton = new Skeleton(skeleton); } - clone.channels = new ArrayList(); // 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) 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]; diff --git a/engine/src/core/com/jme3/animation/Animation.java b/engine/src/core/com/jme3/animation/Animation.java index f59e6178d..330a5c885 100644 --- a/engine/src/core/com/jme3/animation/Animation.java +++ b/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 Animation 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 meshes = new ArrayList(); - 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 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 meshes = new ArrayList(); + 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. *

- * 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); - } + } } diff --git a/engine/src/core/com/jme3/animation/Bone.java b/engine/src/core/com/jme3/animation/Bone.java index c1b2a0c5c..2be9b7e68 100644 --- a/engine/src/core/com/jme3/animation/Bone.java +++ b/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)); } /** diff --git a/engine/src/core/com/jme3/animation/BoneAnimation.java b/engine/src/core/com/jme3/animation/BoneAnimation.java index 9494d4087..f5ffd408e 100644 --- a/engine/src/core/com/jme3/animation/BoneAnimation.java +++ b/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; - /** - * BoneAnimation 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. - *

- * 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); } } diff --git a/engine/src/core/com/jme3/animation/BoneTrack.java b/engine/src/core/com/jme3/animation/BoneTrack.java index 7fcf7fbd6..aa73106ae 100644 --- a/engine/src/core/com/jme3/animation/BoneTrack.java +++ b/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 { +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 { 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 { 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 { } /** - * 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 { * @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 { } /** - * @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 { 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 { 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 { } } } + + public void setTime(float time, float weight, AnimControl control, AnimChannel channel) { + throw new UnsupportedOperationException("Not supported yet."); + } } diff --git a/engine/src/core/com/jme3/animation/MeshAnimation.java b/engine/src/core/com/jme3/animation/MeshAnimation.java deleted file mode 100644 index e36f57390..000000000 --- a/engine/src/core/com/jme3/animation/MeshAnimation.java +++ /dev/null @@ -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); - } -} diff --git a/engine/src/core/com/jme3/animation/PoseTrack.java b/engine/src/core/com/jme3/animation/PoseTrack.java index b61de5a9d..83785746e 100644 --- a/engine/src/core/com/jme3/animation/PoseTrack.java +++ b/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 { +@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 { * 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.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 { 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 { 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) { - } } diff --git a/engine/src/core/com/jme3/animation/Skeleton.java b/engine/src/core/com/jme3/animation/Skeleton.java index 672359117..59e78edcb 100644 --- a/engine/src/core/com/jme3/animation/Skeleton.java +++ b/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. diff --git a/engine/src/core/com/jme3/animation/SkeletonControl.java b/engine/src/core/com/jme3/animation/SkeletonControl.java index 461c88719..61ba80b8c 100644 --- a/engine/src/core/com/jme3/animation/SkeletonControl.java +++ b/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; } diff --git a/engine/src/core/com/jme3/animation/SpatialTrack.java b/engine/src/core/com/jme3/animation/SpatialTrack.java index 4b4de7327..c839ecb67 100644 --- a/engine/src/core/com/jme3/animation/SpatialTrack.java +++ b/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 { - /** 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 { } //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); + } } diff --git a/engine/src/core/com/jme3/animation/Track.java b/engine/src/core/com/jme3/animation/Track.java index 047f4e004..a56807d08 100644 --- a/engine/src/core/com/jme3/animation/Track.java +++ b/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 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 clone(); + public Track clone(); } diff --git a/engine/src/core/com/jme3/export/SavableClassUtil.java b/engine/src/core/com/jme3/export/SavableClassUtil.java index 6b29dafa9..d99372072 100644 --- a/engine/src/core/com/jme3/export/SavableClassUtil.java +++ b/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 {