Further Armature debugger enhancements
This commit is contained in:
parent
8cf0f1a4d5
commit
8d39caec6a
@ -1,5 +1,6 @@
|
||||
package com.jme3.math;
|
||||
|
||||
import com.jme3.renderer.Camera;
|
||||
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
|
||||
// Paul Bourke at http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline3d/
|
||||
TempVars vars = TempVars.get();
|
||||
@ -220,6 +233,12 @@ public class MathUtils {
|
||||
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();
|
||||
vars.release();
|
||||
return length;
|
||||
|
@ -37,7 +37,7 @@ public class ArmatureDebugAppState extends BaseAppState {
|
||||
vp.setClearDepth(true);
|
||||
this.app = app;
|
||||
for (ArmatureDebugger armatureDebugger : armatures.values()) {
|
||||
armatureDebugger.initialize(app.getAssetManager());
|
||||
armatureDebugger.initialize(app.getAssetManager(), app.getCamera());
|
||||
}
|
||||
app.getInputManager().addListener(actionListener, "shoot", "toggleJoints");
|
||||
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);
|
||||
debugNode.attachChild(ad);
|
||||
if (isInitialized()) {
|
||||
ad.initialize(app.getAssetManager());
|
||||
ad.initialize(app.getAssetManager(), app.getCamera());
|
||||
}
|
||||
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() {
|
||||
public void onAction(String name, boolean isPressed, float tpf) {
|
||||
if (name.equals("shoot") && isPressed) {
|
||||
|
@ -34,16 +34,17 @@ package com.jme3.scene.debug.custom;
|
||||
|
||||
import com.jme3.anim.Armature;
|
||||
import com.jme3.anim.Joint;
|
||||
import com.jme3.animation.Bone;
|
||||
import com.jme3.asset.AssetManager;
|
||||
import com.jme3.collision.Collidable;
|
||||
import com.jme3.collision.CollisionResults;
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.material.RenderState;
|
||||
import com.jme3.renderer.Camera;
|
||||
import com.jme3.renderer.queue.RenderQueue;
|
||||
import com.jme3.scene.Geometry;
|
||||
import com.jme3.scene.Node;
|
||||
import com.jme3.texture.Texture;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -63,15 +64,11 @@ public class ArmatureDebugger extends Node {
|
||||
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
|
||||
* available if the length data was not provided.
|
||||
*/
|
||||
private ArmatureInterJointsWire interJointWires;
|
||||
//private Geometry wires;
|
||||
private List<Bone> selectedJoints = new ArrayList<Bone>();
|
||||
|
||||
public ArmatureDebugger() {
|
||||
}
|
||||
@ -86,7 +83,6 @@ public class ArmatureDebugger extends Node {
|
||||
*/
|
||||
public ArmatureDebugger(String name, Armature armature, List<Joint> deformingJoints) {
|
||||
super(name);
|
||||
this.deformingJoints = deformingJoints;
|
||||
this.armature = armature;
|
||||
armature.update();
|
||||
|
||||
@ -102,25 +98,40 @@ public class ArmatureDebugger extends Node {
|
||||
joints.attachChild(ndJoints);
|
||||
outlines.attachChild(ndOutlines);
|
||||
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);
|
||||
|
||||
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);
|
||||
((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");
|
||||
matWires.setBoolean("VertexColor", true);
|
||||
matWires.getAdditionalRenderState().setLineWidth(3);
|
||||
@ -128,19 +139,16 @@ public class ArmatureDebugger extends Node {
|
||||
|
||||
Material matOutline = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
|
||||
matOutline.setBoolean("VertexColor", true);
|
||||
//matOutline.setColor("Color", ColorRGBA.White);
|
||||
matOutline.getAdditionalRenderState().setLineWidth(5);
|
||||
outlines.setMaterial(matOutline);
|
||||
|
||||
Material matJoints = new Material(assetManager, "Common/MatDefs/Misc/Billboard.j3md");
|
||||
Texture t = assetManager.loadTexture("Common/Textures/dot.png");
|
||||
// matJoints.setBoolean("VertexColor", true);
|
||||
// matJoints.setTexture("ColorMap", t);
|
||||
matJoints.setTexture("Texture", t);
|
||||
matJoints.getAdditionalRenderState().setDepthTest(false);
|
||||
matJoints.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
|
||||
joints.setQueueBucket(RenderQueue.Bucket.Translucent);
|
||||
joints.setMaterial(matJoints);
|
||||
Material matOutline2 = new Material(assetManager, "Common/MatDefs/Misc/DashedLine.j3md");
|
||||
matOutline2.getAdditionalRenderState().setLineWidth(1);
|
||||
outlines.getChild(1).setMaterial(matOutline2);
|
||||
|
||||
Material matWires2 = new Material(assetManager, "Common/MatDefs/Misc/DashedLine.j3md");
|
||||
matWires2.getAdditionalRenderState().setLineWidth(1);
|
||||
wires.getChild(1).setMaterial(matWires2);
|
||||
|
||||
}
|
||||
|
||||
@ -152,9 +160,13 @@ public class ArmatureDebugger extends Node {
|
||||
public void updateLogicalState(float tpf) {
|
||||
super.updateLogicalState(tpf);
|
||||
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) {
|
||||
|
@ -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.scene.Mesh;
|
||||
import com.jme3.scene.VertexBuffer;
|
||||
import com.jme3.scene.VertexBuffer.*;
|
||||
import com.jme3.util.BufferUtils;
|
||||
import com.jme3.scene.VertexBuffer.Type;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 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)
|
||||
*/
|
||||
public class ArmatureInterJointsWire extends Mesh {
|
||||
private static final int POINT_AMOUNT = 50;
|
||||
/**
|
||||
* 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 Vector3f tmp = new Vector3f();
|
||||
|
||||
private boolean guessBonesOrientation = false;
|
||||
|
||||
/**
|
||||
* Creates buffers for points. Each line has POINT_AMOUNT of points.
|
||||
*
|
||||
* @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;
|
||||
public ArmatureInterJointsWire(Vector3f start, Vector3f[] ends) {
|
||||
setMode(Mode.Lines);
|
||||
updateGeometry(start, ends);
|
||||
}
|
||||
|
||||
for (Joint joint : armature.getRoots()) {
|
||||
this.countConnections(joint);
|
||||
protected void updateGeometry(Vector3f start, Vector3f[] ends) {
|
||||
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);
|
||||
this.boneLengths = boneLengths;
|
||||
float[] texCoord = new float[ends.length * 2 + 2];
|
||||
texCoord[0] = 0;
|
||||
texCoord[1] = 0;
|
||||
for (int i = 0; i < ends.length * 2; i++) {
|
||||
texCoord[i + 2] = tmp.set(start).subtractLocal(ends[i / 2]).length();
|
||||
}
|
||||
setBuffer(Type.TexCoord, 2, texCoord);
|
||||
|
||||
VertexBuffer pb = new VertexBuffer(Type.Position);
|
||||
FloatBuffer fpb = BufferUtils.createFloatBuffer(POINT_AMOUNT * connectionsAmount * 3);
|
||||
pb.setupData(Usage.Stream, 3, Format.Float, fpb);
|
||||
this.setBuffer(pb);
|
||||
float[] normal = new float[ends.length * 3 + 3];
|
||||
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);
|
||||
|
||||
this.guessBonesOrientation = guessBonesOrientation;
|
||||
this.updateCounts();
|
||||
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() {
|
||||
VertexBuffer vb = this.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))));
|
||||
public void updatePoints(Vector3f start, Vector3f end) {
|
||||
VertexBuffer posBuf = getBuffer(Type.Position);
|
||||
|
||||
if (guessBonesOrientation) {
|
||||
parentTail = joint.getModelTransform().getTranslation();
|
||||
}
|
||||
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);
|
||||
|
||||
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);
|
||||
posBuf.updateData(fb);
|
||||
|
||||
this.updateBound();
|
||||
updateBound();
|
||||
}
|
||||
|
||||
/**
|
||||
* Th method counts the connections between bones.
|
||||
*
|
||||
* @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.collision.*;
|
||||
import com.jme3.math.*;
|
||||
import com.jme3.renderer.Camera;
|
||||
import com.jme3.renderer.queue.RenderQueue;
|
||||
import com.jme3.scene.*;
|
||||
import com.jme3.scene.shape.Line;
|
||||
@ -60,11 +61,13 @@ public class ArmatureNode extends Node {
|
||||
private Map<Geometry, Joint> geomToJoint = new HashMap<>();
|
||||
private Joint selectedJoint = null;
|
||||
private Vector3f tmpStart = new Vector3f();
|
||||
private Vector3f tmpEnd = new Vector3f();
|
||||
ColorRGBA selectedColor = ColorRGBA.Orange;
|
||||
ColorRGBA selectedColorJ = ColorRGBA.Yellow;
|
||||
;//new ColorRGBA(0.2f, 1f, 1.0f, 1.0f);
|
||||
ColorRGBA baseColor = new ColorRGBA(0.05f, 0.05f, 0.05f, 1f);
|
||||
private List<Vector3f> tmpEnds = new ArrayList<>();
|
||||
private final static ColorRGBA selectedColor = ColorRGBA.Orange;
|
||||
private final static ColorRGBA selectedColorJ = ColorRGBA.Yellow;
|
||||
private final static ColorRGBA outlineColor = ColorRGBA.LightGray;
|
||||
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) {
|
||||
Vector3f start = joint.getModelTransform().getTranslation().clone();
|
||||
Vector3f end = null;
|
||||
|
||||
//One child only, the bone direction is from the parent joint to the child joint.
|
||||
if (joint.getChildren().size() == 1) {
|
||||
end = joint.getChildren().get(0).getModelTransform().getTranslation().clone();
|
||||
Vector3f[] ends = null;
|
||||
if (!joint.getChildren().isEmpty()) {
|
||||
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);
|
||||
@ -99,19 +105,36 @@ public class ArmatureNode extends Node {
|
||||
attach(joints, deforms, jGeom);
|
||||
Geometry bGeom = null;
|
||||
Geometry bGeomO = null;
|
||||
if (end != null) {
|
||||
bGeom = new Geometry(joint.getName() + "Bone", new Line(start, end));
|
||||
setColor(bGeom, baseColor);
|
||||
if (ends != null) {
|
||||
Mesh m = null;
|
||||
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);
|
||||
bGeomO = new Geometry(joint.getName() + "BoneOutline", new Line(start, end));
|
||||
setColor(bGeomO, ColorRGBA.White);
|
||||
bGeom.setUserData("start", wires.getWorldTransform().transformVector(start, start));
|
||||
bGeom.setUserData("end", wires.getWorldTransform().transformVector(end, end));
|
||||
bGeom.setUserData("start", getWorldTransform().transformVector(start, start));
|
||||
for (int i = 0; i < ends.length; i++) {
|
||||
getWorldTransform().transformVector(ends[i], ends[i]);
|
||||
}
|
||||
bGeom.setUserData("end", ends);
|
||||
bGeom.setQueueBucket(RenderQueue.Bucket.Transparent);
|
||||
attach(wires, deforms, bGeom);
|
||||
attach(outlines, deforms, bGeomO);
|
||||
attach(wireAttach, deforms, bGeom);
|
||||
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});
|
||||
|
||||
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) {
|
||||
if (deforms) {
|
||||
parent.attachChild(geom);
|
||||
@ -142,7 +169,10 @@ public class ArmatureNode extends Node {
|
||||
Geometry[] geomArray = jointToGeoms.get(selectedJoint);
|
||||
setColor(geomArray[0], selectedColorJ);
|
||||
setColor(geomArray[1], selectedColor);
|
||||
setColor(geomArray[2], baseColor);
|
||||
|
||||
if (geomArray[2] != null) {
|
||||
setColor(geomArray[2], baseColor);
|
||||
}
|
||||
return j;
|
||||
}
|
||||
return null;
|
||||
@ -154,8 +184,10 @@ public class ArmatureNode extends Node {
|
||||
}
|
||||
Geometry[] geoms = jointToGeoms.get(selectedJoint);
|
||||
setColor(geoms[0], ColorRGBA.White);
|
||||
setColor(geoms[1], baseColor);
|
||||
setColor(geoms[2], ColorRGBA.White);
|
||||
setColor(geoms[1], geoms[2] == null ? outlineColor : baseColor);
|
||||
if (geoms[2] != null) {
|
||||
setColor(geoms[2], outlineColor);
|
||||
}
|
||||
selectedJoint = null;
|
||||
}
|
||||
|
||||
@ -171,20 +203,25 @@ public class ArmatureNode extends Node {
|
||||
jGeom.setLocalTranslation(joint.getModelTransform().getTranslation());
|
||||
Geometry bGeom = geoms[1];
|
||||
if (bGeom != null) {
|
||||
tmpStart.set(joint.getModelTransform().getTranslation());
|
||||
boolean hasEnd = false;
|
||||
if (joint.getChildren().size() == 1) {
|
||||
tmpEnd.set(joint.getChildren().get(0).getModelTransform().getTranslation());
|
||||
hasEnd = true;
|
||||
}
|
||||
if (hasEnd) {
|
||||
updateBoneMesh(bGeom);
|
||||
Vector3f start = bGeom.getUserData("start");
|
||||
Vector3f[] ends = bGeom.getUserData("end");
|
||||
start.set(joint.getModelTransform().getTranslation());
|
||||
if (ends != null) {
|
||||
tmpEnds.clear();
|
||||
for (int i = 0; i < joint.getChildren().size(); i++) {
|
||||
ends[i].set(joint.getChildren().get(i).getModelTransform().getTranslation());
|
||||
}
|
||||
updateBoneMesh(bGeom, start, ends);
|
||||
Geometry bGeomO = geoms[2];
|
||||
updateBoneMesh(bGeomO);
|
||||
Vector3f start = bGeom.getUserData("start");
|
||||
Vector3f end = bGeom.getUserData("end");
|
||||
bGeom.setUserData("start", bGeom.getParent().getWorldTransform().transformVector(tmpStart, start));
|
||||
bGeom.setUserData("end", bGeom.getParent().getWorldTransform().transformVector(tmpEnd, end));
|
||||
if (bGeomO != null) {
|
||||
updateBoneMesh(bGeomO, start, ends);
|
||||
}
|
||||
bGeom.setUserData("start", getWorldTransform().transformVector(start, start));
|
||||
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;
|
||||
for (Geometry g : geomToJoint.keySet()) {
|
||||
float len = MathUtils.raySegmentShortestDistance((Ray) other, (Vector3f) g.getUserData("start"), (Vector3f) g.getUserData("end"));
|
||||
if (len > 0 && len < 0.1f) {
|
||||
CollisionResult res = new CollisionResult();
|
||||
res.setGeometry(g);
|
||||
results.addCollision(res);
|
||||
nbCol++;
|
||||
Vector3f start = g.getUserData("start");
|
||||
Vector3f[] ends = g.getUserData("end");
|
||||
for (int i = 0; i < ends.length; i++) {
|
||||
float len = MathUtils.raySegmentShortestDistance((Ray) other, start, ends[i], camera);
|
||||
if (len > 0 && len < 10f) {
|
||||
CollisionResult res = new CollisionResult();
|
||||
res.setGeometry(g);
|
||||
results.addCollision(res);
|
||||
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);
|
||||
FloatBuffer fb = (FloatBuffer) pos.getData();
|
||||
fb.rewind();
|
||||
fb.put(new float[]{tmpStart.x, tmpStart.y, tmpStart.z,
|
||||
tmpEnd.x, tmpEnd.y, tmpEnd.z,});
|
||||
fb.put(new float[]{start.x, start.y, start.z,
|
||||
ends[0].x, ends[0].y, ends[0].z,});
|
||||
pos.updateData(fb);
|
||||
|
||||
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;
|
||||
AnimComposer composer;
|
||||
Queue<String> anims = new LinkedList<>();
|
||||
boolean playAnim = true;
|
||||
boolean playAnim = false;
|
||||
|
||||
public static void main(String... argv) {
|
||||
TestAnimMigration app = new TestAnimMigration();
|
||||
@ -36,15 +36,15 @@ public class TestAnimMigration extends SimpleApplication {
|
||||
@Override
|
||||
public void simpleInitApp() {
|
||||
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);
|
||||
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/Oto/Oto.mesh.xml");
|
||||
//Spatial model = assetManager.loadModel("Models/Jaime/Jaime.j3o");
|
||||
//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/Elephant/Elephant.mesh.xml");
|
||||
Spatial model = assetManager.loadModel("Models/Elephant/Elephant.mesh.xml").scale(0.02f);
|
||||
|
||||
AnimMigrationUtils.migrate(model);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user