Bugfix: improved computation of 'Local with parent' bone constraint space (not yet perfect but much better than the previous one).
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@11017 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
fc8be06297
commit
84aa234446
@ -210,6 +210,13 @@ public class BoneContext {
|
||||
return blenderContext.getSkeleton(armatureObjectOMA);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the initial bone's matrix in model space
|
||||
*/
|
||||
public Matrix4f getBoneMatrixInModelSpace() {
|
||||
return boneMatrixInModelSpace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells if the bone is of specified property defined by its flag.
|
||||
* @param flagMask
|
||||
|
@ -8,7 +8,6 @@ import java.util.logging.Logger;
|
||||
|
||||
import com.jme3.animation.Bone;
|
||||
import com.jme3.animation.Skeleton;
|
||||
import com.jme3.math.FastMath;
|
||||
import com.jme3.math.Matrix4f;
|
||||
import com.jme3.math.Quaternion;
|
||||
import com.jme3.math.Transform;
|
||||
@ -34,9 +33,6 @@ import com.jme3.util.TempVars;
|
||||
public class ConstraintHelper extends AbstractBlenderHelper {
|
||||
private static final Logger LOGGER = Logger.getLogger(ConstraintHelper.class.getName());
|
||||
|
||||
private static final Quaternion POS_PARLOC_SPACE_QUATERNION = new Quaternion(new float[] { FastMath.HALF_PI, 0, 0 });
|
||||
private static final Quaternion NEG_PARLOC_SPACE_QUATERNION = new Quaternion(new float[] { -FastMath.HALF_PI, 0, 0 });
|
||||
|
||||
/**
|
||||
* Helper constructor.
|
||||
*
|
||||
@ -242,28 +238,28 @@ public class ConstraintHelper extends AbstractBlenderHelper {
|
||||
assert bone.getParent() != null : "CONSTRAINT_SPACE_LOCAL should be evaluated as CONSTRAINT_SPACE_POSE if the bone has no parent!";
|
||||
result = new Transform(bone.getLocalPosition(), bone.getLocalRotation(), bone.getLocalScale());
|
||||
break;
|
||||
case CONSTRAINT_SPACE_POSE:
|
||||
case CONSTRAINT_SPACE_POSE: {
|
||||
Matrix4f boneWorldMatrix = this.toMatrix(this.getTransform(oma, subtargetName, Space.CONSTRAINT_SPACE_WORLD), tempVars.tempMat4);
|
||||
Matrix4f armatureInvertedWorldMatrix = this.toMatrix(feature.getWorldTransform(), tempVars.tempMat42).invertLocal();
|
||||
Matrix4f bonePoseMatrix = armatureInvertedWorldMatrix.multLocal(boneWorldMatrix);
|
||||
result = new Transform(bonePoseMatrix.toTranslationVector(), bonePoseMatrix.toRotationQuat(), bonePoseMatrix.toScaleVector());
|
||||
break;
|
||||
case CONSTRAINT_SPACE_PARLOCAL:
|
||||
Matrix4f parentLocalMatrix = tempVars.tempMat4;
|
||||
if (bone.getParent() != null) {
|
||||
Bone parent = bone.getParent();
|
||||
this.toMatrix(parent.getLocalPosition(), parent.getLocalRotation(), parent.getLocalScale(), parentLocalMatrix);
|
||||
} else {
|
||||
parentLocalMatrix.loadIdentity();
|
||||
}
|
||||
Matrix4f boneLocalMatrix = this.toMatrix(bone.getLocalPosition(), bone.getLocalRotation(), bone.getLocalScale(), tempVars.tempMat42);
|
||||
Matrix4f resultMatrix = parentLocalMatrix.multLocal(boneLocalMatrix);
|
||||
}
|
||||
case CONSTRAINT_SPACE_PARLOCAL: {
|
||||
Matrix4f boneWorldMatrix = this.toMatrix(this.getTransform(oma, subtargetName, Space.CONSTRAINT_SPACE_WORLD), tempVars.tempMat4);
|
||||
Matrix4f armatureInvertedWorldMatrix = this.toMatrix(feature.getWorldTransform(), tempVars.tempMat42).invertLocal();
|
||||
Matrix4f bonePoseMatrix = armatureInvertedWorldMatrix.multLocal(boneWorldMatrix);
|
||||
result = new Transform(bonePoseMatrix.toTranslationVector(), bonePoseMatrix.toRotationQuat(), bonePoseMatrix.toScaleVector());
|
||||
Bone parent = bone.getParent();
|
||||
if(parent != null) {
|
||||
BoneContext parentContext = blenderContext.getBoneContext(parent);
|
||||
Vector3f head = parent.getModelSpacePosition();
|
||||
Vector3f tail = head.add(bone.getModelSpaceRotation().mult(Vector3f.UNIT_Y.mult(parentContext.getLength())));
|
||||
result.getTranslation().subtractLocal(tail);
|
||||
|
||||
Vector3f loc = resultMatrix.toTranslationVector();
|
||||
Quaternion rot = resultMatrix.toRotationQuat().normalizeLocal().multLocal(NEG_PARLOC_SPACE_QUATERNION);
|
||||
Vector3f scl = resultMatrix.toScaleVector();
|
||||
result = new Transform(loc, rot, scl);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new IllegalStateException("Unknown space type: " + space);
|
||||
}
|
||||
@ -342,19 +338,27 @@ public class ConstraintHelper extends AbstractBlenderHelper {
|
||||
break;
|
||||
}
|
||||
case CONSTRAINT_SPACE_PARLOCAL:
|
||||
Matrix4f parentLocalInverseMatrix = tempVars.tempMat4;
|
||||
if (bone.getParent() != null) {
|
||||
this.toMatrix(bone.getParent().getLocalPosition(), bone.getParent().getLocalRotation(), bone.getParent().getLocalScale(), parentLocalInverseMatrix);
|
||||
parentLocalInverseMatrix.invertLocal();
|
||||
} else {
|
||||
parentLocalInverseMatrix.loadIdentity();
|
||||
Matrix4f armatureWorldMatrix = this.toMatrix(feature.getWorldTransform(), tempVars.tempMat4);
|
||||
Matrix4f boneMatrixInWorldSpace = armatureWorldMatrix.multLocal(this.toMatrix(transform, tempVars.tempMat42));
|
||||
Matrix4f invertedModelMatrix = this.toMatrix(this.getTransform(targetBoneContext.getSkeletonOwnerOma(), null, Space.CONSTRAINT_SPACE_WORLD), tempVars.tempMat42).invertLocal();
|
||||
Matrix4f boneMatrixInModelSpace = invertedModelMatrix.multLocal(boneMatrixInWorldSpace);
|
||||
Bone parent = bone.getParent();
|
||||
if (parent != null) {
|
||||
//first add the initial parent matrix to the bone's model matrix
|
||||
BoneContext parentContext = blenderContext.getBoneContext(parent);
|
||||
|
||||
Matrix4f initialParentMatrixInModelSpace = parentContext.getBoneMatrixInModelSpace();
|
||||
Matrix4f currentParentMatrixInModelSpace = this.toMatrix(parent.getModelSpacePosition(), parent.getModelSpaceRotation(), parent.getModelSpaceScale(), tempVars.tempMat4);
|
||||
//the bone will now move with its parent in model space
|
||||
|
||||
//now we need to subtract the difference between current parent's model matrix and its initial model matrix
|
||||
boneMatrixInModelSpace = initialParentMatrixInModelSpace.mult(boneMatrixInModelSpace);
|
||||
|
||||
Matrix4f diffMatrix = initialParentMatrixInModelSpace.mult(currentParentMatrixInModelSpace.invert());
|
||||
boneMatrixInModelSpace.multLocal(diffMatrix);
|
||||
//now the bone will have its position in model space with initial parent's model matrix added
|
||||
}
|
||||
Matrix4f m = this.toMatrix(transform.getTranslation(), transform.getRotation(), transform.getScale(), tempVars.tempMat42);
|
||||
Matrix4f result = parentLocalInverseMatrix.multLocal(m);
|
||||
Vector3f loc = result.toTranslationVector();
|
||||
Quaternion rot = result.toRotationQuat().normalizeLocal().multLocal(POS_PARLOC_SPACE_QUATERNION);
|
||||
Vector3f scl = result.toScaleVector();
|
||||
bone.setBindTransforms(loc, rot, scl);
|
||||
bone.setBindTransforms(boneMatrixInModelSpace.toTranslationVector(), boneMatrixInModelSpace.toRotationQuat(), boneMatrixInModelSpace.toScaleVector());
|
||||
break;
|
||||
default:
|
||||
tempVars.release();
|
||||
|
Loading…
x
Reference in New Issue
Block a user