diff --git a/Minie/src/main/java/com/jme3/bullet/control/KinematicRagdollControl.java b/Minie/src/main/java/com/jme3/bullet/control/KinematicRagdollControl.java index 74ae7f1da..1a0ee1828 100644 --- a/Minie/src/main/java/com/jme3/bullet/control/KinematicRagdollControl.java +++ b/Minie/src/main/java/com/jme3/bullet/control/KinematicRagdollControl.java @@ -652,15 +652,10 @@ public void addBoneName(String boneName) { * Generate physics shapes and bone links for the skeleton. */ protected void scanSpatial() { - Map> pointsMap = null; - if (weightThreshold == -1f) { - pointsMap = RagdollUtils.buildPointMap(modelRoot); - } - skeleton.resetAndUpdate(); for (Bone rootBone : skeleton.getRoots()) { logger.log(Level.FINE, "Found root bone in skeleton {0}", skeleton); - boneRecursion(rootBone, baseRigidBody, 1, pointsMap); + boneRecursion(rootBone, baseRigidBody, 1); } } @@ -671,10 +666,9 @@ protected void scanSpatial() { * @param bone the bone to be linked (not null) * @param parent the body linked to the parent bone (not null) * @param reccount depth of the recursion (≥1) - * @param pointsMap (not null) */ protected void boneRecursion(Bone bone, PhysicsRigidBody parent, - int reccount, Map> pointsMap) { + int reccount) { PhysicsRigidBody parentShape = parent; String boneName = bone.getName(); if (jointMap.containsKey(boneName)) { @@ -683,15 +677,9 @@ protected void boneRecursion(Bone bone, PhysicsRigidBody parent, List boneIndices = RagdollUtils.getBoneIndices(bone, skeleton, jointMap.keySet()); Vector3f meshLocation = bone.getModelSpacePosition(); - if (pointsMap != null) { - // Build a shape for the bone, using the vertices most influenced by it. - shape = RagdollUtils.makeShapeFromPointMap(pointsMap, - boneIndices, initScale, meshLocation); - } else { - // Build a shape for the bone, using the vertices for which its weight exceeds the threshold. - shape = RagdollUtils.makeShapeFromVerticeWeights(modelRoot, - boneIndices, initScale, meshLocation, weightThreshold); - } + // Build a shape for the bone, using the vertices for which its weight exceeds the threshold. + shape = RagdollUtils.makeShapeFromVerticeWeights(modelRoot, + boneIndices, initScale, meshLocation, weightThreshold); float limbMass = torsoMass / (float) reccount; assert limbMass > 0f : limbMass; @@ -727,7 +715,7 @@ protected void boneRecursion(Bone bone, PhysicsRigidBody parent, } for (Bone childBone : bone.getChildren()) { - boneRecursion(childBone, parentShape, reccount + 1, pointsMap); + boneRecursion(childBone, parentShape, reccount + 1); } } diff --git a/Minie/src/main/java/com/jme3/bullet/control/ragdoll/RagdollUtils.java b/Minie/src/main/java/com/jme3/bullet/control/ragdoll/RagdollUtils.java index c70f08c69..14a162646 100644 --- a/Minie/src/main/java/com/jme3/bullet/control/ragdoll/RagdollUtils.java +++ b/Minie/src/main/java/com/jme3/bullet/control/ragdoll/RagdollUtils.java @@ -34,8 +34,10 @@ import com.jme3.animation.Bone; import com.jme3.animation.Skeleton; import com.jme3.animation.SkeletonControl; +import com.jme3.bullet.PhysicsSpace; import com.jme3.bullet.collision.shapes.HullCollisionShape; import com.jme3.bullet.joints.SixDofJoint; +import com.jme3.math.FastMath; import com.jme3.math.Quaternion; import com.jme3.math.Transform; import com.jme3.math.Vector3f; @@ -45,12 +47,11 @@ import java.nio.ByteBuffer; import java.nio.FloatBuffer; import java.util.ArrayList; -import java.util.HashMap; import java.util.LinkedList; import java.util.List; -import java.util.Map; import java.util.Set; import java.util.logging.Logger; +import jme3utilities.Validate; /** * Utility methods used by KinematicRagdollControl. @@ -84,111 +85,19 @@ private RagdollUtils() { */ public static void setJointLimit(SixDofJoint joint, float maxX, float minX, float maxY, float minY, float maxZ, float minZ) { - - joint.getRotationalLimitMotor(0).setHiLimit(maxX); - joint.getRotationalLimitMotor(0).setLoLimit(minX); - joint.getRotationalLimitMotor(1).setHiLimit(maxY); - joint.getRotationalLimitMotor(1).setLoLimit(minY); - joint.getRotationalLimitMotor(2).setHiLimit(maxZ); - joint.getRotationalLimitMotor(2).setLoLimit(minZ); - } - - /** - * Build a map of mesh vertices in a subtree of the scene graph. - * - * @param model the root of the subtree (may be null) - * @return a new map (not null) - */ - public static Map> buildPointMap(Spatial model) { - Map> map = new HashMap<>(); - - SkeletonControl skeletonCtrl = model.getControl(SkeletonControl.class); - Mesh[] targetMeshes = skeletonCtrl.getTargets(); - for (Mesh mesh : targetMeshes) { - buildPointMapForMesh(mesh, map); - } - - return map; - } - - private static Map> buildPointMapForMesh(Mesh mesh, - Map> map) { - FloatBuffer vertices = mesh.getFloatBuffer(Type.Position); - ByteBuffer boneIndices = (ByteBuffer) mesh.getBuffer(Type.BoneIndex).getData(); - FloatBuffer boneWeight = (FloatBuffer) mesh.getBuffer(Type.BoneWeight).getData(); - - vertices.rewind(); - boneIndices.rewind(); - boneWeight.rewind(); - - int vertexComponents = mesh.getVertexCount() * 3; - int k, start, index; - float maxWeight; - - for (int i = 0; i < vertexComponents; i += 3) { - start = i / 3 * 4; - index = 0; - maxWeight = -1; - for (k = start; k < start + 4; k++) { - float weight = boneWeight.get(k); - if (weight > maxWeight) { - maxWeight = weight; - index = boneIndices.get(k); - } - } - List points = map.get(index); - if (points == null) { - points = new ArrayList<>(); - map.put(index, points); - } - points.add(vertices.get(i)); - points.add(vertices.get(i + 1)); - points.add(vertices.get(i + 2)); - } - - return map; - } - - /** - * Create a hull collision shape from linked vertices to this bone. Vertices - * must have previously been gathered using buildPointMap(). - * - * @param pointsMap map from bone indices to coordinates (not null, - * unaffected) - * @param boneIndices (not null, unaffected) - * @param initialScale scale factors (not null, unaffected) - * @param initialPosition location (not null, unaffected) - * @return a new shape (not null) - */ - public static HullCollisionShape makeShapeFromPointMap( - Map> pointsMap, List boneIndices, - Vector3f initialScale, Vector3f initialPosition) { - - ArrayList points = new ArrayList<>(); - for (Integer index : boneIndices) { - List l = pointsMap.get(index); - if (l != null) { - - for (int i = 0; i < l.size(); i += 3) { - Vector3f pos = new Vector3f(); - pos.x = l.get(i); - pos.y = l.get(i + 1); - pos.z = l.get(i + 2); - pos.subtractLocal(initialPosition).multLocal(initialScale); - points.add(pos.x); - points.add(pos.y); - points.add(pos.z); - } - } - } - - assert !points.isEmpty(); - float[] p = new float[points.size()]; - for (int i = 0; i < points.size(); i++) { - p[i] = points.get(i); - } - - return new HullCollisionShape(p); + Validate.inRange(maxX, "max X rotation", minX, FastMath.PI); + Validate.inRange(minX, "min X rotation", -FastMath.PI, maxX); + Validate.inRange(maxY, "max Y rotation", minY, FastMath.PI); + Validate.inRange(minY, "min Y rotation", -FastMath.PI, maxY); + Validate.inRange(maxZ, "max Z rotation", minZ, FastMath.PI); + Validate.inRange(minZ, "min Z rotation", -FastMath.PI, maxZ); + + joint.getRotationalLimitMotor(PhysicsSpace.AXIS_X).setHiLimit(maxX); + joint.getRotationalLimitMotor(PhysicsSpace.AXIS_X).setLoLimit(minX); + joint.getRotationalLimitMotor(PhysicsSpace.AXIS_Y).setHiLimit(maxY); + joint.getRotationalLimitMotor(PhysicsSpace.AXIS_Y).setLoLimit(minY); + joint.getRotationalLimitMotor(PhysicsSpace.AXIS_Z).setHiLimit(maxZ); + joint.getRotationalLimitMotor(PhysicsSpace.AXIS_Z).setLoLimit(minZ); } /** @@ -203,13 +112,14 @@ public static HullCollisionShape makeShapeFromPointMap( public static List getBoneIndices(Bone bone, Skeleton skeleton, Set boneList) { List list = new LinkedList<>(); + 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)); + for (Bone child : bone.getChildren()) { + if (!boneList.contains(child.getName())) { + list.addAll(getBoneIndices(child, skeleton, boneList)); } } } @@ -321,11 +231,11 @@ private static List getPoints(Mesh mesh, int boneIndex, */ public static void setTransform(Bone bone, Vector3f pos, Quaternion rot, boolean restoreBoneControl, Set boneList) { - //we ensure that we have the control + // Ensure user control if (restoreBoneControl) { bone.setUserControl(true); } - //we set te user transforms of the bone + // Set the user transform of the bone. bone.setUserTransformsInModelSpace(pos, rot); for (Bone childBone : bone.getChildren()) { //each child bone that is not in the list is updated