- move KinematicRagdollControl to use AbstractPhysicsControl

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10370 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
nor..67 12 years ago
parent 2addc81210
commit 887c13142f
  1. 287
      engine/src/bullet-common/com/jme3/bullet/control/KinematicRagdollControl.java

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

Loading…
Cancel
Save