Added a way to toggle on/off the non deforming bones in the Armature debugger

monkanim
Nehon 7 years ago
parent 1f3c0e4c84
commit 8cf0f1a4d5
  1. 9
      jme3-core/src/main/java/com/jme3/anim/Armature.java
  2. 38
      jme3-core/src/main/java/com/jme3/scene/debug/custom/ArmatureDebugAppState.java
  3. 27
      jme3-core/src/main/java/com/jme3/scene/debug/custom/ArmatureDebugger.java
  4. 27
      jme3-core/src/main/java/com/jme3/scene/debug/custom/ArmatureNode.java
  5. 15
      jme3-examples/src/main/java/jme3test/model/anim/TestAnimMigration.java

@ -8,8 +8,7 @@ import com.jme3.util.clone.Cloner;
import com.jme3.util.clone.JmeCloneable; import com.jme3.util.clone.JmeCloneable;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.*;
import java.util.List;
/** /**
* Created by Nehon on 15/12/2017. * 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 * @return
*/ */
@ -112,6 +111,10 @@ public class Armature implements JmeCloneable, Savable {
return rootJoints; return rootJoints;
} }
public List<Joint> getJointList() {
return Arrays.asList(jointList);
}
/** /**
* return a joint for the given index * return a joint for the given index
* *

@ -8,9 +8,9 @@ import com.jme3.anim.*;
import com.jme3.app.Application; import com.jme3.app.Application;
import com.jme3.app.state.BaseAppState; import com.jme3.app.state.BaseAppState;
import com.jme3.collision.CollisionResults; import com.jme3.collision.CollisionResults;
import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput; import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener; import com.jme3.input.controls.*;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.light.DirectionalLight; import com.jme3.light.DirectionalLight;
import com.jme3.math.*; import com.jme3.math.*;
import com.jme3.renderer.ViewPort; import com.jme3.renderer.ViewPort;
@ -27,6 +27,7 @@ public class ArmatureDebugAppState extends BaseAppState {
private Map<Armature, ArmatureDebugger> armatures = new HashMap<>(); private Map<Armature, ArmatureDebugger> armatures = new HashMap<>();
private Map<Armature, Joint> selectedBones = new HashMap<>(); private Map<Armature, Joint> selectedBones = new HashMap<>();
private Application app; private Application app;
private boolean displayAllJoints = false;
ViewPort vp; ViewPort vp;
@Override @Override
@ -38,8 +39,9 @@ public class ArmatureDebugAppState extends BaseAppState {
for (ArmatureDebugger armatureDebugger : armatures.values()) { for (ArmatureDebugger armatureDebugger : armatures.values()) {
armatureDebugger.initialize(app.getAssetManager()); 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("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())); 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) { 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()); ad.setLocalTransform(forSpatial.getWorldTransform());
if (forSpatial instanceof Node) { if (forSpatial instanceof Node) {
List<Geometry> geoms = new ArrayList<>(); List<Geometry> 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) { public void setDebugNode(Node debugNode) {
this.debugNode = debugNode; this.debugNode = debugNode;
} }
private class JointInfoVisitor extends SceneGraphVisitorAdapter {
List<Joint> 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);
}
}
}
}
} }

@ -60,9 +60,10 @@ public class ArmatureDebugger extends Node {
private Armature armature; private Armature armature;
Node joints; private Node joints;
Node outlines; private Node outlines;
Node wires; private Node wires;
private List<Joint> deformingJoints;
/** /**
* The dotted lines between a bone's tail and the had of its children. Not * 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 name the name of the debugger's node
* @param armature the armature that will be shown * @param armature the armature that will be shown
*/ */
public ArmatureDebugger(String name, Armature armature) { public ArmatureDebugger(String name, Armature armature, List<Joint> deformingJoints) {
super(name); super(name);
this.deformingJoints = deformingJoints;
this.armature = armature; this.armature = armature;
armature.update(); armature.update();
joints = new Node("joints"); joints = new Node("joints");
outlines = new Node("outlines"); outlines = new Node("outlines");
wires = new Node("bones"); wires = new Node("bones");
this.attachChild(joints); this.attachChild(joints);
this.attachChild(outlines); this.attachChild(outlines);
this.attachChild(wires); 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); this.attachChild(armatureNode);
displayNonDeformingJoint(false);
//interJointWires = new ArmatureInterJointsWire(armature, bonesLength, guessJointsOrientation); //interJointWires = new ArmatureInterJointsWire(armature, bonesLength, guessJointsOrientation);
//wires = new Geometry(name + "_interwires", interJointWires); //wires = new Geometry(name + "_interwires", interJointWires);
// this.attachChild(wires); // 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) { protected void initialize(AssetManager assetManager) {
Material matWires = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); Material matWires = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
matWires.setBoolean("VertexColor", true); matWires.setBoolean("VertexColor", true);

@ -41,8 +41,7 @@ import com.jme3.scene.*;
import com.jme3.scene.shape.Line; import com.jme3.scene.shape.Line;
import java.nio.FloatBuffer; import java.nio.FloatBuffer;
import java.util.HashMap; import java.util.*;
import java.util.Map;
/** /**
* The class that displays either wires between the bones' heads if no length * 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 * @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<Joint> deformingJoints) {
this.armature = armature; this.armature = armature;
for (Joint joint : armature.getRoots()) { for (Joint joint : armature.getRoots()) {
createSkeletonGeoms(joint, joints, wires, outlines); createSkeletonGeoms(joint, joints, wires, outlines, deformingJoints);
} }
this.updateModelBound(); 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<Joint> deformingJoints) {
Vector3f start = joint.getModelTransform().getTranslation().clone(); Vector3f start = joint.getModelTransform().getTranslation().clone();
Vector3f end = null; Vector3f end = null;
@ -93,9 +92,11 @@ public class ArmatureNode extends Node {
end = joint.getChildren().get(0).getModelTransform().getTranslation().clone(); end = joint.getChildren().get(0).getModelTransform().getTranslation().clone();
} }
boolean deforms = deformingJoints.contains(joint);
Geometry jGeom = new Geometry(joint.getName() + "Joint", new JointShape()); Geometry jGeom = new Geometry(joint.getName() + "Joint", new JointShape());
jGeom.setLocalTranslation(start); jGeom.setLocalTranslation(start);
joints.attachChild(jGeom); attach(joints, deforms, jGeom);
Geometry bGeom = null; Geometry bGeom = null;
Geometry bGeomO = null; Geometry bGeomO = null;
if (end != null) { if (end != null) {
@ -107,14 +108,22 @@ public class ArmatureNode extends Node {
bGeom.setUserData("start", wires.getWorldTransform().transformVector(start, start)); bGeom.setUserData("start", wires.getWorldTransform().transformVector(start, start));
bGeom.setUserData("end", wires.getWorldTransform().transformVector(end, end)); bGeom.setUserData("end", wires.getWorldTransform().transformVector(end, end));
bGeom.setQueueBucket(RenderQueue.Bucket.Transparent); bGeom.setQueueBucket(RenderQueue.Bucket.Transparent);
wires.attachChild(bGeom); attach(wires, deforms, bGeom);
outlines.attachChild(bGeomO); attach(outlines, deforms, bGeomO);
} }
jointToGeoms.put(joint, new Geometry[]{jGeom, bGeom, bGeomO}); jointToGeoms.put(joint, new Geometry[]{jGeom, bGeom, bGeomO});
for (Joint child : joint.getChildren()) { 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);
} }
} }

@ -41,9 +41,9 @@ public class TestAnimMigration extends SimpleApplication {
rootNode.addLight(new DirectionalLight(new Vector3f(-1, -1, -1).normalizeLocal())); rootNode.addLight(new DirectionalLight(new Vector3f(-1, -1, -1).normalizeLocal()));
rootNode.addLight(new AmbientLight(ColorRGBA.DarkGray)); 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/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"); //Spatial model = assetManager.loadModel("Models/Elephant/Elephant.mesh.xml");
AnimMigrationUtils.migrate(model); AnimMigrationUtils.migrate(model);
@ -52,7 +52,7 @@ public class TestAnimMigration extends SimpleApplication {
debugAppState = new ArmatureDebugAppState(); debugAppState = new ArmatureDebugAppState();
//stateManager.attach(debugAppState); stateManager.attach(debugAppState);
setupModel(model); setupModel(model);
@ -108,6 +108,15 @@ public class TestAnimMigration extends SimpleApplication {
} }
} }
}, "nextAnim"); }, "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) { private void setupModel(Spatial model) {

Loading…
Cancel
Save