From 8cf0f1a4d5783170d81849dc7f46fad8f4725639 Mon Sep 17 00:00:00 2001 From: Nehon Date: Mon, 25 Dec 2017 15:09:55 +0100 Subject: [PATCH] Added a way to toggle on/off the non deforming bones in the Armature debugger --- .../src/main/java/com/jme3/anim/Armature.java | 9 +++-- .../debug/custom/ArmatureDebugAppState.java | 38 +++++++++++++++++-- .../scene/debug/custom/ArmatureDebugger.java | 27 ++++++++++--- .../jme3/scene/debug/custom/ArmatureNode.java | 27 ++++++++----- .../model/anim/TestAnimMigration.java | 15 ++++++-- 5 files changed, 91 insertions(+), 25 deletions(-) diff --git a/jme3-core/src/main/java/com/jme3/anim/Armature.java b/jme3-core/src/main/java/com/jme3/anim/Armature.java index 370618e7f..98b6299be 100644 --- a/jme3-core/src/main/java/com/jme3/anim/Armature.java +++ b/jme3-core/src/main/java/com/jme3/anim/Armature.java @@ -8,8 +8,7 @@ import com.jme3.util.clone.Cloner; import com.jme3.util.clone.JmeCloneable; import java.io.IOException; -import java.util.ArrayList; -import java.util.List; +import java.util.*; /** * Created by Nehon on 15/12/2017. @@ -104,7 +103,7 @@ public class Armature implements JmeCloneable, Savable { } /** - * returns the array of all root joints of this Armatire + * returns the array of all root joints of this Armature * * @return */ @@ -112,6 +111,10 @@ public class Armature implements JmeCloneable, Savable { return rootJoints; } + public List getJointList() { + return Arrays.asList(jointList); + } + /** * return a joint for the given index * diff --git a/jme3-core/src/main/java/com/jme3/scene/debug/custom/ArmatureDebugAppState.java b/jme3-core/src/main/java/com/jme3/scene/debug/custom/ArmatureDebugAppState.java index 47b78c1c1..10bef21ec 100644 --- a/jme3-core/src/main/java/com/jme3/scene/debug/custom/ArmatureDebugAppState.java +++ b/jme3-core/src/main/java/com/jme3/scene/debug/custom/ArmatureDebugAppState.java @@ -8,9 +8,9 @@ import com.jme3.anim.*; import com.jme3.app.Application; import com.jme3.app.state.BaseAppState; import com.jme3.collision.CollisionResults; +import com.jme3.input.KeyInput; import com.jme3.input.MouseInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.MouseButtonTrigger; +import com.jme3.input.controls.*; import com.jme3.light.DirectionalLight; import com.jme3.math.*; import com.jme3.renderer.ViewPort; @@ -27,6 +27,7 @@ public class ArmatureDebugAppState extends BaseAppState { private Map armatures = new HashMap<>(); private Map selectedBones = new HashMap<>(); private Application app; + private boolean displayAllJoints = false; ViewPort vp; @Override @@ -38,8 +39,9 @@ public class ArmatureDebugAppState extends BaseAppState { for (ArmatureDebugger armatureDebugger : armatures.values()) { armatureDebugger.initialize(app.getAssetManager()); } - app.getInputManager().addListener(actionListener, "shoot"); + app.getInputManager().addListener(actionListener, "shoot", "toggleJoints"); app.getInputManager().addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT), new MouseButtonTrigger(MouseInput.BUTTON_RIGHT)); + app.getInputManager().addMapping("toggleJoints", new KeyTrigger(KeyInput.KEY_F10)); debugNode.addLight(new DirectionalLight(new Vector3f(-1f, -1f, -1f).normalizeLocal())); @@ -76,7 +78,10 @@ public class ArmatureDebugAppState extends BaseAppState { public ArmatureDebugger addArmatureFrom(Armature armature, Spatial forSpatial) { - ArmatureDebugger ad = new ArmatureDebugger(forSpatial.getName() + "_Armature", armature); + JointInfoVisitor visitor = new JointInfoVisitor(armature); + forSpatial.depthFirstTraversal(visitor); + + ArmatureDebugger ad = new ArmatureDebugger(forSpatial.getName() + "_Armature", armature, visitor.deformingJoints); ad.setLocalTransform(forSpatial.getWorldTransform()); if (forSpatial instanceof Node) { List geoms = new ArrayList<>(); @@ -149,6 +154,12 @@ public class ArmatureDebugAppState extends BaseAppState { } } } + if (name.equals("toggleJoints") && isPressed) { + displayAllJoints = !displayAllJoints; + for (ArmatureDebugger ad : armatures.values()) { + ad.displayNonDeformingJoint(displayAllJoints); + } + } } }; @@ -163,4 +174,23 @@ public class ArmatureDebugAppState extends BaseAppState { public void setDebugNode(Node debugNode) { this.debugNode = debugNode; } + + private class JointInfoVisitor extends SceneGraphVisitorAdapter { + + List deformingJoints = new ArrayList<>(); + Armature armature; + + public JointInfoVisitor(Armature armature) { + this.armature = armature; + } + + @Override + public void visit(Geometry g) { + for (Joint joint : armature.getJointList()) { + if (g.getMesh().isAnimatedByJoint(armature.getJointIndex(joint))) { + deformingJoints.add(joint); + } + } + } + } } diff --git a/jme3-core/src/main/java/com/jme3/scene/debug/custom/ArmatureDebugger.java b/jme3-core/src/main/java/com/jme3/scene/debug/custom/ArmatureDebugger.java index 43a4e41d7..aec5f532e 100644 --- a/jme3-core/src/main/java/com/jme3/scene/debug/custom/ArmatureDebugger.java +++ b/jme3-core/src/main/java/com/jme3/scene/debug/custom/ArmatureDebugger.java @@ -60,9 +60,10 @@ public class ArmatureDebugger extends Node { private Armature armature; - Node joints; - Node outlines; - Node wires; + private Node joints; + private Node outlines; + private Node wires; + private List deformingJoints; /** * The dotted lines between a bone's tail and the had of its children. Not @@ -83,28 +84,42 @@ public class ArmatureDebugger extends Node { * @param name the name of the debugger's node * @param armature the armature that will be shown */ - public ArmatureDebugger(String name, Armature armature) { + public ArmatureDebugger(String name, Armature armature, List deformingJoints) { super(name); + this.deformingJoints = deformingJoints; this.armature = armature; armature.update(); - joints = new Node("joints"); outlines = new Node("outlines"); wires = new Node("bones"); this.attachChild(joints); this.attachChild(outlines); this.attachChild(wires); + Node ndJoints = new Node("non deforming Joints"); + Node ndOutlines = new Node("non deforming Joints outlines"); + Node ndWires = new Node("non deforming Joints wires"); + joints.attachChild(ndJoints); + outlines.attachChild(ndOutlines); + wires.attachChild(ndWires); + - armatureNode = new ArmatureNode(armature, joints, wires, outlines); + armatureNode = new ArmatureNode(armature, joints, wires, outlines, deformingJoints); this.attachChild(armatureNode); + displayNonDeformingJoint(false); //interJointWires = new ArmatureInterJointsWire(armature, bonesLength, guessJointsOrientation); //wires = new Geometry(name + "_interwires", interJointWires); // this.attachChild(wires); } + public void displayNonDeformingJoint(boolean display) { + joints.getChild(0).setCullHint(display ? CullHint.Dynamic : CullHint.Always); + outlines.getChild(0).setCullHint(display ? CullHint.Dynamic : CullHint.Always); + wires.getChild(0).setCullHint(display ? CullHint.Dynamic : CullHint.Always); + } + protected void initialize(AssetManager assetManager) { Material matWires = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); matWires.setBoolean("VertexColor", true); diff --git a/jme3-core/src/main/java/com/jme3/scene/debug/custom/ArmatureNode.java b/jme3-core/src/main/java/com/jme3/scene/debug/custom/ArmatureNode.java index 2b717adfd..258eb4834 100644 --- a/jme3-core/src/main/java/com/jme3/scene/debug/custom/ArmatureNode.java +++ b/jme3-core/src/main/java/com/jme3/scene/debug/custom/ArmatureNode.java @@ -41,8 +41,7 @@ import com.jme3.scene.*; import com.jme3.scene.shape.Line; import java.nio.FloatBuffer; -import java.util.HashMap; -import java.util.Map; +import java.util.*; /** * The class that displays either wires between the bones' heads if no length @@ -74,17 +73,17 @@ public class ArmatureNode extends Node { * * @param armature the armature that will be shown */ - public ArmatureNode(Armature armature, Node joints, Node wires, Node outlines) { + public ArmatureNode(Armature armature, Node joints, Node wires, Node outlines, List deformingJoints) { this.armature = armature; for (Joint joint : armature.getRoots()) { - createSkeletonGeoms(joint, joints, wires, outlines); + createSkeletonGeoms(joint, joints, wires, outlines, deformingJoints); } this.updateModelBound(); } - protected final void createSkeletonGeoms(Joint joint, Node joints, Node wires, Node outlines) { + protected final void createSkeletonGeoms(Joint joint, Node joints, Node wires, Node outlines, List deformingJoints) { Vector3f start = joint.getModelTransform().getTranslation().clone(); Vector3f end = null; @@ -93,9 +92,11 @@ public class ArmatureNode extends Node { end = joint.getChildren().get(0).getModelTransform().getTranslation().clone(); } + boolean deforms = deformingJoints.contains(joint); + Geometry jGeom = new Geometry(joint.getName() + "Joint", new JointShape()); jGeom.setLocalTranslation(start); - joints.attachChild(jGeom); + attach(joints, deforms, jGeom); Geometry bGeom = null; Geometry bGeomO = null; if (end != null) { @@ -107,14 +108,22 @@ public class ArmatureNode extends Node { bGeom.setUserData("start", wires.getWorldTransform().transformVector(start, start)); bGeom.setUserData("end", wires.getWorldTransform().transformVector(end, end)); bGeom.setQueueBucket(RenderQueue.Bucket.Transparent); - wires.attachChild(bGeom); - outlines.attachChild(bGeomO); + attach(wires, deforms, bGeom); + attach(outlines, deforms, bGeomO); } jointToGeoms.put(joint, new Geometry[]{jGeom, bGeom, bGeomO}); for (Joint child : joint.getChildren()) { - createSkeletonGeoms(child, joints, wires, outlines); + createSkeletonGeoms(child, joints, wires, outlines, deformingJoints); + } + } + + private void attach(Node parent, boolean deforms, Geometry geom) { + if (deforms) { + parent.attachChild(geom); + } else { + ((Node) parent.getChild(0)).attachChild(geom); } } diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestAnimMigration.java b/jme3-examples/src/main/java/jme3test/model/anim/TestAnimMigration.java index 1525165ad..df4aa4eb8 100644 --- a/jme3-examples/src/main/java/jme3test/model/anim/TestAnimMigration.java +++ b/jme3-examples/src/main/java/jme3test/model/anim/TestAnimMigration.java @@ -41,9 +41,9 @@ public class TestAnimMigration extends SimpleApplication { rootNode.addLight(new DirectionalLight(new Vector3f(-1, -1, -1).normalizeLocal())); rootNode.addLight(new AmbientLight(ColorRGBA.DarkGray)); - //Spatial model = assetManager.loadModel("Models/Jaime/Jaime.j3o"); + Spatial model = assetManager.loadModel("Models/Jaime/Jaime.j3o"); //Spatial model = assetManager.loadModel("Models/Oto/Oto.mesh.xml"); - Spatial model = assetManager.loadModel("Models/Sinbad/Sinbad.mesh.xml"); + //Spatial model = assetManager.loadModel("Models/Sinbad/Sinbad.mesh.xml"); //Spatial model = assetManager.loadModel("Models/Elephant/Elephant.mesh.xml"); AnimMigrationUtils.migrate(model); @@ -52,7 +52,7 @@ public class TestAnimMigration extends SimpleApplication { debugAppState = new ArmatureDebugAppState(); - //stateManager.attach(debugAppState); + stateManager.attach(debugAppState); setupModel(model); @@ -108,6 +108,15 @@ public class TestAnimMigration extends SimpleApplication { } } }, "nextAnim"); + inputManager.addMapping("toggleArmature", new KeyTrigger(KeyInput.KEY_SPACE)); + inputManager.addListener(new ActionListener() { + @Override + public void onAction(String name, boolean isPressed, float tpf) { + if (isPressed) { + debugAppState.setEnabled(!debugAppState.isEnabled()); + } + } + }, "toggleArmature"); } private void setupModel(Spatial model) {