- 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
3.0
nor..67 12 years ago
parent a53071ca4d
commit 56244c7744
  1. 160
      engine/src/bullet-common/com/jme3/bullet/control/KinematicRagdollControl.java

@ -193,108 +193,116 @@ public class KinematicRagdollControl extends AbstractPhysicsControl implements P
if (!enabled) { if (!enabled) {
return; 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 tmpRot1 = vars.quat1;
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. for (PhysicsBoneLink link : boneLinks.values()) {
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 //retrieving bone position in physic world space
Vector3f p = link.rigidBody.getMotionState().getWorldLocation(); Vector3f p = link.rigidBody.getMotionState().getWorldLocation();
//transforming this position with inverse transforms of the model //transforming this position with inverse transforms of the model
targetModel.getWorldTransform().transformInverseVector(p, position); targetModel.getWorldTransform().transformInverseVector(p, position);
//retrieving bone rotation in physic world space //retrieving bone rotation in physic world space
Quaternion q = link.rigidBody.getMotionState().getWorldRotationQuat(); Quaternion q = link.rigidBody.getMotionState().getWorldRotationQuat();
//multiplying this rotation by the initialWorld rotation of the bone, //multiplying this rotation by the initialWorld rotation of the bone,
//then transforming it with the inverse world rotation of the model //then transforming it with the inverse world rotation of the model
tmpRot1.set(q).multLocal(link.initalWorldRotation); tmpRot1.set(q).multLocal(link.initalWorldRotation);
tmpRot2.set(targetModel.getWorldRotation()).inverseLocal().mult(tmpRot1, tmpRot1); tmpRot2.set(targetModel.getWorldRotation()).inverseLocal().mult(tmpRot1, tmpRot1);
tmpRot1.normalizeLocal(); 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 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 (link.bone.getParent() == null) {
//offsetting the physic's position/rotation by the root bone inverse model space position/rotaion //offsetting the physic's position/rotation by the root bone inverse model space position/rotaion
modelPosition.set(p).subtractLocal(link.bone.getWorldBindPosition()); modelPosition.set(p).subtractLocal(link.bone.getWorldBindPosition());
targetModel.getParent().getWorldTransform().transformInverseVector(modelPosition, modelPosition); targetModel.getParent().getWorldTransform().transformInverseVector(modelPosition, modelPosition);
modelRotation.set(q).multLocal(tmpRot2.set(link.bone.getWorldBindRotation()).inverseLocal()); modelRotation.set(q).multLocal(tmpRot2.set(link.bone.getWorldBindRotation()).inverseLocal());
//applying transforms to the model //applying transforms to the model
targetModel.setLocalTranslation(modelPosition); targetModel.setLocalTranslation(modelPosition);
targetModel.setLocalRotation(modelRotation); targetModel.setLocalRotation(modelRotation);
//Applying computed transforms to the bone //Applying computed transforms to the bone
link.bone.setUserTransformsWorld(position, tmpRot1); 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 { } else {
//if boneList is empty, this means that every bone in the ragdoll has a collision shape, //boneList is not empty, this means some bones of the skeleton might not be associated with a collision shape.
//so we just update the bone position //So we update them recusively
if (boneList.isEmpty()) { RagdollUtils.setTransform(link.bone, position, tmpRot1, false, boneList);
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);
}
} }
} }
} else { }
//the ragdoll does not have the controll, so the keyframed animation updates the physic position of the physic bonces vars.release();
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);
}
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 //time control for blending
if (blendedControl) { if (blendedControl) {
blendStart += tpf; blendStart += tpf;
if (blendStart > blendTime) { if (blendStart > blendTime) {
blendedControl = false; blendedControl = false;
}
} }
} }
vars.release(); vars.release();
} }
/** /**

Loading…
Cancel
Save