if (link == null || link.bone.getParent() == null) { return; Quaternion preQuat = link.bone.getLocalRotation(); Vector3f vectorAxis; tmpRot2[posOrNeg] = link.bone.getLocalRotation().mult(tmpRot1); tmpRot2[posOrNeg].normalizeLocal(); link.bone.setLocalRotation(tmpRot2[posOrNeg]); link.bone.update(); measureDist[posOrNeg] = tipBone.getModelSpacePosition().distance(target); link.bone.setLocalRotation(preQuat); link.bone.setLocalRotation(tmpRot2[0]); } else if (measureDist[0] > measureDist[1]) { link.bone.setLocalRotation(tmpRot2[1]); link.bone.getLocalRotation().normalizeLocal(); link.bone.update(); if (link.bone.getParent() != null && depth < maxDepth) { updateBone(boneLinks.get(link.bone.getParent().getName()), tpf * limbDampening, vars, tmpRot1, tmpRot2, tipBone, target, depth + 1, maxDepth);
public Bone getJmeBone() { if (bone == null) { bone = new Bone(name); bone.setBindTransforms(jmeLocalBindPose.getTranslation(), jmeLocalBindPose.getRotation(), jmeLocalBindPose.getScale()); } return bone; } }
if (boneList.contains(bone.getName())) { if (pointsMap != null) { shape = RagdollUtils.makeShapeFromPointMap(pointsMap, RagdollUtils.getBoneIndices(link.bone, skeleton, boneList), initScale, link.bone.getModelSpacePosition()); } else { shape = RagdollUtils.makeShapeFromVerticeWeights(model, RagdollUtils.getBoneIndices(link.bone, skeleton, boneList), initScale, link.bone.getModelSpacePosition(), weightThreshold); link.initalWorldRotation = bone.getModelSpaceRotation().clone(); if (bone.getParent() != null) { bone.getModelSpacePosition().subtract(bone.getParent().getModelSpacePosition(), posToParent).multLocal(initScale); preset.setupJointForBone(bone.getName(), joint); boneLinks.put(bone.getName(), link); shapeNode.setUserObject(link); parentShape = shapeNode; for (Iterator<Bone> it = bone.getChildren().iterator(); it.hasNext();) { Bone childBone = it.next(); boneRecursion(model, childBone, parentShape, reccount + 1, pointsMap);
/** * Remove the inverse-kinematics target for the specified bone. * * @param bone which bone has the target (not null, modified) */ public void removeIKTarget(Bone bone) { int depth = ikChainDepth.remove(bone.getName()); int i = 0; while (i < depth+2 && bone.getParent() != null) { if (bone.hasUserControl()) { // matchPhysicObjectToBone(boneLinks.get(bone.getName()), position, tmpRot1); bone.setUserControl(false); } bone = bone.getParent(); i++; } }
/** * Alter the user-control flags of a bone and all its descendents. * * @param bone the ancestor bone (not null, modified) * @param bool true to enable user control, false to disable */ public static void setUserControl(Bone bone, boolean bool) { bone.setUserControl(bool); for (Bone child : bone.getChildren()) { setUserControl(child, bool); } }
private Bone recreateBoneStructure(Bone sourceRoot) { Bone targetRoot = getBone(sourceRoot.getName()); List<Bone> children = sourceRoot.getChildren(); for (int i = 0; i < children.size(); i++) { Bone sourceChild = children.get(i); // find my version of the child Bone targetChild = getBone(sourceChild.getName()); targetRoot.addChild(targetChild); recreateBoneStructure(sourceChild); } return targetRoot; }
selectedBones.put(skeleton.getSkeleton(), selectedBone); System.err.println("-----------------------"); System.err.println("Selected Bone : " + selectedBone.getName() + " in skeleton " + skeleton.getName()); System.err.println("Root Bone : " + (selectedBone.getParent() == null)); System.err.println("-----------------------"); System.err.println("Bind translation: " + selectedBone.getBindPosition()); System.err.println("Bind rotation: " + selectedBone.getBindRotation()); System.err.println("Bind scale: " + selectedBone.getBindScale()); System.err.println("---"); System.err.println("Local translation: " + selectedBone.getLocalPosition()); System.err.println("Local rotation: " + selectedBone.getLocalRotation()); System.err.println("Local scale: " + selectedBone.getLocalScale()); System.err.println("---"); System.err.println("Model translation: " + selectedBone.getModelSpacePosition()); System.err.println("Model rotation: " + selectedBone.getModelSpaceRotation()); System.err.println("Model scale: " + selectedBone.getModelSpaceScale()); System.err.println("---"); System.err.println("Bind inverse Transform: "); System.err.println(selectedBone.getBindInverseTransform()); return;
int boneIndex = skeleton.getBoneIndex(boneContext.getBone()); if (!tracks.containsKey(boneIndex)) { tracks.put(boneIndex, new VirtualTrack(boneContext.getBone().getName(), maxFrame, maxTime)); Vector3f bonePositionDifference = bone.getLocalPosition().subtract(startTransform.getTranslation()); Quaternion boneRotationDifference = startTransform.getRotation().inverse().mult(bone.getLocalRotation()).normalizeLocal(); Vector3f boneScaleDifference = bone.getLocalScale().divide(startTransform.getScale());
public static boolean equalBindAndLocalTransforms(Bone b) { return equalsEpsilon(b.getBindPosition(), b.getLocalPosition()) && equalsEpsilon(b.getBindRotation(), b.getLocalRotation()) && equalsEpsilon(b.getBindScale(), b.getLocalScale()); }
if (link.bone.getParent() == null) { modelPosition.set(p).subtractLocal(link.bone.getBindPosition()); targetModel.getParent().getWorldTransform().transformInverseVector(modelPosition, modelPosition); modelRotation.set(q).multLocal(tmpRot2.set(link.bone.getBindRotation()).inverseLocal()); link.bone.setUserTransformsInModelSpace(position, tmpRot1);
Bone bone = targetBoneContext.getBone(); if (bone.getParent() == null && (space == Space.CONSTRAINT_SPACE_LOCAL || space == Space.CONSTRAINT_SPACE_PARLOCAL)) { space = Space.CONSTRAINT_SPACE_POSE; case CONSTRAINT_SPACE_WORLD: Spatial model = (Spatial) blenderContext.getLoadedFeature(targetBoneContext.getSkeletonOwnerOma(), LoadedDataType.FEATURE); Matrix4f boneModelMatrix = this.toMatrix(bone.getModelSpacePosition(), bone.getModelSpaceRotation(), bone.getModelSpaceScale(), tempVars.tempMat4); Matrix4f modelWorldMatrix = this.toMatrix(model.getWorldTransform(), tempVars.tempMat42); Matrix4f boneMatrixInWorldSpace = modelWorldMatrix.multLocal(boneModelMatrix); break; case CONSTRAINT_SPACE_LOCAL: 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: { 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);
bone.setUserControl(true); bone.setUserTransformsInModelSpace(pos, rot); for (Bone childBone : bone.getChildren()) { if (!boneList.contains(childBone.getName())) { Transform t = childBone.getCombinedTransform(pos, rot); setTransform(childBone, t.getTranslation(), t.getRotation(), restoreBoneControl, boneList); bone.setUserControl(false);
Bone bone = nameToBone.get(boneName); Bone parent = nameToBone.get(parentName); parent.addChild(bone); } else if (qName.equals("bone")) { assert elementStack.peek().equals("bones"); bone = new Bone(attribs.getValue("name")); int id = SAXUtil.parseInt(attribs.getValue("id")); indexToBone.put(id, bone); nameToBone.put(bone.getName(), bone); } else if (qName.equals("tracks")) { assert elementStack.peek().equals("animation");
private static Joint fromBone(Bone b) { Joint j = new Joint(b.getName()); j.setLocalTranslation(b.getBindPosition()); j.setLocalRotation(b.getBindRotation()); j.setLocalScale(b.getBindScale()); return j; }
if (bone.getParent() == null && (space == Space.CONSTRAINT_SPACE_LOCAL || space == Space.CONSTRAINT_SPACE_PARLOCAL)) { space = Space.CONSTRAINT_SPACE_POSE; switch (space) { case CONSTRAINT_SPACE_LOCAL: assert bone.getParent() != null : "CONSTRAINT_SPACE_LOCAL should be evaluated as CONSTRAINT_SPACE_POSE if the bone has no parent!"; bone.setBindTransforms(transform.getTranslation(), transform.getRotation(), transform.getScale()); break; case CONSTRAINT_SPACE_WORLD: { Matrix4f modelWorldMatrix = this.toMatrix(this.getTransform(targetBoneContext.getSkeletonOwnerOma(), null, Space.CONSTRAINT_SPACE_WORLD), tempVars.tempMat42); Matrix4f boneMatrixInModelSpace = modelWorldMatrix.invertLocal().multLocal(boneMatrixInWorldSpace); Bone parent = bone.getParent(); if (parent != null) { Matrix4f parentMatrixInModelSpace = this.toMatrix(parent.getModelSpacePosition(), parent.getModelSpaceRotation(), parent.getModelSpaceScale(), tempVars.tempMat4); boneMatrixInModelSpace = parentMatrixInModelSpace.invertLocal().multLocal(boneMatrixInModelSpace); bone.setBindTransforms(boneMatrixInModelSpace.toTranslationVector(), boneMatrixInModelSpace.toRotationQuat(), boneMatrixInModelSpace.toScaleVector()); break; 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) { Matrix4f parentMatrixInModelSpace = this.toMatrix(parent.getModelSpacePosition(), parent.getModelSpaceRotation(), parent.getModelSpaceScale(), tempVars.tempMat4); boneMatrixInModelSpace = parentMatrixInModelSpace.invertLocal().multLocal(boneMatrixInModelSpace); bone.setBindTransforms(boneMatrixInModelSpace.toTranslationVector(), boneMatrixInModelSpace.toRotationQuat(), boneMatrixInModelSpace.toScaleVector()); break;
/** * Ensure that user control is enabled for any bones used by inverse * kinematics and disabled for any other bones. */ public void applyUserControl() { for (Bone bone : skeleton.getRoots()) { RagdollUtils.setUserControl(bone, false); } if (ikTargets.isEmpty()) { setKinematicMode(); } else { Iterator iterator = ikTargets.keySet().iterator(); TempVars vars = TempVars.get(); while (iterator.hasNext()) { Bone bone = (Bone) iterator.next(); while (bone.getParent() != null) { Quaternion tmpRot1 = vars.quat1; Vector3f position = vars.vect1; matchPhysicObjectToBone(boneLinks.get(bone.getName()), position, tmpRot1); bone.setUserControl(true); bone = bone.getParent(); } } vars.release(); } }
/** * The method updates the geometry according to the poitions of the bones. */ public void updateGeometry() { VertexBuffer vb = this.getBuffer(Type.Position); FloatBuffer posBuf = this.getFloatBuffer(Type.Position); posBuf.clear(); for (int i = 0; i < skeleton.getBoneCount(); ++i) { Bone bone = skeleton.getBone(i); Vector3f head = bone.getModelSpacePosition(); posBuf.put(head.getX()).put(head.getY()).put(head.getZ()); if (boneLengths != null) { Vector3f tail = head.add(bone.getModelSpaceRotation().mult(Vector3f.UNIT_Y.mult(boneLengths.get(i)))); posBuf.put(tail.getX()).put(tail.getY()).put(tail.getZ()); } } posBuf.flip(); vb.updateData(posBuf); this.updateBound(); }
/** * Converts the action into JME bone animation tracks. * * @param skeleton * the skeleton that will be animated * @return the bone tracks for the node */ public BoneTrack[] toTracks(Skeleton skeleton, BlenderContext blenderContext) { List<BoneTrack> tracks = new ArrayList<BoneTrack>(featuresTracks.size()); for (Entry<String, Ipo> entry : featuresTracks.entrySet()) { int boneIndex = skeleton.getBoneIndex(entry.getKey()); BoneContext boneContext = blenderContext.getBoneContext(skeleton.getBone(boneIndex)); tracks.add((BoneTrack) entry.getValue().calculateTrack(boneIndex, boneContext, boneContext.getBone().getBindPosition(), boneContext.getBone().getBindRotation(), boneContext.getBone().getBindScale(), 1, stopFrame, fps, false)); } return tracks.toArray(new BoneTrack[tracks.size()]); }
/** * Alter the transforms of a rigidBody to match the transforms of a bone. * This is used to make the ragdoll follow animated motion in Kinematic mode * * @param link the bone link connecting the bone and the rigidBody * @param position temporary storage used in calculations (not null) * @param tmpRot1 temporary storage used in calculations (not null) */ protected 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.getModelBindInverseRotation()); targetModel.getWorldRotation().mult(tmpRot1, tmpRot1); tmpRot1.normalizeLocal(); //updating physics location/rotation of the physics bone link.rigidBody.setPhysicsLocation(position); link.rigidBody.setPhysicsRotation(tmpRot1); }
/** * returns the bone index of the bone that has the given name * @param name * @return */ public int getBoneIndex(String name) { for (int i = 0; i < boneList.length; i++) { if (boneList[i].getName().equals(name)) { return i; } } return -1; }