OSDN Git Service

- move KinematicRagdollControl to use AbstractPhysicsControl
authornormen667 <normen667@75d07b2b-3a1a-0410-a2c5-0572b91ccdca>
Sat, 9 Feb 2013 03:14:13 +0000 (03:14 +0000)
committernormen667 <normen667@75d07b2b-3a1a-0410-a2c5-0572b91ccdca>
Sat, 9 Feb 2013 03:14:13 +0000 (03:14 +0000)
git-svn-id: http://jmonkeyengine.googlecode.com/svn/trunk@10370 75d07b2b-3a1a-0410-a2c5-0572b91ccdca

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

index e5720bd..63ddf10 100644 (file)
@@ -47,8 +47,10 @@ import com.jme3.bullet.control.ragdoll.RagdollPreset;
 import com.jme3.bullet.control.ragdoll.RagdollUtils;
 import com.jme3.bullet.joints.SixDofJoint;
 import com.jme3.bullet.objects.PhysicsRigidBody;
+import com.jme3.export.InputCapsule;
 import com.jme3.export.JmeExporter;
 import com.jme3.export.JmeImporter;
+import com.jme3.export.OutputCapsule;
 import com.jme3.math.Quaternion;
 import com.jme3.math.Vector3f;
 import com.jme3.renderer.RenderManager;
@@ -92,31 +94,28 @@ import java.util.logging.Logger;
  *
  * @author Normen Hansen and Rémy Bouquet (Nehon)
  */
-public class KinematicRagdollControl implements PhysicsControl, PhysicsCollisionListener {
+public class KinematicRagdollControl extends AbstractPhysicsControl implements PhysicsCollisionListener {
 
     protected static final Logger logger = Logger.getLogger(KinematicRagdollControl.class.getName());
-    protected Map<String, PhysicsBoneLink> boneLinks = new HashMap<String, PhysicsBoneLink>();
-    protected Skeleton skeleton;
-    protected PhysicsSpace space;
-    protected boolean enabled = true;
-    protected boolean debug = false;
+    protected List<RagdollCollisionListener> listeners;
+    protected final Set<String> boneList = new TreeSet<String>();
+    protected final Map<String, PhysicsBoneLink> boneLinks = new HashMap<String, PhysicsBoneLink>();
+    protected final Vector3f modelPosition = new Vector3f();
+    protected final Quaternion modelRotation = new Quaternion();
     protected PhysicsRigidBody baseRigidBody;
-    protected float weightThreshold = -1.0f;
     protected Spatial targetModel;
+    protected Skeleton skeleton;
+    protected RagdollPreset preset = new HumanoidRagdollPreset();
     protected Vector3f initScale;
     protected Mode mode = Mode.Kinematic;
+    protected boolean debug = false;
     protected boolean blendedControl = false;
-    protected float blendTime = 1.0f;
+    protected float weightThreshold = -1.0f;
     protected float blendStart = 0.0f;
-    protected List<RagdollCollisionListener> listeners;
+    protected float blendTime = 1.0f;
     protected float eventDispatchImpulseThreshold = 10;
-    protected RagdollPreset preset = new HumanoidRagdollPreset();
-    protected Set<String> boneList = new TreeSet<String>();
-    protected Vector3f modelPosition = new Vector3f();
-    protected Quaternion modelRotation = new Quaternion();
     protected float rootMass = 15;
     protected float totalMass = 0;
-    protected boolean added = false;
 
     public static enum Mode {
 
@@ -166,7 +165,7 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
             return;
         }
         TempVars vars = TempVars.get();
-        
+
         Quaternion tmpRot1 = vars.quat1;
         Quaternion tmpRot2 = vars.quat2;
 
@@ -270,13 +269,15 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
     }
 
     /**
-     * Set the transforms of a rigidBody to match the transforms of a bone.
-     * this is used to make the ragdoll follow the skeleton motion while in Kinematic mode
+     * Set the transforms of a rigidBody to match the transforms of a bone. this
+     * is used to make the ragdoll follow the skeleton motion while in Kinematic
+     * mode
+     *
      * @param link the link containing the bone and the rigidBody
      * @param position just a temp vector for position
-     * @param tmpRot1  just a temp quaternion for rotation
+     * @param tmpRot1 just a temp quaternion for rotation
      */
-    private void matchPhysicObjectToBone(PhysicsBoneLink link, Vector3f position, Quaternion tmpRot1) {
+    protected void matchPhysicObjectToBone(PhysicsBoneLink link, Vector3f position, Quaternion tmpRot1) {
         //computing position from rotation and scale
         targetModel.getWorldTransform().transformVector(link.bone.getModelSpacePosition(), position);
 
@@ -291,23 +292,29 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
 
     }
 
-    public Control cloneForSpatial(Spatial spatial) {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
     /**
-     * rebuild the ragdoll
-     * this is useful if you applied scale on the ragdoll after it's been initialized
+     * rebuild the ragdoll this is useful if you applied scale on the ragdoll
+     * after it's been initialized, same as reattaching.
      */
     public void reBuild() {
-        setSpatial(targetModel);
-        addToPhysicsSpace();
+        if (added) {
+            removePhysics(space);
+            setSpatial(targetModel);
+            addPhysics(space);
+        } else {
+            setSpatial(targetModel);
+        }
     }
 
+    @Override
     public void setSpatial(Spatial model) {
+        super.setSpatial(model);
+        if (added) {
+            removePhysics(space);
+        }
+        boneLinks.clear();
+        baseRigidBody = null;
         if (model == null) {
-            removeFromPhysicsSpace();
-            clearData();
             return;
         }
         targetModel = model;
@@ -328,10 +335,7 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
         SkeletonControl sc = model.getControl(SkeletonControl.class);
         model.removeControl(sc);
         model.addControl(sc);
-        //---- 
 
-        removeFromPhysicsSpace();
-        clearData();
         // put into bind pose and compute bone transforms in model space
         // maybe dont reset to ragdoll out of animations?
         scanSpatial(model);
@@ -345,19 +349,23 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
         model.setLocalRotation(initRotation);
         model.setLocalScale(initScale);
 
+        if (added) {
+            addPhysics(space);
+        }
         logger.log(Level.FINE, "Created physics ragdoll for skeleton {0}", skeleton);
     }
 
     /**
-     * Add a bone name to this control
-     * Using this method you can specify which bones of the skeleton will be used to build the collision shapes.
-     * @param name 
+     * Add a bone name to this control Using this method you can specify which
+     * bones of the skeleton will be used to build the collision shapes.
+     *
+     * @param name
      */
     public void addBoneName(String name) {
         boneList.add(name);
     }
 
-    private void scanSpatial(Spatial model) {
+    protected void scanSpatial(Spatial model) {
         AnimControl animControl = model.getControl(AnimControl.class);
         Map<Integer, List<Float>> pointsMap = null;
         if (weightThreshold == -1.0f) {
@@ -377,7 +385,7 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
         }
     }
 
-    private void boneRecursion(Spatial model, Bone bone, PhysicsRigidBody parent, int reccount, Map<Integer, List<Float>> pointsMap) {
+    protected void boneRecursion(Spatial model, Bone bone, PhysicsRigidBody parent, int reccount, Map<Integer, List<Float>> pointsMap) {
         PhysicsRigidBody parentShape = parent;
         if (boneList.isEmpty() || boneList.contains(bone.getName())) {
 
@@ -429,6 +437,7 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
     /**
      * Set the joint limits for the joint between the given bone and its parent.
      * This method can't work before attaching the control to a spatial
+     *
      * @param boneName the name of the bone
      * @param maxX the maximum rotation on the x axis (in radians)
      * @param minX the minimum rotation on the x axis (in radians)
@@ -447,8 +456,9 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
     }
 
     /**
-     * Return the joint between the given bone and its parent.
-     * This return null if it's called before attaching the control to a spatial
+     * Return the joint between the given bone and its parent. This return null
+     * if it's called before attaching the control to a spatial
+     *
      * @param boneName the name of the bone
      * @return the joint between the given bone and its parent
      */
@@ -462,18 +472,24 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
         }
     }
 
-    private void clearData() {
-        boneLinks.clear();
-        baseRigidBody = null;
+    @Override
+    protected void setPhysicsLocation(Vector3f vec) {
+        if (baseRigidBody != null) {
+            baseRigidBody.setPhysicsLocation(vec);
+        }
     }
 
-    private void addToPhysicsSpace() {
-        if (space == null) {
-            return;
+    @Override
+    protected void setPhysicsRotation(Quaternion quat) {
+        if (baseRigidBody != null) {
+            baseRigidBody.setPhysicsRotation(quat);
         }
+    }
+
+    @Override
+    protected void addPhysics(PhysicsSpace space) {
         if (baseRigidBody != null) {
             space.add(baseRigidBody);
-            added = true;
         }
         for (Iterator<PhysicsBoneLink> it = boneLinks.values().iterator(); it.hasNext();) {
             PhysicsBoneLink physicsBoneLink = it.next();
@@ -483,15 +499,13 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
                     space.add(physicsBoneLink.joint);
 
                 }
-                added = true;
             }
         }
+        space.addCollisionListener(this);
     }
 
-    protected void removeFromPhysicsSpace() {
-        if (space == null) {
-            return;
-        }
+    @Override
+    protected void removePhysics(PhysicsSpace space) {
         if (baseRigidBody != null) {
             space.remove(baseRigidBody);
         }
@@ -504,92 +518,13 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
                 }
             }
         }
-        added = false;
-    }
-
-    /**
-     * enable or disable the control
-     * note that if enabled is true and that the physic space has been set on the ragdoll, the ragdoll is added to the physic space     
-     * if enabled is false the ragdoll is removed from physic space.
-     * @param enabled 
-     */
-    public void setEnabled(boolean enabled) {
-        if (this.enabled == enabled) {
-            return;
-        }
-        this.enabled = enabled;
-        if (!enabled && space != null) {
-            removeFromPhysicsSpace();
-        } else if (enabled && space != null) {
-            addToPhysicsSpace();
-        }
+        space.removeCollisionListener(this);
     }
 
     /**
-     * returns true if the control is enabled
-     * @return 
-     */
-    public boolean isEnabled() {
-        return enabled;
-    }
-
-    /**
-     * For internal use only
-     * specific render for the ragdoll(if debugging)      
-     * @param rm
-     * @param vp 
-     */
-    public void render(RenderManager rm, ViewPort vp) {
-    }
-
-    /**
-     * set the physic space to this ragdoll
-     * @param space 
-     */
-    public void setPhysicsSpace(PhysicsSpace space) {
-        if (space == null) {
-            removeFromPhysicsSpace();
-            this.space = space;
-        } else {
-            if (this.space == space) {
-                return;
-            }
-            this.space = space;
-            addToPhysicsSpace();
-            this.space.addCollisionListener(this);
-        }
-    }
-
-    /**
-     * returns the physic space
-     * @return 
-     */
-    public PhysicsSpace getPhysicsSpace() {
-        return space;
-    }
-
-    /**
-     * serialize this control
-     * @param ex
-     * @throws IOException 
-     */
-    public void write(JmeExporter ex) throws IOException {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
-    /**
-     * de-serialize this control
-     * @param im
-     * @throws IOException 
-     */
-    public void read(JmeImporter im) throws IOException {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
-    /**
-     * For internal use only
-     * callback for collisionevent
-     * @param event 
+     * For internal use only callback for collisionevent
+     *
+     * @param event
      */
     public void collision(PhysicsCollisionEvent event) {
         PhysicsCollisionObject objA = event.getObjectA();
@@ -639,11 +574,12 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
     }
 
     /**
-     * Enable or disable the ragdoll behaviour.
-     * if ragdollEnabled is true, the character motion will only be powerd by physics
-     * else, the characted will be animated by the keyframe animation, 
-     * but will be able to physically interact with its physic environnement
-     * @param ragdollEnabled 
+     * Enable or disable the ragdoll behaviour. if ragdollEnabled is true, the
+     * character motion will only be powerd by physics else, the characted will
+     * be animated by the keyframe animation, but will be able to physically
+     * interact with its physic environnement
+     *
+     * @param ragdollEnabled
      */
     protected void setMode(Mode mode) {
         this.mode = mode;
@@ -652,7 +588,7 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
 
         baseRigidBody.setKinematic(mode == Mode.Kinematic);
         TempVars vars = TempVars.get();
-        
+
         for (PhysicsBoneLink link : boneLinks.values()) {
             link.rigidBody.setKinematic(mode == Mode.Kinematic);
             if (mode == Mode.Ragdoll) {
@@ -671,8 +607,9 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
     }
 
     /**
-     * Smoothly blend from Ragdoll mode to Kinematic mode
-     * This is useful to blend ragdoll actual position to a keyframe animation for example
+     * Smoothly blend from Ragdoll mode to Kinematic mode This is useful to
+     * blend ragdoll actual position to a keyframe animation for example
+     *
      * @param blendTime the blending time between ragdoll to anim.
      */
     public void blendToKinematicMode(float blendTime) {
@@ -686,7 +623,7 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
         animControl.setEnabled(true);
 
 
-        TempVars vars = TempVars.get();        
+        TempVars vars = TempVars.get();
         for (PhysicsBoneLink link : boneLinks.values()) {
 
             Vector3f p = link.rigidBody.getMotionState().getWorldLocation();
@@ -715,9 +652,9 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
     }
 
     /**
-     * Set the control into Kinematic mode
-     * In theis mode, the collision shapes follow the movements of the skeleton,
-     * and can interact with physical environement
+     * Set the control into Kinematic mode In theis mode, the collision shapes
+     * follow the movements of the skeleton, and can interact with physical
+     * environement
      */
     public void setKinematicMode() {
         if (mode != Mode.Kinematic) {
@@ -726,8 +663,8 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
     }
 
     /**
-     * Sets the control into Ragdoll mode
-     * The skeleton is entirely controlled by physics.
+     * Sets the control into Ragdoll mode The skeleton is entirely controlled by
+     * physics.
      */
     public void setRagdollMode() {
         if (mode != Mode.Ragdoll) {
@@ -737,15 +674,17 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
 
     /**
      * retruns the mode of this control
-     * @return 
+     *
+     * @return
      */
     public Mode getMode() {
         return mode;
     }
 
     /**
-     * add a 
-     * @param listener 
+     * add a
+     *
+     * @param listener
      */
     public void addCollisionListener(RagdollCollisionListener listener) {
         if (listeners == null) {
@@ -780,8 +719,9 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
 
     /**
      * Set the CcdMotionThreshold of all the bone's rigidBodies of the ragdoll
-     * @see PhysicsRigidBody#setCcdMotionThreshold(float) 
-     * @param value 
+     *
+     * @see PhysicsRigidBody#setCcdMotionThreshold(float)
+     * @param value
      */
     public void setCcdMotionThreshold(float value) {
         for (PhysicsBoneLink link : boneLinks.values()) {
@@ -791,8 +731,9 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
 
     /**
      * Set the CcdSweptSphereRadius of all the bone's rigidBodies of the ragdoll
-     * @see PhysicsRigidBody#setCcdSweptSphereRadius(float) 
-     * @param value 
+     *
+     * @see PhysicsRigidBody#setCcdSweptSphereRadius(float)
+     * @param value
      */
     public void setCcdSweptSphereRadius(float value) {
         for (PhysicsBoneLink link : boneLinks.values()) {
@@ -802,6 +743,7 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
 
     /**
      * return the rigidBody associated to the given bone
+     *
      * @param boneName the name of the bone
      * @return the associated rigidBody.
      */
@@ -812,4 +754,39 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision
         }
         return null;
     }
+
+    /**
+     * For internal use only specific render for the ragdoll(if debugging)
+     *
+     * @param rm
+     * @param vp
+     */
+    public void render(RenderManager rm, ViewPort vp) {
+    }
+
+    public Control cloneForSpatial(Spatial spatial) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    /**
+     * serialize this control
+     *
+     * @param ex
+     * @throws IOException
+     */
+    public void write(JmeExporter ex) throws IOException {
+        super.write(ex);
+        OutputCapsule oc = ex.getCapsule(this);
+    }
+
+    /**
+     * de-serialize this control
+     *
+     * @param im
+     * @throws IOException
+     */
+    public void read(JmeImporter im) throws IOException {
+        super.read(im);
+        InputCapsule ic = im.getCapsule(this);
+    }
 }