- RagdollControl is now called KinematicRagdollControl
- better user API (setKinematicMode(), setRagdollMode(),...) - You can now enable/disable the control anytime, with no side effects - added more javadoc git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7370 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
93d0ed73e3
commit
427163475c
@ -78,6 +78,7 @@ import java.util.logging.Logger;
|
|||||||
/**<strong>This control is still a WIP, use it at your own risk</strong><br>
|
/**<strong>This control is still a WIP, use it at your own risk</strong><br>
|
||||||
* To use this control you need a model with an AnimControl and a SkeletonControl.<br>
|
* To use this control you need a model with an AnimControl and a SkeletonControl.<br>
|
||||||
* This should be the case if you imported an animated model from Ogre or blender.<br>
|
* This should be the case if you imported an animated model from Ogre or blender.<br>
|
||||||
|
* Note enabling/disabling the control add/removes it from the physic space<br>
|
||||||
* <p>
|
* <p>
|
||||||
* This control creates collision shapes for each bones of the skeleton when you call spatial.addControl(ragdollControl).
|
* This control creates collision shapes for each bones of the skeleton when you call spatial.addControl(ragdollControl).
|
||||||
* <ul>
|
* <ul>
|
||||||
@ -88,26 +89,25 @@ import java.util.logging.Logger;
|
|||||||
* </ul>
|
* </ul>
|
||||||
*</p>
|
*</p>
|
||||||
*<p>
|
*<p>
|
||||||
*There are 2 behavior for this control :
|
*There are 2 modes for this control :
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li><strong>The kinematic behavior :</strong><br>
|
* <li><strong>The kinematic modes :</strong><br>
|
||||||
* this is the default behavior, this means that the collision shapes of the body are able to interact with physics enabled objects.
|
* this is the default behavior, this means that the collision shapes of the body are able to interact with physics enabled objects.
|
||||||
* in this mode physic shapes follow the moovements of the animated skeleton (for example animated by a key framed animation)
|
* in this mode physic shapes follow the moovements of the animated skeleton (for example animated by a key framed animation)
|
||||||
* this mode is enabled just by enabling the control with setEnabled(true);
|
* this mode is enabled by calling setKinematicMode();
|
||||||
* disabling the control removes it from the phyic space
|
|
||||||
* </li>
|
* </li>
|
||||||
* <li><strong>The ragdoll behavior :</strong><br>
|
* <li><strong>The ragdoll modes :</strong><br>
|
||||||
* To enable this behavior, you need to call setRagdollEnabled(true) method.
|
* To enable this behavior, you need to call setRagdollMode() method.
|
||||||
* In this mode the charater is entirely controled by physics, so it will fall under the garvity and move if any force is applied to it.
|
* In this mode the charater is entirely controled by physics, so it will fall under the gravity and move if any force is applied to it.
|
||||||
* </li>
|
* </li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*</p>
|
*</p>
|
||||||
*
|
*
|
||||||
* @author Normen Hansen and Rémy Bouquet (Nehon)
|
* @author Normen Hansen and Rémy Bouquet (Nehon)
|
||||||
*/
|
*/
|
||||||
public class RagdollControl implements PhysicsControl, PhysicsCollisionListener {
|
public class KinematicRagdollControl implements PhysicsControl, PhysicsCollisionListener {
|
||||||
|
|
||||||
protected static final Logger logger = Logger.getLogger(RagdollControl.class.getName());
|
protected static final Logger logger = Logger.getLogger(KinematicRagdollControl.class.getName());
|
||||||
protected Map<String, PhysicsBoneLink> boneLinks = new HashMap<String, PhysicsBoneLink>();
|
protected Map<String, PhysicsBoneLink> boneLinks = new HashMap<String, PhysicsBoneLink>();
|
||||||
protected Skeleton skeleton;
|
protected Skeleton skeleton;
|
||||||
protected PhysicsSpace space;
|
protected PhysicsSpace space;
|
||||||
@ -117,7 +117,7 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener
|
|||||||
protected float weightThreshold = 1.0f;
|
protected float weightThreshold = 1.0f;
|
||||||
protected Spatial targetModel;
|
protected Spatial targetModel;
|
||||||
protected Vector3f initScale;
|
protected Vector3f initScale;
|
||||||
protected boolean control = false;
|
protected Mode mode = Mode.Kinetmatic;
|
||||||
protected boolean blendedControl = false;
|
protected boolean blendedControl = false;
|
||||||
protected float blendTime = 1.0f;
|
protected float blendTime = 1.0f;
|
||||||
protected float blendStart = 0.0f;
|
protected float blendStart = 0.0f;
|
||||||
@ -131,19 +131,28 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener
|
|||||||
protected float totalMass = 0;
|
protected float totalMass = 0;
|
||||||
protected boolean added = false;
|
protected boolean added = false;
|
||||||
|
|
||||||
public RagdollControl() {
|
public enum Mode {
|
||||||
|
|
||||||
|
Kinetmatic,
|
||||||
|
Ragdoll
|
||||||
}
|
}
|
||||||
|
|
||||||
public RagdollControl(float weightThreshold) {
|
/**
|
||||||
|
* contruct a KinematicRagdollControl
|
||||||
|
*/
|
||||||
|
public KinematicRagdollControl() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public KinematicRagdollControl(float weightThreshold) {
|
||||||
this.weightThreshold = weightThreshold;
|
this.weightThreshold = weightThreshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RagdollControl(RagdollPreset preset, float weightThreshold) {
|
public KinematicRagdollControl(RagdollPreset preset, float weightThreshold) {
|
||||||
this.preset = preset;
|
this.preset = preset;
|
||||||
this.weightThreshold = weightThreshold;
|
this.weightThreshold = weightThreshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RagdollControl(RagdollPreset preset) {
|
public KinematicRagdollControl(RagdollPreset preset) {
|
||||||
this.preset = preset;
|
this.preset = preset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +166,7 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener
|
|||||||
Quaternion tmpRot2 = vars.quat2;
|
Quaternion tmpRot2 = vars.quat2;
|
||||||
|
|
||||||
//if the ragdoll has the control of the skeleton, we update each bone with its position in physic world space.
|
//if the ragdoll has the control of the skeleton, we update each bone with its position in physic world space.
|
||||||
if (control) {
|
if (mode == mode.Ragdoll) {
|
||||||
for (PhysicsBoneLink link : boneLinks.values()) {
|
for (PhysicsBoneLink link : boneLinks.values()) {
|
||||||
|
|
||||||
Vector3f position = vars.vect1;
|
Vector3f position = vars.vect1;
|
||||||
@ -205,10 +214,6 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener
|
|||||||
//the ragdoll does not have the controll, so the keyframed animation updates the physic position of the physic bonces
|
//the ragdoll does not have the controll, so the keyframed animation updates the physic position of the physic bonces
|
||||||
for (PhysicsBoneLink link : boneLinks.values()) {
|
for (PhysicsBoneLink link : boneLinks.values()) {
|
||||||
|
|
||||||
if (!link.rigidBody.isKinematic()) {
|
|
||||||
link.rigidBody.setKinematic(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3f position = vars.vect1;
|
Vector3f position = vars.vect1;
|
||||||
|
|
||||||
//if blended control this means, keyframed animation is updating the skeleton,
|
//if blended control this means, keyframed animation is updating the skeleton,
|
||||||
@ -237,18 +242,9 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
//setting skeleton transforms to the ragdoll
|
||||||
|
matchPhysicObjectToBone(link, position, tmpRot1);
|
||||||
|
|
||||||
//computing position from rotation and scale
|
|
||||||
targetModel.getWorldTransform().transformVector(link.bone.getModelSpacePosition(), position);
|
|
||||||
|
|
||||||
//computing rotation
|
|
||||||
tmpRot1.set(link.bone.getModelSpaceRotation()).multLocal(link.bone.getWorldBindInverseRotation());
|
|
||||||
targetModel.getWorldRotation().mult(tmpRot1, tmpRot1);
|
|
||||||
tmpRot1.normalizeLocal();
|
|
||||||
|
|
||||||
//updating physic location/rotation of the physic bone
|
|
||||||
link.rigidBody.setPhysicsLocation(position);
|
|
||||||
link.rigidBody.setPhysicsRotation(tmpRot1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//time control for blending
|
//time control for blending
|
||||||
@ -293,10 +289,40 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
private void matchPhysicObjectToBone(PhysicsBoneLink link, Vector3f position, Quaternion tmpRot1) {
|
||||||
|
//computing position from rotation and scale
|
||||||
|
targetModel.getWorldTransform().transformVector(link.bone.getModelSpacePosition(), position);
|
||||||
|
|
||||||
|
//computing rotation
|
||||||
|
tmpRot1.set(link.bone.getModelSpaceRotation()).multLocal(link.bone.getWorldBindInverseRotation());
|
||||||
|
targetModel.getWorldRotation().mult(tmpRot1, tmpRot1);
|
||||||
|
tmpRot1.normalizeLocal();
|
||||||
|
|
||||||
|
//updating physic location/rotation of the physic bone
|
||||||
|
link.rigidBody.setPhysicsLocation(position);
|
||||||
|
link.rigidBody.setPhysicsRotation(tmpRot1);
|
||||||
|
|
||||||
|
// position.set(link.bone.getModelSpaceScale()).multLocal(targetModel.getWorldScale());
|
||||||
|
// //TODO support scale!
|
||||||
|
// link.rigidBody.getCollisionShape().setScale(position);
|
||||||
|
}
|
||||||
|
|
||||||
public Control cloneForSpatial(Spatial spatial) {
|
public Control cloneForSpatial(Spatial spatial) {
|
||||||
throw new UnsupportedOperationException("Not supported yet.");
|
throw new UnsupportedOperationException("Not supported yet.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void reInit() {
|
||||||
|
setSpatial(targetModel);
|
||||||
|
addToPhysicsSpace();
|
||||||
|
}
|
||||||
|
|
||||||
public void setSpatial(Spatial model) {
|
public void setSpatial(Spatial model) {
|
||||||
if (model == null) {
|
if (model == null) {
|
||||||
removeFromPhysicsSpace();
|
removeFromPhysicsSpace();
|
||||||
@ -313,7 +339,7 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener
|
|||||||
|
|
||||||
model.removeFromParent();
|
model.removeFromParent();
|
||||||
model.setLocalTranslation(Vector3f.ZERO);
|
model.setLocalTranslation(Vector3f.ZERO);
|
||||||
model.setLocalRotation(Quaternion.ZERO);
|
model.setLocalRotation(Quaternion.IDENTITY);
|
||||||
model.setLocalScale(1);
|
model.setLocalScale(1);
|
||||||
//HACK ALERT change this
|
//HACK ALERT change this
|
||||||
//I remove the skeletonControl and readd it to the spatial to make sure it's after the ragdollControl in the stack
|
//I remove the skeletonControl and readd it to the spatial to make sure it's after the ragdollControl in the stack
|
||||||
@ -355,11 +381,10 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener
|
|||||||
if (childBone.getParent() == null) {
|
if (childBone.getParent() == null) {
|
||||||
logger.log(Level.INFO, "Found root bone in skeleton {0}", skeleton);
|
logger.log(Level.INFO, "Found root bone in skeleton {0}", skeleton);
|
||||||
baseRigidBody = new PhysicsRigidBody(new BoxCollisionShape(Vector3f.UNIT_XYZ.mult(0.1f)), 1);
|
baseRigidBody = new PhysicsRigidBody(new BoxCollisionShape(Vector3f.UNIT_XYZ.mult(0.1f)), 1);
|
||||||
|
baseRigidBody.setKinematic(mode == Mode.Kinetmatic);
|
||||||
boneRecursion(model, childBone, baseRigidBody, 1);
|
boneRecursion(model, childBone, baseRigidBody, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void boneRecursion(Spatial model, Bone bone, PhysicsRigidBody parent, int reccount) {
|
private void boneRecursion(Spatial model, Bone bone, PhysicsRigidBody parent, int reccount) {
|
||||||
@ -370,6 +395,7 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener
|
|||||||
link.bone = bone;
|
link.bone = bone;
|
||||||
//creating the collision shape from the bone's associated vertices
|
//creating the collision shape from the bone's associated vertices
|
||||||
PhysicsRigidBody shapeNode = new PhysicsRigidBody(makeShape(link, model), rootMass / (float) reccount);
|
PhysicsRigidBody shapeNode = new PhysicsRigidBody(makeShape(link, model), rootMass / (float) reccount);
|
||||||
|
shapeNode.setKinematic(mode == Mode.Kinetmatic);
|
||||||
totalMass += rootMass / (float) reccount;
|
totalMass += rootMass / (float) reccount;
|
||||||
|
|
||||||
link.rigidBody = shapeNode;
|
link.rigidBody = shapeNode;
|
||||||
@ -458,7 +484,9 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void addToPhysicsSpace() {
|
private void addToPhysicsSpace() {
|
||||||
|
if (space == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (baseRigidBody != null) {
|
if (baseRigidBody != null) {
|
||||||
space.add(baseRigidBody);
|
space.add(baseRigidBody);
|
||||||
added = true;
|
added = true;
|
||||||
@ -467,17 +495,13 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener
|
|||||||
PhysicsBoneLink physicsBoneLink = it.next();
|
PhysicsBoneLink physicsBoneLink = it.next();
|
||||||
if (physicsBoneLink.rigidBody != null) {
|
if (physicsBoneLink.rigidBody != null) {
|
||||||
space.add(physicsBoneLink.rigidBody);
|
space.add(physicsBoneLink.rigidBody);
|
||||||
added = true;
|
if (physicsBoneLink.joint != null) {
|
||||||
}
|
space.add(physicsBoneLink.joint);
|
||||||
}
|
|
||||||
for (Iterator<PhysicsBoneLink> it = boneLinks.values().iterator(); it.hasNext();) {
|
|
||||||
PhysicsBoneLink physicsBoneLink = it.next();
|
|
||||||
if (physicsBoneLink.joint != null) {
|
|
||||||
space.add(physicsBoneLink.joint);
|
|
||||||
added = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
|
added = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -520,6 +544,7 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener
|
|||||||
p[i] = points.get(i);
|
p[i] = points.get(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return new HullCollisionShape(p);
|
return new HullCollisionShape(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -585,7 +610,9 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void removeFromPhysicsSpace() {
|
protected void removeFromPhysicsSpace() {
|
||||||
|
if (space == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (baseRigidBody != null) {
|
if (baseRigidBody != null) {
|
||||||
space.remove(baseRigidBody);
|
space.remove(baseRigidBody);
|
||||||
}
|
}
|
||||||
@ -593,12 +620,9 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener
|
|||||||
PhysicsBoneLink physicsBoneLink = it.next();
|
PhysicsBoneLink physicsBoneLink = it.next();
|
||||||
if (physicsBoneLink.joint != null) {
|
if (physicsBoneLink.joint != null) {
|
||||||
space.remove(physicsBoneLink.joint);
|
space.remove(physicsBoneLink.joint);
|
||||||
}
|
if (physicsBoneLink.rigidBody != null) {
|
||||||
}
|
space.remove(physicsBoneLink.rigidBody);
|
||||||
for (Iterator<PhysicsBoneLink> it = boneLinks.values().iterator(); it.hasNext();) {
|
}
|
||||||
PhysicsBoneLink physicsBoneLink = it.next();
|
|
||||||
if (physicsBoneLink.rigidBody != null) {
|
|
||||||
space.remove(physicsBoneLink.rigidBody);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
added = false;
|
added = false;
|
||||||
@ -723,7 +747,7 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener
|
|||||||
PhysicsCollisionObject objA = event.getObjectA();
|
PhysicsCollisionObject objA = event.getObjectA();
|
||||||
PhysicsCollisionObject objB = event.getObjectB();
|
PhysicsCollisionObject objB = event.getObjectB();
|
||||||
|
|
||||||
//excluding collisions that do not involve the ragdoll
|
//excluding collisions that involve 2 parts of the ragdoll
|
||||||
if (event.getNodeA() == null && event.getNodeB() == null) {
|
if (event.getNodeA() == null && event.getNodeB() == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -773,40 +797,71 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener
|
|||||||
* but will be able to physically interact with its physic environnement
|
* but will be able to physically interact with its physic environnement
|
||||||
* @param ragdollEnabled
|
* @param ragdollEnabled
|
||||||
*/
|
*/
|
||||||
public void setRagdollEnabled(boolean ragdollEnabled) {
|
protected void setMode(Mode mode) {
|
||||||
|
this.mode = mode;
|
||||||
AnimControl animControl = targetModel.getControl(AnimControl.class);
|
AnimControl animControl = targetModel.getControl(AnimControl.class);
|
||||||
animControl.setEnabled(!ragdollEnabled);
|
animControl.setEnabled(mode == Mode.Kinetmatic);
|
||||||
|
|
||||||
this.control = ragdollEnabled;
|
baseRigidBody.setKinematic(mode == Mode.Kinetmatic);
|
||||||
|
TempVars vars = TempVars.get();
|
||||||
|
assert vars.lock();
|
||||||
for (PhysicsBoneLink link : boneLinks.values()) {
|
for (PhysicsBoneLink link : boneLinks.values()) {
|
||||||
link.rigidBody.setKinematic(!ragdollEnabled);
|
link.rigidBody.setKinematic(mode == Mode.Kinetmatic);
|
||||||
|
if (mode == Mode.Ragdoll) {
|
||||||
|
Quaternion tmpRot1 = vars.quat1;
|
||||||
|
Vector3f position = vars.vect1;
|
||||||
|
//making sure that the ragdoll is at the correct place.
|
||||||
|
matchPhysicObjectToBone(link, position, tmpRot1);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
assert vars.unlock();
|
||||||
|
|
||||||
for (Bone bone : skeleton.getRoots()) {
|
for (Bone bone : skeleton.getRoots()) {
|
||||||
setUserControl(bone, ragdollEnabled);
|
setUserControl(bone, mode == Mode.Ragdoll);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Blend motion between the ragdoll actual physic state to the given animation, in the given blendTime
|
* Set the control into Kinematic mode
|
||||||
* Note that this disable the ragdoll behaviour of the control
|
* In theis mode, the collision shapes follow the movements of the skeleton,
|
||||||
* @param anim the animation name to blend to
|
* and can interact with physical environement
|
||||||
* @param channel the channel to use for this animation
|
*/
|
||||||
|
public void setKinematicMode() {
|
||||||
|
if (mode != Mode.Kinetmatic) {
|
||||||
|
setMode(Mode.Kinetmatic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the control into Ragdoll mode
|
||||||
|
* The skeleton is entirely controlled by physics.
|
||||||
|
*/
|
||||||
|
public void setRagdollMode() {
|
||||||
|
if (mode != Mode.Ragdoll) {
|
||||||
|
setMode(Mode.Ragdoll);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
* @param blendTime the blending time between ragdoll to anim.
|
||||||
*/
|
*/
|
||||||
public void blendRagdollToAnim(String anim, AnimChannel channel, float blendTime) {
|
public void blendToKinematicMode(float blendTime) {
|
||||||
|
if (mode == Mode.Kinetmatic) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
blendedControl = true;
|
blendedControl = true;
|
||||||
this.blendTime = blendTime;
|
this.blendTime = blendTime;
|
||||||
control = false;
|
mode = Mode.Kinetmatic;
|
||||||
AnimControl animControl = targetModel.getControl(AnimControl.class);
|
AnimControl animControl = targetModel.getControl(AnimControl.class);
|
||||||
animControl.setEnabled(true);
|
animControl.setEnabled(true);
|
||||||
channel.setAnim(anim);
|
|
||||||
channel.setLoopMode(LoopMode.DontLoop);
|
|
||||||
|
|
||||||
TempVars vars = TempVars.get();
|
TempVars vars = TempVars.get();
|
||||||
assert vars.lock();
|
assert vars.lock();
|
||||||
//this.control = control;
|
|
||||||
for (PhysicsBoneLink link : boneLinks.values()) {
|
for (PhysicsBoneLink link : boneLinks.values()) {
|
||||||
|
|
||||||
Vector3f p = link.rigidBody.getMotionState().getWorldLocation();
|
Vector3f p = link.rigidBody.getMotionState().getWorldLocation();
|
||||||
@ -842,12 +897,11 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns true if the ragdoll behaviour is enabled
|
* retruns the mode of this control
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public boolean isRagdollEnabled() {
|
public Mode getMode() {
|
||||||
return control;
|
return mode;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
@ -39,12 +39,13 @@ import com.jme3.animation.LoopMode;
|
|||||||
import com.jme3.bullet.BulletAppState;
|
import com.jme3.bullet.BulletAppState;
|
||||||
import com.jme3.app.SimpleApplication;
|
import com.jme3.app.SimpleApplication;
|
||||||
import com.jme3.asset.TextureKey;
|
import com.jme3.asset.TextureKey;
|
||||||
|
import com.jme3.bounding.BoundingBox;
|
||||||
import com.jme3.bullet.PhysicsSpace;
|
import com.jme3.bullet.PhysicsSpace;
|
||||||
import com.jme3.bullet.collision.PhysicsCollisionEvent;
|
import com.jme3.bullet.collision.PhysicsCollisionEvent;
|
||||||
import com.jme3.bullet.collision.PhysicsCollisionObject;
|
import com.jme3.bullet.collision.PhysicsCollisionObject;
|
||||||
import com.jme3.bullet.collision.RagdollCollisionListener;
|
import com.jme3.bullet.collision.RagdollCollisionListener;
|
||||||
import com.jme3.bullet.collision.shapes.SphereCollisionShape;
|
import com.jme3.bullet.collision.shapes.SphereCollisionShape;
|
||||||
import com.jme3.bullet.control.RagdollControl;
|
import com.jme3.bullet.control.KinematicRagdollControl;
|
||||||
import com.jme3.bullet.control.RigidBodyControl;
|
import com.jme3.bullet.control.RigidBodyControl;
|
||||||
import com.jme3.font.BitmapText;
|
import com.jme3.font.BitmapText;
|
||||||
import com.jme3.input.KeyInput;
|
import com.jme3.input.KeyInput;
|
||||||
@ -74,7 +75,7 @@ public class TestBoneRagdoll extends SimpleApplication implements RagdollCollisi
|
|||||||
private BulletAppState bulletAppState;
|
private BulletAppState bulletAppState;
|
||||||
Material matBullet;
|
Material matBullet;
|
||||||
Node model;
|
Node model;
|
||||||
RagdollControl ragdoll;
|
KinematicRagdollControl ragdoll;
|
||||||
float bulletSize = 1f;
|
float bulletSize = 1f;
|
||||||
Material mat;
|
Material mat;
|
||||||
Material mat3;
|
Material mat3;
|
||||||
@ -106,7 +107,7 @@ public class TestBoneRagdoll extends SimpleApplication implements RagdollCollisi
|
|||||||
setupLight();
|
setupLight();
|
||||||
|
|
||||||
model = (Node) assetManager.loadModel("Models/Sinbad/Sinbad.mesh.xml");
|
model = (Node) assetManager.loadModel("Models/Sinbad/Sinbad.mesh.xml");
|
||||||
// model.setLocalTranslation(5, 0, 5);
|
|
||||||
// model.setLocalRotation(new Quaternion().fromAngleAxis(FastMath.HALF_PI, Vector3f.UNIT_X));
|
// model.setLocalRotation(new Quaternion().fromAngleAxis(FastMath.HALF_PI, Vector3f.UNIT_X));
|
||||||
|
|
||||||
//debug view
|
//debug view
|
||||||
@ -119,7 +120,7 @@ public class TestBoneRagdoll extends SimpleApplication implements RagdollCollisi
|
|||||||
skeletonDebug.setLocalTranslation(model.getLocalTranslation());
|
skeletonDebug.setLocalTranslation(model.getLocalTranslation());
|
||||||
|
|
||||||
//Note: PhysicsRagdollControl is still TODO, constructor will change
|
//Note: PhysicsRagdollControl is still TODO, constructor will change
|
||||||
ragdoll = new RagdollControl(0.5f);
|
ragdoll = new KinematicRagdollControl(0.5f);
|
||||||
setupSinbad(ragdoll);
|
setupSinbad(ragdoll);
|
||||||
ragdoll.addCollisionListener(this);
|
ragdoll.addCollisionListener(this);
|
||||||
model.addControl(ragdoll);
|
model.addControl(ragdoll);
|
||||||
@ -157,12 +158,16 @@ public class TestBoneRagdoll extends SimpleApplication implements RagdollCollisi
|
|||||||
float[] angles = new float[3];
|
float[] angles = new float[3];
|
||||||
model.getLocalRotation().toAngles(angles);
|
model.getLocalRotation().toAngles(angles);
|
||||||
q.fromAngleAxis(angles[1], Vector3f.UNIT_Y);
|
q.fromAngleAxis(angles[1], Vector3f.UNIT_Y);
|
||||||
//q.lookAt(model.getLocalRotation().toRotationMatrix().getColumn(2), Vector3f.UNIT_Y);
|
|
||||||
model.setLocalRotation(q);
|
model.setLocalRotation(q);
|
||||||
if (angles[0] < 0) {
|
if (angles[0] < 0) {
|
||||||
ragdoll.blendRagdollToAnim("StandUpBack", animChannel, 1);
|
animChannel.setAnim("StandUpBack");
|
||||||
|
// ragdoll.setKinematicMode();
|
||||||
|
ragdoll.blendToKinematicMode(0.5f);
|
||||||
} else {
|
} else {
|
||||||
ragdoll.blendRagdollToAnim("StandUpFront", animChannel, 1);
|
animChannel.setAnim("StandUpFront");
|
||||||
|
ragdoll.blendToKinematicMode(0.5f);
|
||||||
|
// ragdoll.setKinematicMode();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -178,8 +183,10 @@ public class TestBoneRagdoll extends SimpleApplication implements RagdollCollisi
|
|||||||
// bulletSize = 0;
|
// bulletSize = 0;
|
||||||
}
|
}
|
||||||
if (name.equals("stop") && isPressed) {
|
if (name.equals("stop") && isPressed) {
|
||||||
bulletAppState.setEnabled(!bulletAppState.isEnabled());
|
// bulletAppState.setEnabled(!bulletAppState.isEnabled());
|
||||||
|
|
||||||
|
ragdoll.setEnabled(!ragdoll.isEnabled());
|
||||||
|
ragdoll.setRagdollMode();
|
||||||
}
|
}
|
||||||
if (name.equals("shoot") && !isPressed) {
|
if (name.equals("shoot") && !isPressed) {
|
||||||
Geometry bulletg = new Geometry("bullet", bullet);
|
Geometry bulletg = new Geometry("bullet", bullet);
|
||||||
@ -265,13 +272,11 @@ public class TestBoneRagdoll extends SimpleApplication implements RagdollCollisi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ragdoll.isRagdollEnabled()) {
|
ragdoll.setRagdollMode();
|
||||||
ragdoll.setRagdollEnabled(true);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupSinbad(RagdollControl ragdoll) {
|
private void setupSinbad(KinematicRagdollControl ragdoll) {
|
||||||
ragdoll.addBoneName("Ulna.L");
|
ragdoll.addBoneName("Ulna.L");
|
||||||
ragdoll.addBoneName("Ulna.R");
|
ragdoll.addBoneName("Ulna.R");
|
||||||
ragdoll.addBoneName("Chest");
|
ragdoll.addBoneName("Chest");
|
||||||
@ -304,6 +309,7 @@ public class TestBoneRagdoll extends SimpleApplication implements RagdollCollisi
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void simpleUpdate(float tpf) {
|
public void simpleUpdate(float tpf) {
|
||||||
|
System.out.println(((BoundingBox) model.getWorldBound()).getYExtent());
|
||||||
// elTime += tpf;
|
// elTime += tpf;
|
||||||
// if (elTime > 3) {
|
// if (elTime > 3) {
|
||||||
// elTime = 0;
|
// elTime = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user