diff --git a/jme3-core/src/main/java/com/jme3/math/MathUtils.java b/jme3-core/src/main/java/com/jme3/math/MathUtils.java index 234d5f61b..8c22700b1 100644 --- a/jme3-core/src/main/java/com/jme3/math/MathUtils.java +++ b/jme3-core/src/main/java/com/jme3/math/MathUtils.java @@ -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; 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 10bef21ec..edcb287e6 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 @@ -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.
  1. Map "pick target" action - * to a MouseButtonTrigger.
  2. flyCam.setEnabled(false); - *
  3. inputManager.setCursorVisible(true);
  4. Implement action in - * AnalogListener (TODO).
- */ private ActionListener actionListener = new ActionListener() { public void onAction(String name, boolean isPressed, float tpf) { if (name.equals("shoot") && isPressed) { 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 aec5f532e..e76f45253 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 @@ -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 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 selectedJoints = new ArrayList(); public ArmatureDebugger() { } @@ -86,7 +83,6 @@ public class ArmatureDebugger extends Node { */ public ArmatureDebugger(String name, Armature armature, List 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) { diff --git a/jme3-core/src/main/java/com/jme3/scene/debug/custom/ArmatureInterJointsWire.java b/jme3-core/src/main/java/com/jme3/scene/debug/custom/ArmatureInterJointsWire.java index 3c93e7dad..01c24cb49 100644 --- a/jme3-core/src/main/java/com/jme3/scene/debug/custom/ArmatureInterJointsWire.java +++ b/jme3-core/src/main/java/com/jme3/scene/debug/custom/ArmatureInterJointsWire.java @@ -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 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 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; - - 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[] 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); - this.guessBonesOrientation = guessBonesOrientation; - this.updateCounts(); + 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); + + 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)))); - - 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); + public void updatePoints(Vector3f start, Vector3f end) { + VertexBuffer posBuf = getBuffer(Type.Position); - 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); - /** - * 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); - } + posBuf.updateData(fb); + + updateBound(); } + } 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 258eb4834..52bafa771 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 @@ -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 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 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 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(); } diff --git a/jme3-core/src/main/resources/Common/MatDefs/Misc/DashedLine.j3md b/jme3-core/src/main/resources/Common/MatDefs/Misc/DashedLine.j3md new file mode 100644 index 000000000..097b44c71 --- /dev/null +++ b/jme3-core/src/main/resources/Common/MatDefs/Misc/DashedLine.j3md @@ -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 + } + } + } + + } +} diff --git a/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Misc/Dashed.j3sn b/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Misc/Dashed.j3sn new file mode 100644 index 000000000..87f235121 --- /dev/null +++ b/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Misc/Dashed.j3sn @@ -0,0 +1,37 @@ +ShaderNodeDefinitions{ + ShaderNodeDefinition Dashed { + //Vertex/Fragment + Type: Fragment + + //Shader GLSL: + 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 + @input vec2 texCoord the texture coordinates + @input vec4 inColor The input color + + + //@output + @output vec4 outColor The modified output color + } + Input { + //all the node inputs + // + vec2 texCoord + vec4 inColor + vec4 startPos + vec2 resolution + + + } + Output { + //all the node outputs + // + vec4 outColor + } + } +} \ No newline at end of file diff --git a/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Misc/Dashed100.frag b/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Misc/Dashed100.frag new file mode 100644 index 000000000..522971863 --- /dev/null +++ b/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Misc/Dashed100.frag @@ -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; + } + +} diff --git a/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Misc/PerspectiveDivide.j3sn b/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Misc/PerspectiveDivide.j3sn new file mode 100644 index 000000000..61ada6c2c --- /dev/null +++ b/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Misc/PerspectiveDivide.j3sn @@ -0,0 +1,30 @@ +ShaderNodeDefinitions{ + ShaderNodeDefinition PerspectiveDivide { + //Vertex/Fragment + Type: Vertex + + //Shader GLSL: + Shader GLSL100: Common/MatDefs/ShaderNodes/Misc/PerspectiveDivide100.frag + + Documentation{ + //type documentation here. This is optional but recommended + performs inVec.xyz / inVec.w + + //@input + @input vec4 inVec The input vector + + //@output + @output vec4 outVec The modified output vector + } + Input { + //all the node inputs + // + vec4 inVec + } + Output { + //all the node outputs + // + vec4 outVec + } + } +} \ No newline at end of file diff --git a/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Misc/PerspectiveDivide100.frag b/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Misc/PerspectiveDivide100.frag new file mode 100644 index 000000000..0e4f1d5be --- /dev/null +++ b/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Misc/PerspectiveDivide100.frag @@ -0,0 +1,3 @@ +void main(){ + outVec = vec4(inVec.xyz / inVec.w,1.0); +} 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 df4aa4eb8..836238e2b 100644 --- a/jme3-examples/src/main/java/jme3test/model/anim/TestAnimMigration.java +++ b/jme3-examples/src/main/java/jme3test/model/anim/TestAnimMigration.java @@ -26,7 +26,7 @@ public class TestAnimMigration extends SimpleApplication { ArmatureDebugAppState debugAppState; AnimComposer composer; Queue 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);