From 8f21a7eb557ff8d0cd0c140ddd291fd0c61e7126 Mon Sep 17 00:00:00 2001 From: Stephen Gold Date: Thu, 4 Oct 2018 15:26:27 -0700 Subject: [PATCH] test and fix for issue #931 --- .../bullet/control/ragdoll/RagdollUtils.java | 50 +++++------- .../java/jme3test/bullet/TestIssue931.java | 76 +++++++++++++++++++ 2 files changed, 94 insertions(+), 32 deletions(-) create mode 100644 jme3-examples/src/main/java/jme3test/bullet/TestIssue931.java diff --git a/jme3-bullet/src/common/java/com/jme3/bullet/control/ragdoll/RagdollUtils.java b/jme3-bullet/src/common/java/com/jme3/bullet/control/ragdoll/RagdollUtils.java index 965bb9c7e..419c337bc 100644 --- a/jme3-bullet/src/common/java/com/jme3/bullet/control/ragdoll/RagdollUtils.java +++ b/jme3-bullet/src/common/java/com/jme3/bullet/control/ragdoll/RagdollUtils.java @@ -33,14 +33,13 @@ package com.jme3.bullet.control.ragdoll; import com.jme3.animation.Bone; import com.jme3.animation.Skeleton; +import com.jme3.animation.SkeletonControl; import com.jme3.bullet.collision.shapes.HullCollisionShape; import com.jme3.bullet.joints.SixDofJoint; import com.jme3.math.Quaternion; import com.jme3.math.Transform; import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; import com.jme3.scene.Mesh; -import com.jme3.scene.Node; import com.jme3.scene.Spatial; import com.jme3.scene.VertexBuffer.Type; import java.nio.ByteBuffer; @@ -90,21 +89,14 @@ public class RagdollUtils { * @return a new map (not null) */ public static Map> buildPointMap(Spatial model) { + Map> map = new HashMap<>(); - - Map> map = new HashMap>(); - if (model instanceof Geometry) { - Geometry g = (Geometry) model; - buildPointMapForMesh(g.getMesh(), map); - } else if (model instanceof Node) { - Node node = (Node) model; - for (Spatial s : node.getChildren()) { - if (s instanceof Geometry) { - Geometry g = (Geometry) s; - buildPointMapForMesh(g.getMesh(), map); - } - } + SkeletonControl skeletonCtrl = model.getControl(SkeletonControl.class); + Mesh[] targetMeshes = skeletonCtrl.getTargets(); + for (Mesh mesh : targetMeshes) { + buildPointMapForMesh(mesh, map); } + return map; } @@ -221,24 +213,18 @@ public class RagdollUtils { * @param weightThreshold minimum weight for inclusion * @return a new shape */ - public static HullCollisionShape makeShapeFromVerticeWeights(Spatial model, List boneIndices, Vector3f initialScale, Vector3f initialPosition, float weightThreshold) { - - ArrayList points = new ArrayList(); - if (model instanceof Geometry) { - Geometry g = (Geometry) model; + public static HullCollisionShape makeShapeFromVerticeWeights(Spatial model, + List boneIndices, Vector3f initialScale, + Vector3f initialPosition, float weightThreshold) { + List points = new ArrayList<>(100); + + SkeletonControl skeletonCtrl = model.getControl(SkeletonControl.class); + Mesh[] targetMeshes = skeletonCtrl.getTargets(); + for (Mesh mesh : targetMeshes) { for (Integer index : boneIndices) { - points.addAll(getPoints(g.getMesh(), index, initialScale, initialPosition, weightThreshold)); - } - } else if (model instanceof Node) { - Node node = (Node) model; - for (Spatial s : node.getChildren()) { - if (s instanceof Geometry) { - Geometry g = (Geometry) s; - for (Integer index : boneIndices) { - points.addAll(getPoints(g.getMesh(), index, initialScale, initialPosition, weightThreshold)); - } - - } + List bonePoints = getPoints(mesh, index, initialScale, + initialPosition, weightThreshold); + points.addAll(bonePoints); } } diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestIssue931.java b/jme3-examples/src/main/java/jme3test/bullet/TestIssue931.java new file mode 100644 index 000000000..63d56dd53 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/bullet/TestIssue931.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2018 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package jme3test.bullet; + +import com.jme3.app.SimpleApplication; +import com.jme3.bullet.BulletAppState; +import com.jme3.bullet.control.KinematicRagdollControl; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; + +/** + * Test case for JME issue #931: RagdollUtils can miss model meshes or use the + * non-animated ones. + *

+ * If successful, no AssertionError will be thrown. + */ +public class TestIssue931 extends SimpleApplication { + // ************************************************************************* + // new methods exposed + + public static void main(String[] args) { + TestIssue931 app = new TestIssue931(); + app.start(); + } + // ************************************************************************* + // SimpleApplication methods + + @Override + public void simpleInitApp() { + BulletAppState bulletAppState = new BulletAppState(); + stateManager.attach(bulletAppState); + String sinbadPath = "Models/Sinbad/SinbadOldAnim.j3o"; + Node sinbad = (Node) assetManager.loadModel(sinbadPath); + + Node extender = new Node(); + for (Spatial child : sinbad.getChildren()) { + extender.attachChild(child); + } + sinbad.attachChild(extender); + + //Note: PhysicsRagdollControl is still a WIP, constructor will change + KinematicRagdollControl ragdoll = new KinematicRagdollControl(0.5f); + sinbad.addControl(ragdoll); + + stop(); + } +}