/** * Access the named bone. * * @param name which bone to access * @return the pre-existing instance, or null if not found */ public Bone getBone(String name){ return skeleton.getBone(name); } /**
/** * 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); } } } }
/** * 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()]); }
/** * 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); } } } }
/** * Access the named bone. * * @param name which bone to access * @return the pre-existing instance, or null if not found */ public Bone getBone(String name){ return skeleton.getBone(name); } /**
/** * Access the attachments node of the named bone. If the bone doesn't * already have an attachments node, create one and attach it to the scene * graph. Models and effects attached to the attachments node will follow * the bone's motions. * * @param boneName the name of the bone * @return the attachments node of the bone */ public Node getAttachmentsNode(String boneName) { Bone b = skeleton.getBone(boneName); if (b == null) { throw new IllegalArgumentException("Given bone name does not exist " + "in the skeleton."); } updateTargetsAndMaterials(spatial); int boneIndex = skeleton.getBoneIndex(b); Node n = b.getAttachmentsNode(boneIndex, targets); /* * Select a node to parent the attachments node. */ Node parent; if (spatial instanceof Node) { parent = (Node) spatial; // the usual case } else { parent = spatial.getParent(); } parent.attachChild(n); return n; }
@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); } } } }
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; }
/** * Add a single bone to be influenced by this animation channel. */ public void addBone(String name) { addBone(control.getSkeleton().getBone(name)); }
/** * 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(); }
/** * Add bones to be influenced by this animation channel starting from the * given bone name and going toward the root bone. */ public void addToRootBone(String name) { addToRootBone(control.getSkeleton().getBone(name)); }
/** * The method updates the geometry according to the positions 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(); } }
/** * Add bones to be influenced by this animation channel, starting * from the given named bone and going toward its children. */ public void addFromRootBone(String name) { addFromRootBone(control.getSkeleton().getBone(name)); }
@Override public void visit(Spatial spatial) { SkeletonControl control = spatial.getControl(SkeletonControl.class); if (control != null) { Armature armature = skeletonArmatureMap.get(control.getSkeleton()); SkinningControl skinningControl = new SkinningControl(armature); Map<String, List<Spatial>> attachedSpatials = new HashMap<>(); for (int i = 0; i < control.getSkeleton().getBoneCount(); i++) { Bone b = control.getSkeleton().getBone(i); Node n = control.getAttachmentsNode(b.getName()); n.removeFromParent(); if (!n.getChildren().isEmpty()) { attachedSpatials.put(b.getName(), n.getChildren()); } } spatial.removeControl(control); spatial.addControl(skinningControl); for (String name : attachedSpatials.keySet()) { List<Spatial> spatials = attachedSpatials.get(name); for (Spatial child : spatials) { skinningControl.getAttachmentsNode(name).attachChild(child); } } } }
/** * @return the target feature; it is either Node or Bone (vertex group subtarger is not yet supported) */ private Object getTarget() { Object target = blenderContext.getLoadedFeature(targetOMA, LoadedDataType.FEATURE); if (subtargetName != null && blenderContext.getMarkerValue(ObjectHelper.ARMATURE_NODE_MARKER, target) != null) { Skeleton skeleton = blenderContext.getSkeleton(targetOMA); target = skeleton.getBone(subtargetName); } return target; }
Bone bone = skeleton.getBone(i); boneStartTransforms.put(bone, new Transform(bone.getBindPosition(), bone.getBindRotation(), bone.getBindScale()));
private void setupAnimationController() { animationControl = model.getControl(AnimControl.class); animationControl.addListener(this); animationChannel = animationControl.createChannel(); shootingChannel = animationControl.createChannel(); shootingChannel.addBone(animationControl.getSkeleton().getBone("uparm.right")); shootingChannel.addBone(animationControl.getSkeleton().getBone("arm.right")); shootingChannel.addBone(animationControl.getSkeleton().getBone("hand.right")); }
/** * 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 parentTail = bone.getModelSpacePosition().add(bone.getModelSpaceRotation().mult(Vector3f.UNIT_Y.mult(boneLengths.get(i)))); for (Bone child : bone.getChildren()) { Vector3f childHead = child.getModelSpacePosition(); Vector3f v = childHead.subtract(parentTail); float pointDelta = v.length() / POINT_AMOUNT; v.normalizeLocal().multLocal(pointDelta); Vector3f pointPosition = parentTail.clone(); for (int j = 0; j < POINT_AMOUNT; ++j) { posBuf.put(pointPosition.getX()).put(pointPosition.getY()).put(pointPosition.getZ()); pointPosition.addLocal(v); } } } posBuf.flip(); vb.updateData(posBuf); this.updateBound(); }
@Override public void simpleUpdate(float tpf){ Bone b = control.getSkeleton().getBone("spinehigh"); Bone b2 = control.getSkeleton().getBone("uparm.left"); angle += tpf * rate; if (angle > FastMath.HALF_PI / 2f){ angle = FastMath.HALF_PI / 2f; rate = -1; }else if (angle < -FastMath.HALF_PI / 2f){ angle = -FastMath.HALF_PI / 2f; rate = 1; } Quaternion q = new Quaternion(); q.fromAngles(0, angle, 0); b.setUserControl(true); b.setUserTransforms(Vector3f.ZERO, q, Vector3f.UNIT_XYZ); b2.setUserControl(true); b2.setUserTransforms(Vector3f.ZERO, Quaternion.IDENTITY, new Vector3f(1+angle,1+ angle, 1+angle)); }