Further Armature debugger enhancements

monkanim
Nehon 7 years ago
parent 8cf0f1a4d5
commit 8d39caec6a
  1. 21
      jme3-core/src/main/java/com/jme3/math/MathUtils.java
  2. 10
      jme3-core/src/main/java/com/jme3/scene/debug/custom/ArmatureDebugAppState.java
  3. 62
      jme3-core/src/main/java/com/jme3/scene/debug/custom/ArmatureDebugger.java
  4. 131
      jme3-core/src/main/java/com/jme3/scene/debug/custom/ArmatureInterJointsWire.java
  5. 130
      jme3-core/src/main/java/com/jme3/scene/debug/custom/ArmatureNode.java
  6. 59
      jme3-core/src/main/resources/Common/MatDefs/Misc/DashedLine.j3md
  7. 37
      jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Misc/Dashed.j3sn
  8. 10
      jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Misc/Dashed100.frag
  9. 30
      jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Misc/PerspectiveDivide.j3sn
  10. 3
      jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Misc/PerspectiveDivide100.frag
  11. 10
      jme3-examples/src/main/java/jme3test/model/anim/TestAnimMigration.java

@ -1,5 +1,6 @@
package com.jme3.math; package com.jme3.math;
import com.jme3.renderer.Camera;
import com.jme3.util.TempVars; import com.jme3.util.TempVars;
/** /**
@ -164,7 +165,19 @@ public class MathUtils {
} }
public static float raySegmentShortestDistance(Ray ray, Vector3f segStart, Vector3f segEnd) { /**
* Returns the shortest distance between a Ray and a segment.
* The segment is defined by a start position and an end position in world space
* The distance returned will be in world space (world units).
* If the camera parameter is not null the distance will be returned in screen space (pixels)
*
* @param ray The ray
* @param segStart The start position of the segment in world space
* @param segEnd The end position of the segment in world space
* @param camera The renderer camera if the distance is required in screen space. Null if the distance is required in world space
* @return the shortest distance between the ray and the segment or -1 if no solution is found.
*/
public static float raySegmentShortestDistance(Ray ray, Vector3f segStart, Vector3f segEnd, Camera camera) {
// Algorithm is ported from the C algorithm of // Algorithm is ported from the C algorithm of
// Paul Bourke at http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline3d/ // Paul Bourke at http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline3d/
TempVars vars = TempVars.get(); TempVars vars = TempVars.get();
@ -220,6 +233,12 @@ public class MathUtils {
return -1; return -1;
} }
if (camera != null) {
//camera is not null let's convert the points in screen space
camera.getScreenCoordinates(resultSegmentPoint1, resultSegmentPoint1);
camera.getScreenCoordinates(resultSegmentPoint2, resultSegmentPoint2);
}
float length = resultSegmentPoint1.subtractLocal(resultSegmentPoint2).length(); float length = resultSegmentPoint1.subtractLocal(resultSegmentPoint2).length();
vars.release(); vars.release();
return length; return length;

@ -37,7 +37,7 @@ public class ArmatureDebugAppState extends BaseAppState {
vp.setClearDepth(true); vp.setClearDepth(true);
this.app = app; this.app = app;
for (ArmatureDebugger armatureDebugger : armatures.values()) { for (ArmatureDebugger armatureDebugger : armatures.values()) {
armatureDebugger.initialize(app.getAssetManager()); armatureDebugger.initialize(app.getAssetManager(), app.getCamera());
} }
app.getInputManager().addListener(actionListener, "shoot", "toggleJoints"); 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));
@ -93,7 +93,7 @@ public class ArmatureDebugAppState extends BaseAppState {
armatures.put(armature, ad); armatures.put(armature, ad);
debugNode.attachChild(ad); debugNode.attachChild(ad);
if (isInitialized()) { if (isInitialized()) {
ad.initialize(app.getAssetManager()); ad.initialize(app.getAssetManager(), app.getCamera());
} }
return ad; return ad;
} }
@ -108,12 +108,6 @@ public class ArmatureDebugAppState extends BaseAppState {
} }
} }
/**
* Pick a Target Using the Mouse Pointer. <ol><li>Map "pick target" action
* to a MouseButtonTrigger. <li>flyCam.setEnabled(false);
* <li>inputManager.setCursorVisible(true); <li>Implement action in
* AnalogListener (TODO).</ol>
*/
private ActionListener actionListener = new ActionListener() { private ActionListener actionListener = new ActionListener() {
public void onAction(String name, boolean isPressed, float tpf) { public void onAction(String name, boolean isPressed, float tpf) {
if (name.equals("shoot") && isPressed) { if (name.equals("shoot") && isPressed) {

@ -34,16 +34,17 @@ package com.jme3.scene.debug.custom;
import com.jme3.anim.Armature; import com.jme3.anim.Armature;
import com.jme3.anim.Joint; import com.jme3.anim.Joint;
import com.jme3.animation.Bone;
import com.jme3.asset.AssetManager; import com.jme3.asset.AssetManager;
import com.jme3.collision.Collidable;
import com.jme3.collision.CollisionResults;
import com.jme3.material.Material; import com.jme3.material.Material;
import com.jme3.material.RenderState; import com.jme3.material.RenderState;
import com.jme3.renderer.Camera;
import com.jme3.renderer.queue.RenderQueue; import com.jme3.renderer.queue.RenderQueue;
import com.jme3.scene.Geometry; import com.jme3.scene.Geometry;
import com.jme3.scene.Node; import com.jme3.scene.Node;
import com.jme3.texture.Texture; import com.jme3.texture.Texture;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
@ -63,15 +64,11 @@ public class ArmatureDebugger extends Node {
private Node joints; private Node joints;
private Node outlines; private Node outlines;
private 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
* available if the length data was not provided. * available if the length data was not provided.
*/ */
private ArmatureInterJointsWire interJointWires; private ArmatureInterJointsWire interJointWires;
//private Geometry wires;
private List<Bone> selectedJoints = new ArrayList<Bone>();
public ArmatureDebugger() { public ArmatureDebugger() {
} }
@ -86,7 +83,6 @@ public class ArmatureDebugger extends Node {
*/ */
public ArmatureDebugger(String name, Armature armature, List<Joint> deformingJoints) { 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();
@ -102,25 +98,40 @@ public class ArmatureDebugger extends Node {
joints.attachChild(ndJoints); joints.attachChild(ndJoints);
outlines.attachChild(ndOutlines); outlines.attachChild(ndOutlines);
wires.attachChild(ndWires); wires.attachChild(ndWires);
Node outlineDashed = new Node("Outlines Dashed");
Node wiresDashed = new Node("Wires Dashed");
wiresDashed.attachChild(new Node("dashed non defrom"));
outlineDashed.attachChild(new Node("dashed non defrom"));
outlines.attachChild(outlineDashed);
wires.attachChild(wiresDashed);
armatureNode = new ArmatureNode(armature, joints, wires, outlines, deformingJoints); armatureNode = new ArmatureNode(armature, joints, wires, outlines, deformingJoints);
this.attachChild(armatureNode); this.attachChild(armatureNode);
displayNonDeformingJoint(false); displayNonDeformingJoint(false);
//interJointWires = new ArmatureInterJointsWire(armature, bonesLength, guessJointsOrientation);
//wires = new Geometry(name + "_interwires", interJointWires);
// this.attachChild(wires);
} }
public void displayNonDeformingJoint(boolean display) { public void displayNonDeformingJoint(boolean display) {
joints.getChild(0).setCullHint(display ? CullHint.Dynamic : CullHint.Always); joints.getChild(0).setCullHint(display ? CullHint.Dynamic : CullHint.Always);
outlines.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); wires.getChild(0).setCullHint(display ? CullHint.Dynamic : CullHint.Always);
((Node) outlines.getChild(1)).getChild(0).setCullHint(display ? CullHint.Dynamic : CullHint.Always);
((Node) wires.getChild(1)).getChild(0).setCullHint(display ? CullHint.Dynamic : CullHint.Always);
} }
protected void initialize(AssetManager assetManager) { protected void initialize(AssetManager assetManager, Camera camera) {
armatureNode.setCamera(camera);
Material matJoints = new Material(assetManager, "Common/MatDefs/Misc/Billboard.j3md");
Texture t = assetManager.loadTexture("Common/Textures/dot.png");
matJoints.setTexture("Texture", t);
matJoints.getAdditionalRenderState().setDepthTest(false);
matJoints.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
joints.setQueueBucket(RenderQueue.Bucket.Translucent);
joints.setMaterial(matJoints);
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);
matWires.getAdditionalRenderState().setLineWidth(3); matWires.getAdditionalRenderState().setLineWidth(3);
@ -128,19 +139,16 @@ public class ArmatureDebugger extends Node {
Material matOutline = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); Material matOutline = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
matOutline.setBoolean("VertexColor", true); matOutline.setBoolean("VertexColor", true);
//matOutline.setColor("Color", ColorRGBA.White);
matOutline.getAdditionalRenderState().setLineWidth(5); matOutline.getAdditionalRenderState().setLineWidth(5);
outlines.setMaterial(matOutline); outlines.setMaterial(matOutline);
Material matJoints = new Material(assetManager, "Common/MatDefs/Misc/Billboard.j3md"); Material matOutline2 = new Material(assetManager, "Common/MatDefs/Misc/DashedLine.j3md");
Texture t = assetManager.loadTexture("Common/Textures/dot.png"); matOutline2.getAdditionalRenderState().setLineWidth(1);
// matJoints.setBoolean("VertexColor", true); outlines.getChild(1).setMaterial(matOutline2);
// matJoints.setTexture("ColorMap", t);
matJoints.setTexture("Texture", t); Material matWires2 = new Material(assetManager, "Common/MatDefs/Misc/DashedLine.j3md");
matJoints.getAdditionalRenderState().setDepthTest(false); matWires2.getAdditionalRenderState().setLineWidth(1);
matJoints.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha); wires.getChild(1).setMaterial(matWires2);
joints.setQueueBucket(RenderQueue.Bucket.Translucent);
joints.setMaterial(matJoints);
} }
@ -152,9 +160,13 @@ public class ArmatureDebugger extends Node {
public void updateLogicalState(float tpf) { public void updateLogicalState(float tpf) {
super.updateLogicalState(tpf); super.updateLogicalState(tpf);
armatureNode.updateGeometry(); armatureNode.updateGeometry();
if (interJointWires != null) { }
// interJointWires.updateGeometry();
} @Override
public int collideWith(Collidable other, CollisionResults results) {
return armatureNode.collideWith(other, results);
} }
protected Joint select(Geometry g) { protected Joint select(Geometry g) {

@ -33,16 +33,12 @@ package com.jme3.scene.debug.custom;
*/ */
import com.jme3.anim.Armature;
import com.jme3.anim.Joint;
import com.jme3.math.Vector3f; import com.jme3.math.Vector3f;
import com.jme3.scene.Mesh; import com.jme3.scene.Mesh;
import com.jme3.scene.VertexBuffer; import com.jme3.scene.VertexBuffer;
import com.jme3.scene.VertexBuffer.*; import com.jme3.scene.VertexBuffer.Type;
import com.jme3.util.BufferUtils;
import java.nio.FloatBuffer; import java.nio.FloatBuffer;
import java.util.Map;
/** /**
* A class that displays a dotted line between a bone tail and its childrens' heads. * A class that displays a dotted line between a bone tail and its childrens' heads.
@ -50,90 +46,69 @@ import java.util.Map;
* @author Marcin Roguski (Kaelthas) * @author Marcin Roguski (Kaelthas)
*/ */
public class ArmatureInterJointsWire extends Mesh { public class ArmatureInterJointsWire extends Mesh {
private static final int POINT_AMOUNT = 50; private Vector3f tmp = new Vector3f();
/**
* The amount of connections between bones.
*/
private int connectionsAmount;
/**
* The armature that will be showed.
*/
private Armature armature;
/**
* The map between the bone index and its length.
*/
private Map<Integer, Float> boneLengths;
private boolean guessBonesOrientation = false;
/** public ArmatureInterJointsWire(Vector3f start, Vector3f[] ends) {
* Creates buffers for points. Each line has POINT_AMOUNT of points. setMode(Mode.Lines);
* updateGeometry(start, ends);
* @param armature the armature that will be showed }
* @param boneLengths the lengths of the bones
*/
public ArmatureInterJointsWire(Armature armature, Map<Integer, Float> boneLengths, boolean guessBonesOrientation) {
this.armature = armature;
for (Joint joint : armature.getRoots()) { protected void updateGeometry(Vector3f start, Vector3f[] ends) {
this.countConnections(joint); float[] pos = new float[ends.length * 3 + 3];
pos[0] = start.x;
pos[1] = start.y;
pos[2] = start.z;
int index;
for (int i = 0; i < ends.length; i++) {
index = i * 3 + 3;
pos[index] = ends[i].x;
pos[index + 1] = ends[i].y;
pos[index + 2] = ends[i].z;
} }
setBuffer(Type.Position, 3, pos);
this.setMode(Mode.Points); float[] texCoord = new float[ends.length * 2 + 2];
this.boneLengths = boneLengths; texCoord[0] = 0;
texCoord[1] = 0;
VertexBuffer pb = new VertexBuffer(Type.Position); for (int i = 0; i < ends.length * 2; i++) {
FloatBuffer fpb = BufferUtils.createFloatBuffer(POINT_AMOUNT * connectionsAmount * 3); texCoord[i + 2] = tmp.set(start).subtractLocal(ends[i / 2]).length();
pb.setupData(Usage.Stream, 3, Format.Float, fpb); }
this.setBuffer(pb); setBuffer(Type.TexCoord, 2, texCoord);
this.guessBonesOrientation = guessBonesOrientation; float[] normal = new float[ends.length * 3 + 3];
this.updateCounts(); for (int i = 0; i < ends.length * 3 + 3; i += 3) {
normal[i] = start.x;
normal[i + 1] = start.y;
normal[i + 2] = start.z;
}
setBuffer(Type.Normal, 3, normal);
short[] id = new short[ends.length * 2];
index = 1;
for (int i = 0; i < ends.length * 2; i += 2) {
id[i] = 0;
id[i + 1] = (short) (index);
index++;
}
setBuffer(Type.Index, 2, id);
updateBound();
} }
/** /**
* The method updates the geometry according to the positions of the bones. * Update the start and end points of the line.
*/ */
public void updateGeometry() { public void updatePoints(Vector3f start, Vector3f end) {
VertexBuffer vb = this.getBuffer(Type.Position); VertexBuffer posBuf = getBuffer(Type.Position);
FloatBuffer posBuf = this.getFloatBuffer(Type.Position);
posBuf.clear();
for (int i = 0; i < armature.getJointCount(); ++i) {
Joint joint = armature.getJoint(i);
Vector3f parentTail = joint.getModelTransform().getTranslation().add(joint.getModelTransform().getRotation().mult(Vector3f.UNIT_Y.mult(boneLengths.get(i))));
if (guessBonesOrientation) {
parentTail = joint.getModelTransform().getTranslation();
}
for (Joint child : joint.getChildren()) {
Vector3f childHead = child.getModelTransform().getTranslation();
Vector3f v = childHead.subtract(parentTail);
float len = v.length();
float pointDelta = 1f / POINT_AMOUNT;
v.normalizeLocal().multLocal(pointDelta);
Vector3f pointPosition = parentTail.clone();
for (int j = 0; j < POINT_AMOUNT * len; ++j) {
posBuf.put(pointPosition.getX()).put(pointPosition.getY()).put(pointPosition.getZ());
pointPosition.addLocal(v);
}
}
}
posBuf.flip();
vb.updateData(posBuf);
this.updateBound(); FloatBuffer fb = (FloatBuffer) posBuf.getData();
} fb.rewind();
fb.put(start.x).put(start.y).put(start.z);
fb.put(end.x).put(end.y).put(end.z);
/** posBuf.updateData(fb);
* Th method counts the connections between bones.
* updateBound();
* @param joint the bone where counting starts
*/
private void countConnections(Joint joint) {
for (Joint child : joint.getChildren()) {
++connectionsAmount;
this.countConnections(child);
}
} }
} }

@ -36,6 +36,7 @@ import com.jme3.anim.Armature;
import com.jme3.anim.Joint; import com.jme3.anim.Joint;
import com.jme3.collision.*; import com.jme3.collision.*;
import com.jme3.math.*; import com.jme3.math.*;
import com.jme3.renderer.Camera;
import com.jme3.renderer.queue.RenderQueue; import com.jme3.renderer.queue.RenderQueue;
import com.jme3.scene.*; import com.jme3.scene.*;
import com.jme3.scene.shape.Line; import com.jme3.scene.shape.Line;
@ -60,11 +61,13 @@ public class ArmatureNode extends Node {
private Map<Geometry, Joint> geomToJoint = new HashMap<>(); private Map<Geometry, Joint> geomToJoint = new HashMap<>();
private Joint selectedJoint = null; private Joint selectedJoint = null;
private Vector3f tmpStart = new Vector3f(); private Vector3f tmpStart = new Vector3f();
private Vector3f tmpEnd = new Vector3f(); private List<Vector3f> tmpEnds = new ArrayList<>();
ColorRGBA selectedColor = ColorRGBA.Orange; private final static ColorRGBA selectedColor = ColorRGBA.Orange;
ColorRGBA selectedColorJ = ColorRGBA.Yellow; private final static ColorRGBA selectedColorJ = ColorRGBA.Yellow;
;//new ColorRGBA(0.2f, 1f, 1.0f, 1.0f); private final static ColorRGBA outlineColor = ColorRGBA.LightGray;
ColorRGBA baseColor = new ColorRGBA(0.05f, 0.05f, 0.05f, 1f); private final static ColorRGBA baseColor = new ColorRGBA(0.05f, 0.05f, 0.05f, 1f);
private Camera camera;
/** /**
@ -85,11 +88,14 @@ public class ArmatureNode extends Node {
protected final void createSkeletonGeoms(Joint joint, Node joints, Node wires, Node outlines, List<Joint> deformingJoints) { 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;
//One child only, the bone direction is from the parent joint to the child joint. Vector3f[] ends = null;
if (joint.getChildren().size() == 1) { if (!joint.getChildren().isEmpty()) {
end = joint.getChildren().get(0).getModelTransform().getTranslation().clone(); ends = new Vector3f[joint.getChildren().size()];
}
for (int i = 0; i < joint.getChildren().size(); i++) {
ends[i] = joint.getChildren().get(i).getModelTransform().getTranslation().clone();
} }
boolean deforms = deformingJoints.contains(joint); boolean deforms = deformingJoints.contains(joint);
@ -99,19 +105,36 @@ public class ArmatureNode extends Node {
attach(joints, deforms, jGeom); attach(joints, deforms, jGeom);
Geometry bGeom = null; Geometry bGeom = null;
Geometry bGeomO = null; Geometry bGeomO = null;
if (end != null) { if (ends != null) {
bGeom = new Geometry(joint.getName() + "Bone", new Line(start, end)); Mesh m = null;
setColor(bGeom, baseColor); Mesh mO = null;
Node wireAttach = wires;
Node outlinesAttach = outlines;
if (ends.length == 1) {
m = new Line(start, ends[0]);
mO = new Line(start, ends[0]);
} else {
m = new ArmatureInterJointsWire(start, ends);
mO = new ArmatureInterJointsWire(start, ends);
wireAttach = (Node) wires.getChild(1);
outlinesAttach = null;
}
bGeom = new Geometry(joint.getName() + "Bone", m);
setColor(bGeom, outlinesAttach == null ? outlineColor : baseColor);
geomToJoint.put(bGeom, joint); geomToJoint.put(bGeom, joint);
bGeomO = new Geometry(joint.getName() + "BoneOutline", new Line(start, end)); bGeom.setUserData("start", getWorldTransform().transformVector(start, start));
setColor(bGeomO, ColorRGBA.White); for (int i = 0; i < ends.length; i++) {
bGeom.setUserData("start", wires.getWorldTransform().transformVector(start, start)); getWorldTransform().transformVector(ends[i], ends[i]);
bGeom.setUserData("end", wires.getWorldTransform().transformVector(end, end)); }
bGeom.setUserData("end", ends);
bGeom.setQueueBucket(RenderQueue.Bucket.Transparent); bGeom.setQueueBucket(RenderQueue.Bucket.Transparent);
attach(wires, deforms, bGeom); attach(wireAttach, deforms, bGeom);
attach(outlines, deforms, bGeomO); if (outlinesAttach != null) {
bGeomO = new Geometry(joint.getName() + "BoneOutline", mO);
setColor(bGeomO, outlineColor);
attach(outlinesAttach, 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()) {
@ -119,6 +142,10 @@ public class ArmatureNode extends Node {
} }
} }
public void setCamera(Camera camera) {
this.camera = camera;
}
private void attach(Node parent, boolean deforms, Geometry geom) { private void attach(Node parent, boolean deforms, Geometry geom) {
if (deforms) { if (deforms) {
parent.attachChild(geom); parent.attachChild(geom);
@ -142,7 +169,10 @@ public class ArmatureNode extends Node {
Geometry[] geomArray = jointToGeoms.get(selectedJoint); Geometry[] geomArray = jointToGeoms.get(selectedJoint);
setColor(geomArray[0], selectedColorJ); setColor(geomArray[0], selectedColorJ);
setColor(geomArray[1], selectedColor); setColor(geomArray[1], selectedColor);
setColor(geomArray[2], baseColor);
if (geomArray[2] != null) {
setColor(geomArray[2], baseColor);
}
return j; return j;
} }
return null; return null;
@ -154,8 +184,10 @@ public class ArmatureNode extends Node {
} }
Geometry[] geoms = jointToGeoms.get(selectedJoint); Geometry[] geoms = jointToGeoms.get(selectedJoint);
setColor(geoms[0], ColorRGBA.White); setColor(geoms[0], ColorRGBA.White);
setColor(geoms[1], baseColor); setColor(geoms[1], geoms[2] == null ? outlineColor : baseColor);
setColor(geoms[2], ColorRGBA.White); if (geoms[2] != null) {
setColor(geoms[2], outlineColor);
}
selectedJoint = null; selectedJoint = null;
} }
@ -171,20 +203,25 @@ public class ArmatureNode extends Node {
jGeom.setLocalTranslation(joint.getModelTransform().getTranslation()); jGeom.setLocalTranslation(joint.getModelTransform().getTranslation());
Geometry bGeom = geoms[1]; Geometry bGeom = geoms[1];
if (bGeom != null) { if (bGeom != null) {
tmpStart.set(joint.getModelTransform().getTranslation()); Vector3f start = bGeom.getUserData("start");
boolean hasEnd = false; Vector3f[] ends = bGeom.getUserData("end");
if (joint.getChildren().size() == 1) { start.set(joint.getModelTransform().getTranslation());
tmpEnd.set(joint.getChildren().get(0).getModelTransform().getTranslation()); if (ends != null) {
hasEnd = true; tmpEnds.clear();
} for (int i = 0; i < joint.getChildren().size(); i++) {
if (hasEnd) { ends[i].set(joint.getChildren().get(i).getModelTransform().getTranslation());
updateBoneMesh(bGeom); }
updateBoneMesh(bGeom, start, ends);
Geometry bGeomO = geoms[2]; Geometry bGeomO = geoms[2];
updateBoneMesh(bGeomO); if (bGeomO != null) {
Vector3f start = bGeom.getUserData("start"); updateBoneMesh(bGeomO, start, ends);
Vector3f end = bGeom.getUserData("end"); }
bGeom.setUserData("start", bGeom.getParent().getWorldTransform().transformVector(tmpStart, start)); bGeom.setUserData("start", getWorldTransform().transformVector(start, start));
bGeom.setUserData("end", bGeom.getParent().getWorldTransform().transformVector(tmpEnd, end)); for (int i = 0; i < ends.length; i++) {
getWorldTransform().transformVector(ends[i], ends[i]);
}
bGeom.setUserData("end", ends);
} }
} }
} }
@ -201,25 +238,28 @@ public class ArmatureNode extends Node {
} }
int nbCol = 0; int nbCol = 0;
for (Geometry g : geomToJoint.keySet()) { for (Geometry g : geomToJoint.keySet()) {
float len = MathUtils.raySegmentShortestDistance((Ray) other, (Vector3f) g.getUserData("start"), (Vector3f) g.getUserData("end")); Vector3f start = g.getUserData("start");
if (len > 0 && len < 0.1f) { Vector3f[] ends = g.getUserData("end");
CollisionResult res = new CollisionResult(); for (int i = 0; i < ends.length; i++) {
res.setGeometry(g); float len = MathUtils.raySegmentShortestDistance((Ray) other, start, ends[i], camera);
results.addCollision(res); if (len > 0 && len < 10f) {
nbCol++; CollisionResult res = new CollisionResult();
res.setGeometry(g);
results.addCollision(res);
nbCol++;
}
} }
} }
return nbCol; return nbCol;
} }
private void updateBoneMesh(Geometry bGeom) { private void updateBoneMesh(Geometry bGeom, Vector3f start, Vector3f[] ends) {
VertexBuffer pos = bGeom.getMesh().getBuffer(VertexBuffer.Type.Position); VertexBuffer pos = bGeom.getMesh().getBuffer(VertexBuffer.Type.Position);
FloatBuffer fb = (FloatBuffer) pos.getData(); FloatBuffer fb = (FloatBuffer) pos.getData();
fb.rewind(); fb.rewind();
fb.put(new float[]{tmpStart.x, tmpStart.y, tmpStart.z, fb.put(new float[]{start.x, start.y, start.z,
tmpEnd.x, tmpEnd.y, tmpEnd.z,}); ends[0].x, ends[0].y, ends[0].z,});
pos.updateData(fb); pos.updateData(fb);
bGeom.updateModelBound(); bGeom.updateModelBound();
} }

@ -0,0 +1,59 @@
MaterialDef DashedLine {
MaterialParameters {
}
Technique {
WorldParameters {
WorldViewProjectionMatrix
Resolution
}
VertexShaderNodes {
ShaderNode TransformPosition {
Definition: TransformPosition: Common/MatDefs/ShaderNodes/Basic/TransformPosition.j3sn
InputMappings {
transformsMatrix = WorldParam.WorldViewProjectionMatrix
inputPosition = Attr.inNormal
}
OutputMappings {
}
}
ShaderNode PerspectiveDivide {
Definition: PerspectiveDivide: Common/MatDefs/ShaderNodes/Misc/PerspectiveDivide.j3sn
InputMappings {
inVec = TransformPosition.outPosition
}
OutputMappings {
}
}
ShaderNode CommonVert {
Definition: CommonVert: Common/MatDefs/ShaderNodes/Common/CommonVert.j3sn
InputMappings {
worldViewProjectionMatrix = WorldParam.WorldViewProjectionMatrix
modelPosition = Attr.inPosition
vertColor = Attr.inColor
texCoord1 = Attr.inTexCoord
}
OutputMappings {
Global.position = projPosition
}
}
}
FragmentShaderNodes {
ShaderNode Dashed {
Definition: Dashed: Common/MatDefs/ShaderNodes/Misc/Dashed.j3sn
InputMappings {
texCoord = CommonVert.texCoord1
inColor = CommonVert.vertColor
resolution = WorldParam.Resolution
startPos = PerspectiveDivide.outVec
}
OutputMappings {
Global.color = outColor
}
}
}
}
}

@ -0,0 +1,37 @@
ShaderNodeDefinitions{
ShaderNodeDefinition Dashed {
//Vertex/Fragment
Type: Fragment
//Shader GLSL<version>: <Path to shader>
Shader GLSL100: Common/MatDefs/ShaderNodes/Misc/Dashed100.frag
Documentation{
//type documentation here. This is optional but recommended
Output a dashed line (better have a LINE mode mesh)
//@input <glsltype> <varName> <description>
@input vec2 texCoord the texture coordinates
@input vec4 inColor The input color
//@output <glslType> <varName> <description>
@output vec4 outColor The modified output color
}
Input {
//all the node inputs
//<glslType> <varName>
vec2 texCoord
vec4 inColor
vec4 startPos
vec2 resolution
}
Output {
//all the node outputs
//<glslType> <varName>
vec4 outColor
}
}
}

@ -0,0 +1,10 @@
void main(){
startPos.xy = (startPos * 0.5 + 0.5).xy * resolution;
float len = distance(gl_FragCoord.xy,startPos.xy);
outColor = inColor;
float factor = int(len * 0.25);
if(mod(factor, 2) > 0.0){
discard;
}
}

@ -0,0 +1,30 @@
ShaderNodeDefinitions{
ShaderNodeDefinition PerspectiveDivide {
//Vertex/Fragment
Type: Vertex
//Shader GLSL<version>: <Path to shader>
Shader GLSL100: Common/MatDefs/ShaderNodes/Misc/PerspectiveDivide100.frag
Documentation{
//type documentation here. This is optional but recommended
performs inVec.xyz / inVec.w
//@input <glsltype> <varName> <description>
@input vec4 inVec The input vector
//@output <glslType> <varName> <description>
@output vec4 outVec The modified output vector
}
Input {
//all the node inputs
//<glslType> <varName>
vec4 inVec
}
Output {
//all the node outputs
//<glslType> <varName>
vec4 outVec
}
}
}

@ -0,0 +1,3 @@
void main(){
outVec = vec4(inVec.xyz / inVec.w,1.0);
}

@ -26,7 +26,7 @@ public class TestAnimMigration extends SimpleApplication {
ArmatureDebugAppState debugAppState; ArmatureDebugAppState debugAppState;
AnimComposer composer; AnimComposer composer;
Queue<String> anims = new LinkedList<>(); Queue<String> anims = new LinkedList<>();
boolean playAnim = true; boolean playAnim = false;
public static void main(String... argv) { public static void main(String... argv) {
TestAnimMigration app = new TestAnimMigration(); TestAnimMigration app = new TestAnimMigration();
@ -36,15 +36,15 @@ public class TestAnimMigration extends SimpleApplication {
@Override @Override
public void simpleInitApp() { public void simpleInitApp() {
setTimer(new EraseTimer()); setTimer(new EraseTimer());
//cam.setFrustumPerspective(90f, (float) cam.getWidth() / cam.getHeight(), 0.01f, 10f); cam.setFrustumPerspective(45f, (float) cam.getWidth() / cam.getHeight(), 0.1f, 100f);
viewPort.setBackgroundColor(ColorRGBA.DarkGray); viewPort.setBackgroundColor(ColorRGBA.DarkGray);
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").scale(0.2f).move(0, 1, 0);
//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").scale(0.02f);
AnimMigrationUtils.migrate(model); AnimMigrationUtils.migrate(model);

Loading…
Cancel
Save