/** * 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<Integer, List<Float>> buildPointMap(Spatial model) { Map<Integer, List<Float>> map = new HashMap<>(); SkeletonControl skeletonCtrl = model.getControl(SkeletonControl.class); Mesh[] targetMeshes = skeletonCtrl.getTargets(); for (Mesh mesh : targetMeshes) { buildPointMapForMesh(mesh, map); } return map; }
/** * 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<Integer, List<Float>> buildPointMap(Spatial model) { Map<Integer, List<Float>> map = new HashMap<>(); SkeletonControl skeletonCtrl = model.getControl(SkeletonControl.class); Mesh[] targetMeshes = skeletonCtrl.getTargets(); for (Mesh mesh : targetMeshes) { buildPointMapForMesh(mesh, map); } return map; }
/** * Create a hull collision shape from linked vertices to this bone. * * @param model the model on which to base the shape * @param boneIndices indices of relevant bones (not null, unaffected) * @param initialScale scale factors * @param initialPosition location * @param weightThreshold minimum weight for inclusion * @return a new shape */ public static HullCollisionShape makeShapeFromVerticeWeights(Spatial model, List<Integer> boneIndices, Vector3f initialScale, Vector3f initialPosition, float weightThreshold) { List<Float> points = new ArrayList<>(100); SkeletonControl skeletonCtrl = model.getControl(SkeletonControl.class); Mesh[] targetMeshes = skeletonCtrl.getTargets(); for (Mesh mesh : targetMeshes) { for (Integer index : boneIndices) { List<Float> bonePoints = getPoints(mesh, index, initialScale, initialPosition, weightThreshold); points.addAll(bonePoints); } } 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); }
/** * Create a hull collision shape from linked vertices to this bone. * * @param model the model on which to base the shape * @param boneIndices indices of relevant bones (not null, unaffected) * @param initialScale scale factors * @param initialPosition location * @param weightThreshold minimum weight for inclusion * @return a new shape */ public static HullCollisionShape makeShapeFromVerticeWeights(Spatial model, List<Integer> boneIndices, Vector3f initialScale, Vector3f initialPosition, float weightThreshold) { List<Float> points = new ArrayList<>(100); SkeletonControl skeletonCtrl = model.getControl(SkeletonControl.class); Mesh[] targetMeshes = skeletonCtrl.getTargets(); for (Mesh mesh : targetMeshes) { for (Integer index : boneIndices) { List<Float> bonePoints = getPoints(mesh, index, initialScale, initialPosition, weightThreshold); points.addAll(bonePoints); } } 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); }
/** * 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 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); } } } }