diff --git a/engine/src/bullet/com/jme3/bullet/control/KinematicRagdollControl.java b/engine/src/bullet/com/jme3/bullet/control/KinematicRagdollControl.java index e9783bafe..7937780e4 100644 --- a/engine/src/bullet/com/jme3/bullet/control/KinematicRagdollControl.java +++ b/engine/src/bullet/com/jme3/bullet/control/KinematicRagdollControl.java @@ -51,7 +51,6 @@ import com.jme3.bullet.objects.PhysicsRigidBody; import com.jme3.export.JmeExporter; import com.jme3.export.JmeImporter; import com.jme3.math.Quaternion; -import com.jme3.math.Transform; import com.jme3.math.Vector3f; import com.jme3.renderer.RenderManager; import com.jme3.renderer.ViewPort; @@ -171,7 +170,7 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision 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 (mode == mode.Ragdoll) { + if (mode == mode.Ragdoll && targetModel.getLocalTranslation().equals(modelPosition)) { for (PhysicsBoneLink link : boneLinks.values()) { Vector3f position = vars.vect1; @@ -192,12 +191,16 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision //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.getInitialPos()); + targetModel.getParent().getWorldTransform().transformInverseVector(modelPosition, modelPosition); modelRotation.set(q).multLocal(tmpRot2.set(link.bone.getInitialRot()).inverseLocal()); + //applying transforms to the model targetModel.setLocalTranslation(modelPosition); + targetModel.setLocalRotation(modelRotation); //Applying computed transforms to the bone @@ -230,7 +233,7 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision tmpRot1.set(link.startBlendingRot); //interpolating between ragdoll position/rotation and keyframed position/rotation - tmpRot2.set(tmpRot1).slerp(link.bone.getModelSpaceRotation(), blendStart / blendTime); + tmpRot2.set(tmpRot1).nlerp(link.bone.getModelSpaceRotation(), blendStart / blendTime); position2.set(position).interpolate(link.bone.getModelSpacePosition(), blendStart / blendTime); tmpRot1.set(tmpRot2); position.set(position2); @@ -249,6 +252,7 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision } //setting skeleton transforms to the ragdoll matchPhysicObjectToBone(link, position, tmpRot1); + modelPosition.set(targetModel.getLocalTranslation()); } @@ -390,6 +394,7 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision } PhysicsRigidBody shapeNode = new PhysicsRigidBody(shape, rootMass / (float) reccount); + shapeNode.setKinematic(mode == Mode.Kinetmatic); totalMass += rootMass / (float) reccount; @@ -804,4 +809,67 @@ public class KinematicRagdollControl implements PhysicsControl, PhysicsCollision public void setEventDispatchImpulseThreshold(float eventDispatchImpulseThreshold) { this.eventDispatchImpulseThreshold = eventDispatchImpulseThreshold; } + + /** + * Set the CcdMotionThreshold of all the bone's rigidBodies of the ragdoll + * @see PhysicsRigidBody#setCcdMotionThreshold(float) + * @param value + */ + public void setCcdMotionThreshold(float value) { + for (PhysicsBoneLink link : boneLinks.values()) { + link.rigidBody.setCcdMotionThreshold(value); + } + } + + /** + * Set the CcdSweptSphereRadius of all the bone's rigidBodies of the ragdoll + * @see PhysicsRigidBody#setCcdSweptSphereRadius(float) + * @param value + */ + public void setCcdSweptSphereRadius(float value) { + for (PhysicsBoneLink link : boneLinks.values()) { + link.rigidBody.setCcdSweptSphereRadius(value); + } + } + + /** + * Set the CcdMotionThreshold of the given bone's rigidBodies of the ragdoll + * @see PhysicsRigidBody#setCcdMotionThreshold(float) + * @param value + * @deprecated use getBoneRigidBody(String BoneName).setCcdMotionThreshold(float) instead + */ + @Deprecated + public void setBoneCcdMotionThreshold(String boneName, float value) { + PhysicsBoneLink link = boneLinks.get(boneName); + if (link != null) { + link.rigidBody.setCcdMotionThreshold(value); + } + } + + /** + * Set the CcdSweptSphereRadius of the given bone's rigidBodies of the ragdoll + * @see PhysicsRigidBody#setCcdSweptSphereRadius(float) + * @param value + * @deprecated use getBoneRigidBody(String BoneName).setCcdSweptSphereRadius(float) instead + */ + @Deprecated + public void setBoneCcdSweptSphereRadius(String boneName, float value) { + PhysicsBoneLink link = boneLinks.get(boneName); + if (link != null) { + link.rigidBody.setCcdSweptSphereRadius(value); + } + } + + /** + * return the rigidBody associated to the given bone + * @param boneName the name of the bone + * @return the associated rigidBody. + */ + public PhysicsRigidBody getBoneRigidBody(String boneName) { + PhysicsBoneLink link = boneLinks.get(boneName); + if (link != null) { + return link.rigidBody; + } + return null; + } }