@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); } }
@Override public boolean isLeaf(Object node) { Bone f = (Bone) node; if (f.getChildren() == null) { return true; } return f.getChildren().isEmpty(); }
@Override public int getChildCount(Object parent) { Bone f = (Bone) parent; if (f.getChildren() == null) { return 0; } return f.getChildren().size(); }
@Override public Object getChild(Object parent, int index) { Bone f = (Bone) parent; if (f.getChildren() == null) { return null; } return f.getChildren().get(index); }
@Override public int getIndexOfChild(Object parent, Object child) { Bone par = (Bone) parent; Bone ch = (Bone) child; if (par.getChildren() == null) { return 0; } return par.getChildren().indexOf(ch); }
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); } } }
/** * This method builds the bone. It recursively builds the bone's children. * * @param bones a list of bones where the newly created bone will be added * @param boneOMAs the map between bone and its old memory address * @param blenderContext the blender context * @return newly created bone */ public Bone buildBone(List<Bone> bones, Map<Bone, Long> boneOMAs, BlenderContext blenderContext) { Long boneOMA = boneStructure.getOldMemoryAddress(); bone = new Bone(boneName); bones.add(bone); boneOMAs.put(bone, boneOMA); blenderContext.addLoadedFeatures(boneOMA, boneName, boneStructure, bone); Matrix4f pose = this.restMatrix.clone(); ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class); Vector3f poseLocation = pose.toTranslationVector(); Quaternion rotation = pose.toRotationQuat(); Vector3f scale = objectHelper.getScale(pose); bone.setBindTransforms(poseLocation, rotation, scale); for (BoneContext child : children) { bone.addChild(child.buildBone(bones, boneOMAs, blenderContext)); } this.computePoseTransform(); return bone; }
/** This method computes the pose transform for the bone. */ @SuppressWarnings("unchecked") private void computePoseTransform() { DynamicArray<Number> loc = (DynamicArray<Number>) poseChannel.getFieldValue("loc"); DynamicArray<Number> size = (DynamicArray<Number>) poseChannel.getFieldValue("size"); DynamicArray<Number> quat = (DynamicArray<Number>) poseChannel.getFieldValue("quat"); if (fixUpAxis) { poseTransform.setTranslation( loc.get(0).floatValue(), -loc.get(2).floatValue(), loc.get(1).floatValue()); poseTransform.setRotation( new Quaternion( quat.get(1).floatValue(), quat.get(3).floatValue(), -quat.get(2).floatValue(), quat.get(0).floatValue())); poseTransform.setScale( size.get(0).floatValue(), size.get(2).floatValue(), size.get(1).floatValue()); } else { poseTransform.setTranslation( loc.get(0).floatValue(), loc.get(1).floatValue(), loc.get(2).floatValue()); poseTransform.setRotation( new Quaternion( quat.get(0).floatValue(), quat.get(1).floatValue(), quat.get(2).floatValue(), quat.get(3).floatValue())); poseTransform.setScale( size.get(0).floatValue(), size.get(1).floatValue(), size.get(2).floatValue()); } Transform localTransform = new Transform(bone.getLocalPosition(), bone.getLocalRotation()); localTransform.setScale(bone.getLocalScale()); localTransform.getTranslation().addLocal(poseTransform.getTranslation()); localTransform.getRotation().multLocal(poseTransform.getRotation()); localTransform.getScale().multLocal(poseTransform.getScale()); poseTransform.set(localTransform); }
public static void setBonesSuchAs(AnimControl animControl, String animationName) { Animation animation = animControl.getAnim(animationName); int size = animControl.getSkeleton().getBoneCount(); for (int index = 0; index < size; index++) { Bone bone = animControl.getSkeleton().getBone(index); BoneTrack boneTrack = getFirstTrackForBone(animation, index); if (boneTrack != null) { Quaternion rotation = boneTrack.getRotations()[0]; Vector3f translation = boneTrack.getTranslations()[0]; Vector3f scale = boneTrack.getScales()[0]; System.out.println("Bone = " + bone.getName()); System.out.println("\tRotation = " + rotation); System.out.println("\tTranslation = " + translation); System.out.println("\tScale = " + scale); bone.setUserControl(true); bone.setUserTransforms(translation, rotation, scale); bone.updateWorldVectors(); bone.setUserControl(false); } } }
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); } }