Browse Source

- separate update() call in KinematicRagdollControl to multiple methods to make them run hot quicker

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10374 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
nor..67 12 years ago
parent
commit
56244c7744

+ 84 - 76
engine/src/bullet-common/com/jme3/bullet/control/KinematicRagdollControl.java

@@ -193,108 +193,116 @@ public class KinematicRagdollControl extends AbstractPhysicsControl implements P
         if (!enabled) {
             return;
         }
-        TempVars vars = TempVars.get();
 
+        //if the ragdoll has the control of the skeleton, we update each bone with its position in physic world space.
+        if (mode == mode.Ragdoll && targetModel.getLocalTranslation().equals(modelPosition)) {
+            ragDollUpdate(tpf);
+        } else {
+            kinematicUpdate(tpf);
+        }
+    }
+
+    protected void ragDollUpdate(float tpf) {
+        TempVars vars = TempVars.get();
         Quaternion tmpRot1 = vars.quat1;
         Quaternion tmpRot2 = vars.quat2;
+        
+        for (PhysicsBoneLink link : boneLinks.values()) {
 
-        //if the ragdoll has the control of the skeleton, we update each bone with its position in physic world space.
-        if (mode == mode.Ragdoll && targetModel.getLocalTranslation().equals(modelPosition)) {
-            for (PhysicsBoneLink link : boneLinks.values()) {
+            Vector3f position = vars.vect1;
 
-                Vector3f position = vars.vect1;
+            //retrieving bone position in physic world space
+            Vector3f p = link.rigidBody.getMotionState().getWorldLocation();
+            //transforming this position with inverse transforms of the model
+            targetModel.getWorldTransform().transformInverseVector(p, position);
 
-                //retrieving bone position in physic world space
-                Vector3f p = link.rigidBody.getMotionState().getWorldLocation();
-                //transforming this position with inverse transforms of the model
-                targetModel.getWorldTransform().transformInverseVector(p, position);
+            //retrieving bone rotation in physic world space
+            Quaternion q = link.rigidBody.getMotionState().getWorldRotationQuat();
 
-                //retrieving bone rotation in physic world space
-                Quaternion q = link.rigidBody.getMotionState().getWorldRotationQuat();
+            //multiplying this rotation by the initialWorld rotation of the bone, 
+            //then transforming it with the inverse world rotation of the model
+            tmpRot1.set(q).multLocal(link.initalWorldRotation);
+            tmpRot2.set(targetModel.getWorldRotation()).inverseLocal().mult(tmpRot1, tmpRot1);
+            tmpRot1.normalizeLocal();
 
-                //multiplying this rotation by the initialWorld rotation of the bone, 
-                //then transforming it with the inverse world rotation of the model
-                tmpRot1.set(q).multLocal(link.initalWorldRotation);
-                tmpRot2.set(targetModel.getWorldRotation()).inverseLocal().mult(tmpRot1, tmpRot1);
-                tmpRot1.normalizeLocal();
+            //if the bone is the root bone, we apply the physic's transform to the model, so its position and rotation are correctly updated
+            if (link.bone.getParent() == null) {
 
-                //if the bone is the root bone, we apply the physic's transform to the model, so its position and rotation are correctly updated
-                if (link.bone.getParent() == null) {
+                //offsetting the physic's position/rotation by the root bone inverse model space position/rotaion
+                modelPosition.set(p).subtractLocal(link.bone.getWorldBindPosition());
+                targetModel.getParent().getWorldTransform().transformInverseVector(modelPosition, modelPosition);
+                modelRotation.set(q).multLocal(tmpRot2.set(link.bone.getWorldBindRotation()).inverseLocal());
 
-                    //offsetting the physic's position/rotation by the root bone inverse model space position/rotaion
-                    modelPosition.set(p).subtractLocal(link.bone.getWorldBindPosition());
-                    targetModel.getParent().getWorldTransform().transformInverseVector(modelPosition, modelPosition);
-                    modelRotation.set(q).multLocal(tmpRot2.set(link.bone.getWorldBindRotation()).inverseLocal());
 
+                //applying transforms to the model
+                targetModel.setLocalTranslation(modelPosition);
 
-                    //applying transforms to the model
-                    targetModel.setLocalTranslation(modelPosition);
+                targetModel.setLocalRotation(modelRotation);
 
-                    targetModel.setLocalRotation(modelRotation);
+                //Applying computed transforms to the bone
+                link.bone.setUserTransformsWorld(position, tmpRot1);
 
-                    //Applying computed transforms to the bone
+            } else {
+                //if boneList is empty, this means that every bone in the ragdoll has a collision shape,
+                //so we just update the bone position
+                if (boneList.isEmpty()) {
                     link.bone.setUserTransformsWorld(position, tmpRot1);
-
                 } else {
-                    //if boneList is empty, this means that every bone in the ragdoll has a collision shape,
-                    //so we just update the bone position
-                    if (boneList.isEmpty()) {
-                        link.bone.setUserTransformsWorld(position, tmpRot1);
-                    } else {
-                        //boneList is not empty, this means some bones of the skeleton might not be associated with a collision shape.
-                        //So we update them recusively
-                        RagdollUtils.setTransform(link.bone, position, tmpRot1, false, boneList);
-                    }
+                    //boneList is not empty, this means some bones of the skeleton might not be associated with a collision shape.
+                    //So we update them recusively
+                    RagdollUtils.setTransform(link.bone, position, tmpRot1, false, boneList);
                 }
             }
-        } else {
-            //the ragdoll does not have the controll, so the keyframed animation updates the physic position of the physic bonces
-            for (PhysicsBoneLink link : boneLinks.values()) {
-
-                Vector3f position = vars.vect1;
-
-                //if blended control this means, keyframed animation is updating the skeleton, 
-                //but to allow smooth transition, we blend this transformation with the saved position of the ragdoll
-                if (blendedControl) {
-                    Vector3f position2 = vars.vect2;
-                    //initializing tmp vars with the start position/rotation of the ragdoll
-                    position.set(link.startBlendingPos);
-                    tmpRot1.set(link.startBlendingRot);
-
-                    //interpolating between ragdoll position/rotation and keyframed position/rotation
-                    tmpRot2.set(tmpRot1).nlerp(link.bone.getModelSpaceRotation(), blendStart / blendTime);
-                    position2.set(position).interpolate(link.bone.getModelSpacePosition(), blendStart / blendTime);
-                    tmpRot1.set(tmpRot2);
-                    position.set(position2);
-
-                    //updating bones transforms
-                    if (boneList.isEmpty()) {
-                        //we ensure we have the control to update the bone
-                        link.bone.setUserControl(true);
-                        link.bone.setUserTransformsWorld(position, tmpRot1);
-                        //we give control back to the key framed animation.
-                        link.bone.setUserControl(false);
-                    } else {
-                        RagdollUtils.setTransform(link.bone, position, tmpRot1, true, boneList);
-                    }
+        }
+        vars.release();
+    }
 
+    protected void kinematicUpdate(float tpf) {
+        //the ragdoll does not have the controll, so the keyframed animation updates the physic position of the physic bonces
+        TempVars vars = TempVars.get();
+        Quaternion tmpRot1 = vars.quat1;
+        Quaternion tmpRot2 = vars.quat2;
+        Vector3f position = vars.vect1;
+        for (PhysicsBoneLink link : boneLinks.values()) {
+            //if blended control this means, keyframed animation is updating the skeleton, 
+            //but to allow smooth transition, we blend this transformation with the saved position of the ragdoll
+            if (blendedControl) {
+                Vector3f position2 = vars.vect2;
+                //initializing tmp vars with the start position/rotation of the ragdoll
+                position.set(link.startBlendingPos);
+                tmpRot1.set(link.startBlendingRot);
+
+                //interpolating between ragdoll position/rotation and keyframed position/rotation
+                tmpRot2.set(tmpRot1).nlerp(link.bone.getModelSpaceRotation(), blendStart / blendTime);
+                position2.set(position).interpolate(link.bone.getModelSpacePosition(), blendStart / blendTime);
+                tmpRot1.set(tmpRot2);
+                position.set(position2);
+
+                //updating bones transforms
+                if (boneList.isEmpty()) {
+                    //we ensure we have the control to update the bone
+                    link.bone.setUserControl(true);
+                    link.bone.setUserTransformsWorld(position, tmpRot1);
+                    //we give control back to the key framed animation.
+                    link.bone.setUserControl(false);
+                } else {
+                    RagdollUtils.setTransform(link.bone, position, tmpRot1, true, boneList);
                 }
-                //setting skeleton transforms to the ragdoll
-                matchPhysicObjectToBone(link, position, tmpRot1);
-                modelPosition.set(targetModel.getLocalTranslation());
 
             }
+            //setting skeleton transforms to the ragdoll
+            matchPhysicObjectToBone(link, position, tmpRot1);
+            modelPosition.set(targetModel.getLocalTranslation());
+        }
 
-            //time control for blending
-            if (blendedControl) {
-                blendStart += tpf;
-                if (blendStart > blendTime) {
-                    blendedControl = false;
-                }
+        //time control for blending
+        if (blendedControl) {
+            blendStart += tpf;
+            if (blendStart > blendTime) {
+                blendedControl = false;
             }
         }
         vars.release();
-
     }
 
     /**