@Override protected void prepareTracksForApplyingConstraints() { Long[] bonesOMAs = new Long[] {ownerOMA, targetOMA}; Space[] spaces = new Space[] {ownerSpace, targetSpace}; // creating animations for current objects if at least on of their parents have an animation for (int i = 0; i < bonesOMAs.length; ++i) { Long oma = bonesOMAs[i]; if (this.hasAnimation(oma)) { Bone currentBone = blenderContext.getBoneContext(oma).getBone(); Bone parent = currentBone.getParent(); boolean foundAnimation = false; AnimData animData = null; while (parent != null && !foundAnimation) { BoneContext boneContext = blenderContext.getBoneByName(parent.getName()); foundAnimation = this.hasAnimation(boneContext.getBoneOma()); animData = blenderContext.getAnimData(boneContext.getBoneOma()); parent = parent.getParent(); } if (foundAnimation) { this.applyAnimData(blenderContext.getBoneContext(oma), spaces[i], animData); } } } // creating animation for owner if it doesn't have one already and if the target has it if (!this.hasAnimation(ownerOMA) && this.hasAnimation(targetOMA)) { AnimData targetAnimData = blenderContext.getAnimData(targetOMA); this.applyAnimData(blenderContext.getBoneContext(ownerOMA), ownerSpace, targetAnimData); } }
private void scanSpatial(Spatial model) { AnimControl animControl = model.getControl(AnimControl.class); Map<Integer, List<Float>> pointsMap = null; if (weightThreshold == -1.0f) { pointsMap = RagdollUtils.buildPointMap(model); } skeleton = animControl.getSkeleton(); skeleton.resetAndUpdate(); for (int i = 0; i < skeleton.getRoots().length; i++) { Bone childBone = skeleton.getRoots()[i]; if (childBone.getParent() == null) { logger.log(Level.INFO, "Found root bone in skeleton {0}", skeleton); baseRigidBody = new PhysicsRigidBody(new BoxCollisionShape(Vector3f.UNIT_XYZ.mult(0.1f)), 1); baseRigidBody.setKinematic(mode == Mode.Kinematic); boneRecursion(model, childBone, baseRigidBody, 1, pointsMap); } } }
private void boneRecursion( Spatial model, Bone bone, PhysicsRigidBody parent, int reccount, Map<Integer, List<Float>> pointsMap) { PhysicsRigidBody parentShape = parent; if (boneList.isEmpty() || boneList.contains(bone.getName())) { PhysicsBoneLink link = new PhysicsBoneLink(); link.bone = bone; // creating the collision shape HullCollisionShape shape = null; if (pointsMap != null) { // build a shape for the bone, using the vertices that are most influenced by this bone shape = RagdollUtils.makeShapeFromPointMap( pointsMap, RagdollUtils.getBoneIndices(link.bone, skeleton, boneList), initScale, link.bone.getModelSpacePosition()); } else { // build a shape for the bone, using the vertices associated with this bone with a weight // above the threshold shape = RagdollUtils.makeShapeFromVerticeWeights( model, RagdollUtils.getBoneIndices(link.bone, skeleton, boneList), initScale, link.bone.getModelSpacePosition(), weightThreshold); } PhysicsRigidBody shapeNode = new PhysicsRigidBody(shape, rootMass / (float) reccount); shapeNode.setKinematic(mode == Mode.Kinematic); totalMass += rootMass / (float) reccount; link.rigidBody = shapeNode; link.initalWorldRotation = bone.getModelSpaceRotation().clone(); if (parent != null) { // get joint position for parent Vector3f posToParent = new Vector3f(); if (bone.getParent() != null) { bone.getModelSpacePosition() .subtract(bone.getParent().getModelSpacePosition(), posToParent) .multLocal(initScale); } SixDofJoint joint = new SixDofJoint(parent, shapeNode, posToParent, new Vector3f(0, 0, 0f), true); preset.setupJointForBone(bone.getName(), joint); link.joint = joint; joint.setCollisionBetweenLinkedBodys(false); } 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); } }