Feature: added support for 'Use tail' option in Inverse Kinematics

constraint.
Bugfix: fixed a bug that could cause bad computations when bones were
not directly 'in touch' with their parents.
experimental
jmekaelthas 10 years ago
parent a5699e9d82
commit 6a642ae1be
  1. 21
      jme3-blender/src/main/java/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionIK.java

@ -22,6 +22,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
*/ */
public class ConstraintDefinitionIK extends ConstraintDefinition { public class ConstraintDefinitionIK extends ConstraintDefinition {
private static final float MIN_DISTANCE = 0.0001f; private static final float MIN_DISTANCE = 0.0001f;
private static final int FLAG_USE_TAIL = 0x01;
private static final int FLAG_POSITION = 0x20; private static final int FLAG_POSITION = 0x20;
/** The number of affected bones. Zero means that all parent bones of the current bone should take part in baking. */ /** The number of affected bones. Zero means that all parent bones of the current bone should take part in baking. */
@ -30,6 +31,8 @@ public class ConstraintDefinitionIK extends ConstraintDefinition {
private float chainLength; private float chainLength;
/** Tells if there is anything to compute at all. */ /** Tells if there is anything to compute at all. */
private boolean needToCompute = true; private boolean needToCompute = true;
/** Indicates if the tail of the bone should be used or not. */
private boolean useTail;
/** The amount of iterations of the algorithm. */ /** The amount of iterations of the algorithm. */
private int iterations; private int iterations;
@ -37,6 +40,7 @@ public class ConstraintDefinitionIK extends ConstraintDefinition {
super(constraintData, ownerOMA, blenderContext); super(constraintData, ownerOMA, blenderContext);
bonesAffected = ((Number) constraintData.getFieldValue("rootbone")).intValue(); bonesAffected = ((Number) constraintData.getFieldValue("rootbone")).intValue();
iterations = ((Number) constraintData.getFieldValue("iterations")).intValue(); iterations = ((Number) constraintData.getFieldValue("iterations")).intValue();
useTail = (flag & FLAG_USE_TAIL) != 0;
if ((flag & FLAG_POSITION) == 0) { if ((flag & FLAG_POSITION) == 0) {
needToCompute = false; needToCompute = false;
@ -149,6 +153,12 @@ public class ConstraintDefinitionIK extends ConstraintDefinition {
private List<BoneContext> loadBones() { private List<BoneContext> loadBones() {
List<BoneContext> bones = new ArrayList<BoneContext>(); List<BoneContext> bones = new ArrayList<BoneContext>();
Bone bone = (Bone) this.getOwner(); Bone bone = (Bone) this.getOwner();
if (bone == null) {
return bones;
}
if (!useTail) {
bone = bone.getParent();
}
chainLength = 0; chainLength = 0;
while (bone != null) { while (bone != null) {
BoneContext boneContext = blenderContext.getBoneContext(bone); BoneContext boneContext = blenderContext.getBoneContext(bone);
@ -158,7 +168,18 @@ public class ConstraintDefinitionIK extends ConstraintDefinition {
if (bonesAffected != 0 && bones.size() >= bonesAffected) { if (bonesAffected != 0 && bones.size() >= bonesAffected) {
break; break;
} }
// need to add spaces between bones to the chain length
Transform boneWorldTransform = constraintHelper.getTransform(boneContext.getArmatureObjectOMA(), boneContext.getBone().getName(), Space.CONSTRAINT_SPACE_WORLD);
Vector3f boneWorldTranslation = boneWorldTransform.getTranslation();
bone = bone.getParent(); bone = bone.getParent();
if (bone != null) {
boneContext = blenderContext.getBoneContext(bone);
Transform parentWorldTransform = constraintHelper.getTransform(boneContext.getArmatureObjectOMA(), boneContext.getBone().getName(), Space.CONSTRAINT_SPACE_WORLD);
Vector3f parentWorldTranslation = parentWorldTransform.getTranslation();
chainLength += boneWorldTranslation.distance(parentWorldTranslation);
}
} }
return bones; return bones;
} }

Loading…
Cancel
Save