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 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<Joint> getJointList() {
return Arrays.asList(jointList);
}
/**
* return a joint for the given index
*

@ -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<Armature, ArmatureDebugger> armatures = new HashMap<>();
private Map<Armature, Joint> 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<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) {
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;
Node joints;
Node outlines;
Node wires;
private Node joints;
private Node outlines;
private Node wires;
private List<Joint> 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<Joint> 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);

@ -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<Joint> 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<Joint> 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);
}
}

@ -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) {

Loading…
Cancel
Save