OSDN Git Service

[Changed] Added tagged joints. Will post blog explaining it
authordavedx@gmail.com <davedx@gmail.com@6c4fd544-2939-11df-bb46-9574ba5d0bfa>
Tue, 4 Jan 2011 17:41:56 +0000 (17:41 +0000)
committerdavedx@gmail.com <davedx@gmail.com@6c4fd544-2939-11df-bb46-9574ba5d0bfa>
Tue, 4 Jan 2011 17:41:56 +0000 (17:41 +0000)
gdx/src/com/badlogic/gdx/graphics/animation/Animator.java
gdx/src/com/badlogic/gdx/graphics/keyframed/Keyframe.java
gdx/src/com/badlogic/gdx/graphics/keyframed/KeyframeAnimator.java
gdx/src/com/badlogic/gdx/graphics/keyframed/KeyframedModel.java

index 5c55671..ac29151 100644 (file)
@@ -40,12 +40,13 @@ public abstract class Animator {
                mCurrentAnim = anim;\r
                mAnimLoop = loop;\r
 \r
+               mAnimPos = mFrameDelta = 0.f;\r
+               mCurrentFrameIdx = -1;\r
+               mNextFrameIdx = -1;\r
+\r
                if(mCurrentAnim != null)\r
                {\r
                        mAnimLen = mCurrentAnim.getLength(); \r
-                       mAnimPos = mFrameDelta = 0.f;\r
-                       mCurrentFrameIdx = -1;\r
-                       mNextFrameIdx = -1;\r
                }       \r
        }\r
        \r
@@ -106,7 +107,7 @@ public abstract class Animator {
                                mFrameDelta = 0.f;\r
                                mCurrentFrameIdx = currentFrameIdx;\r
                        }\r
-       \r
+\r
                        mFrameDelta += dt;\r
                        \r
                        setInterpolationFrames();\r
index d68dbb1..9b46b31 100644 (file)
@@ -12,6 +12,9 @@
  */\r
 package com.badlogic.gdx.graphics.keyframed;\r
 \r
+import com.badlogic.gdx.math.Quaternion;\r
+import com.badlogic.gdx.math.Vector3;\r
+\r
 /**\r
  * Container for the geometry of a single animation keyframe.\r
  * \r
@@ -23,4 +26,7 @@ public class Keyframe {
        public short[][] Indices = null;\r
        public boolean IndicesSet = false;\r
        public boolean IndicesSent = false;\r
+       \r
+       public Vector3[] TaggedJointPos = null;\r
+       public Quaternion[] TaggedJoint = null;\r
 }\r
index df5a623..df8cd29 100644 (file)
  */\r
 package com.badlogic.gdx.graphics.keyframed;\r
 \r
+import com.badlogic.gdx.Gdx;\r
 import com.badlogic.gdx.graphics.animation.Animator;\r
 import com.badlogic.gdx.graphics.loaders.md5.MD5Animation;\r
+import com.badlogic.gdx.graphics.loaders.md5.MD5Quaternion;\r
+import com.badlogic.gdx.math.Quaternion;\r
+import com.badlogic.gdx.math.Vector3;\r
 \r
 /**\r
  * An animation controller for keyframed animations.\r
@@ -70,12 +74,31 @@ public class KeyframeAnimator extends Animator {
                R.Indices[idx] = new short[numIndices];\r
        }\r
        \r
+       /**\r
+        * Set the number of tagged joints for allocation\r
+        * @param num\r
+        */\r
+       public void setNumTaggedJoints(int num)\r
+       {\r
+               // allocate space for joint data in the result keyframe\r
+               R.TaggedJointPos = new Vector3[num];\r
+               for(int i=0; i<num; i++)\r
+                       R.TaggedJointPos[i] = new Vector3();\r
+               R.TaggedJoint = new Quaternion[num];\r
+               for(int i=0; i<num; i++)\r
+                       R.TaggedJoint[i] = new Quaternion(0,0,0,0);\r
+       }\r
+       \r
        @Override\r
        protected void setInterpolationFrames() {\r
                A = ((KeyframeAnimation)mCurrentAnim).mKeyframes[mCurrentFrameIdx];\r
                B = ((KeyframeAnimation)mCurrentAnim).mKeyframes[mNextFrameIdx];\r
        }\r
 \r
+\r
+       static MD5Quaternion jointAOrient = new MD5Quaternion();\r
+       static MD5Quaternion jointBOrient = new MD5Quaternion();\r
+\r
        //TODO: Optimise further if possible - this is the CPU bottleneck for animation\r
        @Override\r
        protected void interpolate()\r
@@ -128,6 +151,37 @@ public class KeyframeAnimator extends Animator {
                        }\r
                }\r
                R.IndicesSet = true;\r
+               \r
+               //interpolate any tagged joints\r
+               for(int tj = 0; tj<A.TaggedJoint.length; tj++)\r
+               {\r
+                       //position\r
+                       float PAX = A.TaggedJointPos[tj].x;\r
+                       float PAY = A.TaggedJointPos[tj].y;\r
+                       float PAZ = A.TaggedJointPos[tj].z;\r
+                       float PBX = B.TaggedJointPos[tj].x;\r
+                       float PBY = B.TaggedJointPos[tj].y;\r
+                       float PBZ = B.TaggedJointPos[tj].z;\r
+\r
+                       R.TaggedJointPos[tj].x = PAX + (PBX - PAX)*t;\r
+                       R.TaggedJointPos[tj].y = PAY + (PBY - PAY)*t;\r
+                       R.TaggedJointPos[tj].z = PAZ + (PBZ - PAZ)*t;\r
+                       \r
+                       //orientation\r
+                       jointAOrient.x = A.TaggedJoint[tj].x;\r
+                       jointAOrient.y = A.TaggedJoint[tj].y;\r
+                       jointAOrient.z = A.TaggedJoint[tj].z;\r
+                       jointAOrient.w = A.TaggedJoint[tj].w;\r
+                       jointBOrient.x = B.TaggedJoint[tj].x;\r
+                       jointBOrient.y = B.TaggedJoint[tj].y;\r
+                       jointBOrient.z = B.TaggedJoint[tj].z;\r
+                       jointBOrient.w = B.TaggedJoint[tj].w;\r
+                       jointAOrient.slerp(jointBOrient, t);\r
+                       R.TaggedJoint[tj].x = jointAOrient.x;\r
+                       R.TaggedJoint[tj].y = jointAOrient.y;\r
+                       R.TaggedJoint[tj].z = jointAOrient.z;\r
+                       R.TaggedJoint[tj].w = jointAOrient.w;\r
+               }\r
        }\r
 \r
        /**\r
index ed4414a..dc84057 100644 (file)
@@ -14,6 +14,8 @@ package com.badlogic.gdx.graphics.keyframed;
 \r
 import java.io.DataInputStream;\r
 import java.io.DataOutputStream;\r
+import java.util.ArrayList;\r
+import java.util.Iterator;\r
 \r
 import com.badlogic.gdx.graphics.GL10;\r
 import com.badlogic.gdx.graphics.Material;\r
@@ -22,8 +24,11 @@ import com.badlogic.gdx.graphics.VertexAttributes;
 import com.badlogic.gdx.graphics.animation.Animator;\r
 import com.badlogic.gdx.graphics.loaders.md5.MD5Animation;\r
 import com.badlogic.gdx.graphics.loaders.md5.MD5Animator;\r
+import com.badlogic.gdx.graphics.loaders.md5.MD5Joints;\r
 import com.badlogic.gdx.graphics.loaders.md5.MD5Model;\r
 import com.badlogic.gdx.graphics.loaders.md5.MD5Renderer;\r
+import com.badlogic.gdx.math.Quaternion;\r
+import com.badlogic.gdx.math.Vector3;\r
 import com.badlogic.gdx.utils.GdxRuntimeException;\r
 import com.badlogic.gdx.utils.ObjectMap;\r
 \r
@@ -41,6 +46,7 @@ public class KeyframedModel {
        private KeyframeAnimator mAnimator = null;\r
        private Mesh[] mTarget = null;\r
        private int mNumMeshes = 0;\r
+       private ArrayList<String> mTaggedJointNames = new ArrayList<String>();\r
        \r
        /**\r
         * Gets the {@link KeyframeAnimator} for this model.\r
@@ -71,6 +77,16 @@ public class KeyframedModel {
                        mMaterials[i] = mats[i];\r
                }\r
        }\r
+       \r
+       /**\r
+        * Sets the tagged joints for this model's animations. Tagged joints have their data preserved post-sampling.\r
+        * @param joints\r
+        *           An array of joint names.\r
+        */\r
+       public void setTaggedJoints(ArrayList<String> joints)\r
+       {\r
+               mTaggedJointNames = joints;\r
+       }\r
 \r
        //TODO: Split this out to an MD5toKeyframe loader in com.badlogic.gdx.graphics.loaders\r
        /**\r
@@ -115,6 +131,11 @@ public class KeyframedModel {
                        Keyframe k = new Keyframe();\r
                        k.Vertices = new float[mNumMeshes][];\r
                        k.Indices = new short[mNumMeshes][];\r
+                       if(mTaggedJointNames.size() > 0)\r
+                       {\r
+                               k.TaggedJointPos = new Vector3[mTaggedJointNames.size()];\r
+                               k.TaggedJoint = new Quaternion[mTaggedJointNames.size()];\r
+                       }\r
                        \r
                        for(int m=0; m<mNumMeshes; m++)\r
                        {\r
@@ -130,6 +151,7 @@ public class KeyframedModel {
                                if(mTarget[m] == null)\r
                                {\r
                                        mAnimator.setKeyframeDimensions(m, numVertices, numIndices);\r
+                                       mAnimator.setNumTaggedJoints(mTaggedJointNames.size());\r
 \r
                                        VertexAttributes attribs = renderer.getMesh().getVertexAttributes();\r
                                        mTarget[m] = new Mesh(false, numVertices, numIndices, attribs);\r
@@ -138,6 +160,31 @@ public class KeyframedModel {
                                }\r
                        }\r
                        \r
+                       //store tagged joints.\r
+                       MD5Joints skel = animator.getSkeleton();\r
+                       for(int tj=0; tj<mTaggedJointNames.size(); tj++)\r
+                       {\r
+                               String name = mTaggedJointNames.get(tj);\r
+                               for(int j=0; j<skel.numJoints; j++)\r
+                               {\r
+                                       if(name.equals(skel.names[j]))\r
+                                       {\r
+                                               int idx = j*8;\r
+                                               float p = skel.joints[idx];\r
+                                               float x = skel.joints[idx+1];\r
+                                               float y = skel.joints[idx+2];\r
+                                               float z = skel.joints[idx+3];\r
+                                               k.TaggedJointPos[tj] = new Vector3(x, y, z);\r
+                                               float qx = skel.joints[idx+4];\r
+                                               float qy = skel.joints[idx+5];\r
+                                               float qz = skel.joints[idx+6];\r
+                                               float qw = skel.joints[idx+7];\r
+                                               k.TaggedJoint[tj] = new Quaternion(qx, qy, qz, qw);\r
+                                               break;\r
+                                       }\r
+                               }\r
+                       }\r
+                       \r
                        a.mKeyframes[i] = k;\r
                        \r
                        animator.update(sampleRate);\r
@@ -149,6 +196,16 @@ public class KeyframedModel {
                mAnimations.put(animKey, a);\r
        }\r
        \r
+       public void getJointData(int tagIndex, Vector3 pos, Quaternion orient)\r
+       {\r
+               Keyframe kf = mAnimator.getInterpolatedKeyframe();\r
+               pos.set(kf.TaggedJointPos[tagIndex]);\r
+               orient.x = kf.TaggedJoint[tagIndex].x;\r
+               orient.y = kf.TaggedJoint[tagIndex].y;\r
+               orient.z = kf.TaggedJoint[tagIndex].z;\r
+               orient.w = kf.TaggedJoint[tagIndex].w;\r
+       }\r
+       \r
        /**\r
         * Set the current playing animation.\r
         * @param animKey\r