/** * returns the bone with the given name * @param name * @return */ public Bone getBone(String name) { for (int i = 0; i < boneList.length; i++) { if (boneList[i].getName().equals(name)) { return boneList[i]; } } return null; }
/** * 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; }
/** * Returns bone context for the given bone. * * @param bone * the bone * @return the bone's bone context */ public BoneContext getBoneContext(Bone bone) { for (Entry<Long, BoneContext> entry : boneContexts.entrySet()) { if (entry.getValue().getBone().getName().equals(bone.getName())) { return entry.getValue(); } } throw new IllegalStateException("Cannot find context for bone: " + bone); }
/** * Returns bone by given name. * * @param skeletonOMA * the OMA of the skeleton where the bone will be searched * @param name * the name of the bone * @return found bone or null if none bone of a given name exists */ public BoneContext getBoneByName(Long skeletonOMA, String name) { for (Entry<Long, BoneContext> entry : boneContexts.entrySet()) { if (entry.getValue().getArmatureObjectOMA().equals(skeletonOMA)) { Bone bone = entry.getValue().getBone(); if (bone != null && name.equals(bone.getName())) { return entry.getValue(); } } } return null; }
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; }
/** * Enumerate the bone indices of the specified bone and all its descendents. * * @param bone the input bone (not null) * @param skeleton the skeleton containing the bone (not null) * @param boneList a set of bone names (not null, unaffected) * * @return a new list (not null) */ public static List<Integer> getBoneIndices(Bone bone, Skeleton skeleton, Set<String> boneList) { List<Integer> list = new LinkedList<Integer>(); if (boneList.isEmpty()) { list.add(skeleton.getBoneIndex(bone)); } else { list.add(skeleton.getBoneIndex(bone)); for (Bone chilBone : bone.getChildren()) { if (!boneList.contains(chilBone.getName())) { list.addAll(getBoneIndices(chilBone, skeleton, boneList)); } } } return list; }
/** * Enumerate the bone indices of the specified bone and all its descendents. * * @param bone the input bone (not null) * @param skeleton the skeleton containing the bone (not null) * @param boneList a set of bone names (not null, unaffected) * * @return a new list (not null) */ public static List<Integer> getBoneIndices(Bone bone, Skeleton skeleton, Set<String> boneList) { List<Integer> list = new LinkedList<Integer>(); if (boneList.isEmpty()) { list.add(skeleton.getBoneIndex(bone)); } else { list.add(skeleton.getBoneIndex(bone)); for (Bone chilBone : bone.getChildren()) { if (!boneList.contains(chilBone.getName())) { list.addAll(getBoneIndices(chilBone, skeleton, boneList)); } } } return list; }
/** * Add a target for inverse kinematics. * * @param bone which bone the IK applies to (not null) * @param worldPos the world coordinates of the goal (not null) * @param chainLength number of bones in the chain * @return a new instance (not null, already added to ikTargets) */ public Vector3f setIKTarget(Bone bone, Vector3f worldPos, int chainLength) { Vector3f target = worldPos.subtract(targetModel.getWorldTranslation()); ikTargets.put(bone.getName(), target); ikChainDepth.put(bone.getName(), chainLength); int i = 0; while (i < chainLength+2 && bone.getParent() != null) { if (!bone.hasUserControl()) { bone.setUserControl(true); } bone = bone.getParent(); i++; } // setIKMode(); return target; }
/** * Add a target for inverse kinematics. * * @param bone which bone the IK applies to (not null) * @param worldPos the world coordinates of the goal (not null) * @param chainLength number of bones in the chain * @return a new instance (not null, already added to ikTargets) */ public Vector3f setIKTarget(Bone bone, Vector3f worldPos, int chainLength) { Vector3f target = worldPos.subtract(targetModel.getWorldTranslation()); ikTargets.put(bone.getName(), target); ikChainDepth.put(bone.getName(), chainLength); int i = 0; while (i < chainLength+2 && bone.getParent() != null) { if (!bone.hasUserControl()) { bone.setUserControl(true); } bone = bone.getParent(); i++; } // setIKMode(); return target; }
/** * 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++; } }
@Override public void apply(Node node, BlenderContext blenderContext) { if (invalid) { LOGGER.log(Level.WARNING, "Armature modifier is invalid! Cannot be applied to: {0}", node.getName()); } if (modifying) { TemporalMesh temporalMesh = this.getTemporalMesh(node); if (temporalMesh != null) { LOGGER.log(Level.FINE, "Applying armature modifier to: {0}", temporalMesh); LOGGER.fine("Creating map between bone name and its index."); for (int i = 0; i < skeleton.getBoneCount(); ++i) { Bone bone = skeleton.getBone(i); temporalMesh.addBoneIndex(bone.getName(), i); } temporalMesh.applyAfterMeshCreate(this); } else { LOGGER.log(Level.WARNING, "Cannot find temporal mesh for node: {0}. The modifier will NOT be applied!", node); } } } }
/** * Remove any bones without vertices from the boneList, so that every hull * shape will contain at least 1 vertex. */ private void filterBoneList(SkeletonControl skeletonControl) { Mesh[] targets = skeletonControl.getTargets(); Skeleton skel = skeletonControl.getSkeleton(); for (int boneI = 0; boneI < skel.getBoneCount(); boneI++) { String boneName = skel.getBone(boneI).getName(); if (boneList.contains(boneName)) { boolean hasVertices = RagdollUtils.hasVertices(boneI, targets, weightThreshold); if (!hasVertices) { boneList.remove(boneName); } } } }
/** * Remove any bones without vertices from the boneList, so that every hull * shape will contain at least 1 vertex. */ private void filterBoneList(SkeletonControl skeletonControl) { Mesh[] targets = skeletonControl.getTargets(); Skeleton skel = skeletonControl.getSkeleton(); for (int boneI = 0; boneI < skel.getBoneCount(); boneI++) { String boneName = skel.getBone(boneI).getName(); if (boneList.contains(boneName)) { boolean hasVertices = RagdollUtils.hasVertices(boneI, targets, weightThreshold); if (!hasVertices) { boneList.remove(boneName); } } } }
/** * 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++; } }
/** * 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(); } }
/** * 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(); } }
public BonesChain(Bone bone, boolean useTail, int bonesAffected, Collection<Long> alteredOmas, BlenderContext blenderContext) { if (bone != null) { ConstraintHelper constraintHelper = blenderContext.getHelper(ConstraintHelper.class); if (!useTail) { bone = bone.getParent(); } while (bone != null && (bonesAffected <= 0 || this.size() < bonesAffected)) { BoneContext boneContext = blenderContext.getBoneContext(bone); this.add(boneContext); alteredOmas.add(boneContext.getBoneOma()); Transform transform = constraintHelper.getTransform(boneContext.getArmatureObjectOMA(), boneContext.getBone().getName(), Space.CONSTRAINT_SPACE_WORLD); localBonesMatrices.add(new DTransform(transform).toMatrix()); bone = bone.getParent(); } if(localBonesMatrices.size() > 0) { // making the matrices describe the local transformation Matrix parentWorldMatrix = localBonesMatrices.get(localBonesMatrices.size() - 1); for(int i=localBonesMatrices.size() - 2;i>=0;--i) { SimpleMatrix m = parentWorldMatrix.invert().mult(localBonesMatrices.get(i)); parentWorldMatrix = localBonesMatrices.get(i); localBonesMatrices.set(i, new Matrix(m)); } } } }
/** * The method gets the owner's transformation. The owner can be either bone or spatial. * @param ownerSpace * the space in which the computed transformation is given * @return the constraint owner's transformation */ protected Transform getOwnerTransform(Space ownerSpace) { if (this.getOwner() instanceof Bone) { BoneContext boneContext = blenderContext.getBoneContext(ownerOMA); return constraintHelper.getTransform(boneContext.getArmatureObjectOMA(), boneContext.getBone().getName(), ownerSpace); } return constraintHelper.getTransform(ownerOMA, null, ownerSpace); }
/** * The method applies the given transformation to the owner. * @param ownerTransform * the transformation to apply to the owner * @param ownerSpace * the space that defines which owner's transformation (ie. global, local, etc. will be set) */ protected void applyOwnerTransform(Transform ownerTransform, Space ownerSpace) { if (this.getOwner() instanceof Bone) { BoneContext boneContext = blenderContext.getBoneContext(ownerOMA); constraintHelper.applyTransform(boneContext.getArmatureObjectOMA(), boneContext.getBone().getName(), ownerSpace, ownerTransform); } else { constraintHelper.applyTransform(ownerOMA, null, ownerSpace, ownerTransform); } }
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; }