better Armature debugger
This commit is contained in:
parent
b5ad72b0e9
commit
ce170b8b53
@ -0,0 +1,24 @@
|
|||||||
|
package com.jme3.anim.util;
|
||||||
|
|
||||||
|
import com.jme3.animation.AnimControl;
|
||||||
|
import com.jme3.scene.SceneGraphVisitor;
|
||||||
|
import com.jme3.scene.Spatial;
|
||||||
|
|
||||||
|
public class AnimMigrationUtils {
|
||||||
|
|
||||||
|
public static Spatial migrate(Spatial source) {
|
||||||
|
//source.depthFirstTraversal();
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class AnimControlVisitor implements SceneGraphVisitor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(Spatial spatial) {
|
||||||
|
AnimControl control = spatial.getControl(AnimControl.class);
|
||||||
|
if (control != null) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
package com.jme3.math;
|
package com.jme3.math;
|
||||||
|
|
||||||
|
import com.jme3.util.TempVars;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Nehon on 23/04/2017.
|
* Created by Nehon on 23/04/2017.
|
||||||
*/
|
*/
|
||||||
@ -162,4 +164,65 @@ public class MathUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static float raySegmentShortestDistance(Ray ray, Vector3f segStart, Vector3f segEnd) {
|
||||||
|
// Algorithm is ported from the C algorithm of
|
||||||
|
// Paul Bourke at http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline3d/
|
||||||
|
TempVars vars = TempVars.get();
|
||||||
|
Vector3f resultSegmentPoint1 = vars.vect1;
|
||||||
|
Vector3f resultSegmentPoint2 = vars.vect2;
|
||||||
|
|
||||||
|
Vector3f p1 = segStart;
|
||||||
|
Vector3f p2 = segEnd;
|
||||||
|
Vector3f p3 = ray.origin;
|
||||||
|
Vector3f p4 = vars.vect3.set(ray.getDirection()).multLocal(Math.min(ray.getLimit(), 1000)).addLocal(ray.getOrigin());
|
||||||
|
Vector3f p13 = vars.vect4.set(p1).subtractLocal(p3);
|
||||||
|
Vector3f p43 = vars.vect5.set(p4).subtractLocal(p3);
|
||||||
|
|
||||||
|
if (p43.lengthSquared() < 0.0001) {
|
||||||
|
vars.release();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
Vector3f p21 = vars.vect6.set(p2).subtractLocal(p1);
|
||||||
|
if (p21.lengthSquared() < 0.0001) {
|
||||||
|
vars.release();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
double d1343 = p13.x * (double) p43.x + (double) p13.y * p43.y + (double) p13.z * p43.z;
|
||||||
|
double d4321 = p43.x * (double) p21.x + (double) p43.y * p21.y + (double) p43.z * p21.z;
|
||||||
|
double d1321 = p13.x * (double) p21.x + (double) p13.y * p21.y + (double) p13.z * p21.z;
|
||||||
|
double d4343 = p43.x * (double) p43.x + (double) p43.y * p43.y + (double) p43.z * p43.z;
|
||||||
|
double d2121 = p21.x * (double) p21.x + (double) p21.y * p21.y + (double) p21.z * p21.z;
|
||||||
|
|
||||||
|
double denom = d2121 * d4343 - d4321 * d4321;
|
||||||
|
if (Math.abs(denom) < 0.0001) {
|
||||||
|
vars.release();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
double numer = d1343 * d4321 - d1321 * d4343;
|
||||||
|
|
||||||
|
double mua = numer / denom;
|
||||||
|
double mub = (d1343 + d4321 * (mua)) / d4343;
|
||||||
|
|
||||||
|
resultSegmentPoint1.x = (float) (p1.x + mua * p21.x);
|
||||||
|
resultSegmentPoint1.y = (float) (p1.y + mua * p21.y);
|
||||||
|
resultSegmentPoint1.z = (float) (p1.z + mua * p21.z);
|
||||||
|
resultSegmentPoint2.x = (float) (p3.x + mub * p43.x);
|
||||||
|
resultSegmentPoint2.y = (float) (p3.y + mub * p43.y);
|
||||||
|
resultSegmentPoint2.z = (float) (p3.z + mub * p43.z);
|
||||||
|
|
||||||
|
//check if result 1 is in the segment section.
|
||||||
|
float startToPoint = vars.vect3.set(resultSegmentPoint1).subtractLocal(segStart).lengthSquared();
|
||||||
|
float endToPoint = vars.vect3.set(resultSegmentPoint1).subtractLocal(segEnd).lengthSquared();
|
||||||
|
float segLength = vars.vect3.set(segEnd).subtractLocal(segStart).lengthSquared();
|
||||||
|
if (startToPoint > segLength || endToPoint > segLength) {
|
||||||
|
vars.release();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
float length = resultSegmentPoint1.subtractLocal(resultSegmentPoint2).length();
|
||||||
|
vars.release();
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,199 +0,0 @@
|
|||||||
package com.jme3.scene.debug.custom;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are
|
|
||||||
* met:
|
|
||||||
*
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
*
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
|
||||||
* may be used to endorse or promote products derived from this software
|
|
||||||
* without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
||||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
||||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
||||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
||||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
||||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import com.jme3.anim.Armature;
|
|
||||||
import com.jme3.anim.Joint;
|
|
||||||
import com.jme3.bounding.*;
|
|
||||||
import com.jme3.math.Quaternion;
|
|
||||||
import com.jme3.math.Vector3f;
|
|
||||||
import com.jme3.scene.*;
|
|
||||||
import com.jme3.scene.shape.Sphere;
|
|
||||||
|
|
||||||
import java.nio.FloatBuffer;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static com.jme3.util.BufferUtils.createFloatBuffer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The class that displays either wires between the bones' heads if no length
|
|
||||||
* data is supplied and full bones' shapes otherwise.
|
|
||||||
*/
|
|
||||||
public class ArmatureBone extends Node {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The armature to be displayed.
|
|
||||||
*/
|
|
||||||
private Armature armature;
|
|
||||||
/**
|
|
||||||
* The map between the bone index and its length.
|
|
||||||
*/
|
|
||||||
private Map<Joint, Node> jointNode = new HashMap<>();
|
|
||||||
private Map<Node, Joint> nodeJoint = new HashMap<>();
|
|
||||||
private Node selectedNode = null;
|
|
||||||
private boolean guessJointsOrientation = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a wire with bone lengths data. If the data is supplied then the
|
|
||||||
* wires will show each full bone (from head to tail).
|
|
||||||
*
|
|
||||||
* @param armature the armature that will be shown
|
|
||||||
* @param boneLengths a map between the bone's index and the bone's length
|
|
||||||
*/
|
|
||||||
public ArmatureBone(Armature armature, Map<Integer, Float> boneLengths, boolean guessJointsOrientation) {
|
|
||||||
this.armature = armature;
|
|
||||||
this.guessJointsOrientation = guessJointsOrientation;
|
|
||||||
|
|
||||||
BoneShape boneShape = new BoneShape();
|
|
||||||
Sphere jointShape = new Sphere(16, 16, 0.05f);
|
|
||||||
jointShape.setBuffer(VertexBuffer.Type.Color, 4, createFloatBuffer(jointShape.getVertexCount() * 4));
|
|
||||||
FloatBuffer cb = jointShape.getFloatBuffer(VertexBuffer.Type.Color);
|
|
||||||
|
|
||||||
cb.rewind();
|
|
||||||
for (int i = 0; i < jointShape.getVertexCount(); i++) {
|
|
||||||
cb.put(0.05f).put(0.05f).put(0.05f).put(1f);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Joint joint : armature.getRoots()) {
|
|
||||||
createSkeletonGeoms(joint, boneShape, jointShape, boneLengths, armature, this, guessJointsOrientation);
|
|
||||||
}
|
|
||||||
this.updateModelBound();
|
|
||||||
|
|
||||||
|
|
||||||
Sphere originShape = new Sphere(16, 16, 0.02f);
|
|
||||||
originShape.setBuffer(VertexBuffer.Type.Color, 4, createFloatBuffer(originShape.getVertexCount() * 4));
|
|
||||||
cb = originShape.getFloatBuffer(VertexBuffer.Type.Color);
|
|
||||||
cb.rewind();
|
|
||||||
for (int i = 0; i < jointShape.getVertexCount(); i++) {
|
|
||||||
cb.put(0.4f).put(0.4f).put(0.05f).put(1f);
|
|
||||||
}
|
|
||||||
|
|
||||||
Geometry origin = new Geometry("origin", originShape);
|
|
||||||
BoundingVolume bv = this.getWorldBound();
|
|
||||||
float scale = 1;
|
|
||||||
if (bv.getType() == BoundingVolume.Type.AABB) {
|
|
||||||
BoundingBox bb = (BoundingBox) bv;
|
|
||||||
scale = (bb.getXExtent() + bb.getYExtent() + bb.getZExtent()) / 3f;
|
|
||||||
} else if (bv.getType() == BoundingVolume.Type.Sphere) {
|
|
||||||
BoundingSphere bs = (BoundingSphere) bv;
|
|
||||||
scale = bs.getRadius();
|
|
||||||
}
|
|
||||||
origin.scale(scale);
|
|
||||||
attachChild(origin);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final void createSkeletonGeoms(Joint joint, Mesh boneShape, Mesh jointShape, Map<Integer, Float> boneLengths, Armature armature, Node parent, boolean guessBonesOrientation) {
|
|
||||||
|
|
||||||
Node n = new Node(joint.getName() + "Node");
|
|
||||||
Geometry bGeom = new Geometry(joint.getName() + "Bone", boneShape);
|
|
||||||
Geometry jGeom = new Geometry(joint.getName() + "Joint", jointShape);
|
|
||||||
n.setLocalTransform(joint.getLocalTransform());
|
|
||||||
|
|
||||||
float boneLength = boneLengths.get(armature.getJointIndex(joint));
|
|
||||||
|
|
||||||
if (guessBonesOrientation) {
|
|
||||||
//One child only, the bone direction is from the parent joint to the child joint.
|
|
||||||
if (joint.getChildren().size() == 1) {
|
|
||||||
Vector3f v = joint.getChildren().get(0).getLocalTranslation();
|
|
||||||
Quaternion q = new Quaternion();
|
|
||||||
q.lookAt(v, Vector3f.UNIT_Z);
|
|
||||||
bGeom.setLocalRotation(q);
|
|
||||||
}
|
|
||||||
//no child, the bone has the same direction as the parent bone.
|
|
||||||
if (joint.getChildren().isEmpty()) {
|
|
||||||
//no parent, let's use the bind orientation of the bone
|
|
||||||
Spatial s = parent.getChild(0);
|
|
||||||
if (s != null) {
|
|
||||||
bGeom.setLocalRotation(s.getLocalRotation());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float boneScale = boneLength * 0.8f;
|
|
||||||
float scale = boneScale / 8f;
|
|
||||||
bGeom.setLocalScale(new Vector3f(scale, scale, boneScale));
|
|
||||||
Vector3f offset = new Vector3f(0, 0, boneLength * 0.1f);
|
|
||||||
bGeom.getLocalRotation().multLocal(offset);
|
|
||||||
bGeom.setLocalTranslation(offset);
|
|
||||||
jGeom.setLocalScale(boneLength);
|
|
||||||
|
|
||||||
if (joint.getChildren().size() <= 1) {
|
|
||||||
n.attachChild(bGeom);
|
|
||||||
}
|
|
||||||
n.attachChild(jGeom);
|
|
||||||
|
|
||||||
jointNode.put(joint, n);
|
|
||||||
nodeJoint.put(n, joint);
|
|
||||||
parent.attachChild(n);
|
|
||||||
for (Joint child : joint.getChildren()) {
|
|
||||||
createSkeletonGeoms(child, boneShape, jointShape, boneLengths, armature, n, guessBonesOrientation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Joint select(Geometry g) {
|
|
||||||
Node parentNode = g.getParent();
|
|
||||||
|
|
||||||
if (parent != null) {
|
|
||||||
Joint j = nodeJoint.get(parentNode);
|
|
||||||
if (j != null) {
|
|
||||||
selectedNode = parentNode;
|
|
||||||
}
|
|
||||||
return j;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Node getSelectedNode() {
|
|
||||||
return selectedNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected final void updateSkeletonGeoms(Joint joint) {
|
|
||||||
Node n = jointNode.get(joint);
|
|
||||||
n.setLocalTransform(joint.getLocalTransform());
|
|
||||||
|
|
||||||
for (Joint child : joint.getChildren()) {
|
|
||||||
updateSkeletonGeoms(child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The method updates the geometry according to the positions of the bones.
|
|
||||||
*/
|
|
||||||
public void updateGeometry() {
|
|
||||||
for (Joint joint : armature.getRoots()) {
|
|
||||||
updateSkeletonGeoms(joint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -8,12 +8,12 @@ import com.jme3.anim.*;
|
|||||||
import com.jme3.app.Application;
|
import com.jme3.app.Application;
|
||||||
import com.jme3.app.state.AbstractAppState;
|
import com.jme3.app.state.AbstractAppState;
|
||||||
import com.jme3.app.state.AppStateManager;
|
import com.jme3.app.state.AppStateManager;
|
||||||
|
import com.jme3.collision.CollisionResults;
|
||||||
import com.jme3.input.MouseInput;
|
import com.jme3.input.MouseInput;
|
||||||
import com.jme3.input.controls.ActionListener;
|
import com.jme3.input.controls.ActionListener;
|
||||||
import com.jme3.input.controls.MouseButtonTrigger;
|
import com.jme3.input.controls.MouseButtonTrigger;
|
||||||
import com.jme3.light.DirectionalLight;
|
import com.jme3.light.DirectionalLight;
|
||||||
import com.jme3.math.ColorRGBA;
|
import com.jme3.math.*;
|
||||||
import com.jme3.math.Vector3f;
|
|
||||||
import com.jme3.renderer.ViewPort;
|
import com.jme3.renderer.ViewPort;
|
||||||
import com.jme3.scene.*;
|
import com.jme3.scene.*;
|
||||||
|
|
||||||
@ -28,7 +28,6 @@ public class ArmatureDebugAppState extends AbstractAppState {
|
|||||||
private Map<Armature, ArmatureDebugger> armatures = new HashMap<>();
|
private Map<Armature, ArmatureDebugger> armatures = new HashMap<>();
|
||||||
private Map<Armature, Joint> selectedBones = new HashMap<>();
|
private Map<Armature, Joint> selectedBones = new HashMap<>();
|
||||||
private Application app;
|
private Application app;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize(AppStateManager stateManager, Application app) {
|
public void initialize(AppStateManager stateManager, Application app) {
|
||||||
ViewPort vp = app.getRenderManager().createMainView("debug", app.getCamera());
|
ViewPort vp = app.getRenderManager().createMainView("debug", app.getCamera());
|
||||||
@ -46,7 +45,6 @@ public class ArmatureDebugAppState extends AbstractAppState {
|
|||||||
debugNode.addLight(new DirectionalLight(new Vector3f(-1f, -1f, -1f).normalizeLocal()));
|
debugNode.addLight(new DirectionalLight(new Vector3f(-1f, -1f, -1f).normalizeLocal()));
|
||||||
|
|
||||||
debugNode.addLight(new DirectionalLight(new Vector3f(1f, 1f, 1f).normalizeLocal(), new ColorRGBA(0.5f, 0.5f, 0.5f, 1.0f)));
|
debugNode.addLight(new DirectionalLight(new Vector3f(1f, 1f, 1f).normalizeLocal(), new ColorRGBA(0.5f, 0.5f, 0.5f, 1.0f)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -55,15 +53,15 @@ public class ArmatureDebugAppState extends AbstractAppState {
|
|||||||
debugNode.updateGeometricState();
|
debugNode.updateGeometricState();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArmatureDebugger addArmature(SkinningControl skinningControl, boolean guessJointsOrientation) {
|
public ArmatureDebugger addArmature(SkinningControl skinningControl) {
|
||||||
Armature armature = skinningControl.getArmature();
|
Armature armature = skinningControl.getArmature();
|
||||||
Spatial forSpatial = skinningControl.getSpatial();
|
Spatial forSpatial = skinningControl.getSpatial();
|
||||||
return addArmature(armature, forSpatial, guessJointsOrientation);
|
return addArmature(armature, forSpatial);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArmatureDebugger addArmature(Armature armature, Spatial forSpatial, boolean guessJointsOrientation) {
|
public ArmatureDebugger addArmature(Armature armature, Spatial forSpatial) {
|
||||||
|
|
||||||
ArmatureDebugger ad = new ArmatureDebugger(forSpatial.getName() + "_Armature", armature, guessJointsOrientation);
|
ArmatureDebugger ad = new ArmatureDebugger(forSpatial.getName() + "_Armature", armature);
|
||||||
ad.setLocalTransform(forSpatial.getWorldTransform());
|
ad.setLocalTransform(forSpatial.getWorldTransform());
|
||||||
if (forSpatial instanceof Node) {
|
if (forSpatial instanceof Node) {
|
||||||
List<Geometry> geoms = new ArrayList<>();
|
List<Geometry> geoms = new ArrayList<>();
|
||||||
@ -98,45 +96,44 @@ public class ArmatureDebugAppState extends AbstractAppState {
|
|||||||
*/
|
*/
|
||||||
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) {
|
||||||
// CollisionResults results = new CollisionResults();
|
CollisionResults results = new CollisionResults();
|
||||||
// Vector2f click2d = app.getInputManager().getCursorPosition();
|
Vector2f click2d = app.getInputManager().getCursorPosition();
|
||||||
// Vector3f click3d = app.getCamera().getWorldCoordinates(new Vector2f(click2d.x, click2d.y), 0f).clone();
|
Vector3f click3d = app.getCamera().getWorldCoordinates(new Vector2f(click2d.x, click2d.y), 0f).clone();
|
||||||
// Vector3f dir = app.getCamera().getWorldCoordinates(new Vector2f(click2d.x, click2d.y), 1f).subtractLocal(click3d);
|
Vector3f dir = app.getCamera().getWorldCoordinates(new Vector2f(click2d.x, click2d.y), 1f).subtractLocal(click3d);
|
||||||
// Ray ray = new Ray(click3d, dir);
|
Ray ray = new Ray(click3d, dir);
|
||||||
//
|
|
||||||
// debugNode.collideWith(ray, results);
|
debugNode.collideWith(ray, results);
|
||||||
//
|
if (results.size() == 0) {
|
||||||
// if (results.size() > 0) {
|
for (ArmatureDebugger ad : armatures.values()) {
|
||||||
// // The closest result is the target that the player picked:
|
ad.select(null);
|
||||||
// Geometry target = results.getClosestCollision().getGeometry();
|
}
|
||||||
// for (ArmatureDebugger skeleton : armatures.values()) {
|
return;
|
||||||
// Joint selectedBone = skeleton.select(target);
|
}
|
||||||
// if (selectedBone != null) {
|
// The closest result is the target that the player picked:
|
||||||
// selectedBones.put(skeleton.getArmature(), selectedBone);
|
Geometry target = results.getClosestCollision().getGeometry();
|
||||||
// System.err.println("-----------------------");
|
for (ArmatureDebugger ad : armatures.values()) {
|
||||||
// System.err.println("Selected Bone : " + selectedBone.getName() + " in skeleton " + skeleton.getName());
|
Joint selectedjoint = ad.select(target);
|
||||||
// System.err.println("Root Bone : " + (selectedBone.getParent() == null));
|
if (selectedjoint != null) {
|
||||||
// System.err.println("-----------------------");
|
selectedBones.put(ad.getArmature(), selectedjoint);
|
||||||
// System.err.println("Bind translation: " + selectedBone.getBindPosition());
|
System.err.println("-----------------------");
|
||||||
// System.err.println("Bind rotation: " + selectedBone.getBindRotation());
|
System.err.println("Selected Joint : " + selectedjoint.getName() + " in armature " + ad.getName());
|
||||||
// System.err.println("Bind scale: " + selectedBone.getBindScale());
|
System.err.println("Root Bone : " + (selectedjoint.getParent() == null));
|
||||||
// System.err.println("---");
|
System.err.println("-----------------------");
|
||||||
// System.err.println("Local translation: " + selectedBone.getLocalPosition());
|
System.err.println("Local translation: " + selectedjoint.getLocalTranslation());
|
||||||
// System.err.println("Local rotation: " + selectedBone.getLocalRotation());
|
System.err.println("Local rotation: " + selectedjoint.getLocalRotation());
|
||||||
// System.err.println("Local scale: " + selectedBone.getLocalScale());
|
System.err.println("Local scale: " + selectedjoint.getLocalScale());
|
||||||
// System.err.println("---");
|
System.err.println("---");
|
||||||
// System.err.println("Model translation: " + selectedBone.getModelSpacePosition());
|
System.err.println("Model translation: " + selectedjoint.getModelTransform().getTranslation());
|
||||||
// System.err.println("Model rotation: " + selectedBone.getModelSpaceRotation());
|
System.err.println("Model rotation: " + selectedjoint.getModelTransform().getRotation());
|
||||||
// System.err.println("Model scale: " + selectedBone.getModelSpaceScale());
|
System.err.println("Model scale: " + selectedjoint.getModelTransform().getScale());
|
||||||
// System.err.println("---");
|
System.err.println("---");
|
||||||
// System.err.println("Bind inverse Transform: ");
|
System.err.println("Bind inverse Transform: ");
|
||||||
// System.err.println(selectedBone.getBindInverseTransform());
|
System.err.println(selectedjoint.getInverseModelBindMatrix());
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -37,31 +37,39 @@ import com.jme3.anim.Joint;
|
|||||||
import com.jme3.animation.Bone;
|
import com.jme3.animation.Bone;
|
||||||
import com.jme3.asset.AssetManager;
|
import com.jme3.asset.AssetManager;
|
||||||
import com.jme3.material.Material;
|
import com.jme3.material.Material;
|
||||||
import com.jme3.math.ColorRGBA;
|
import com.jme3.material.RenderState;
|
||||||
import com.jme3.scene.*;
|
import com.jme3.renderer.queue.RenderQueue;
|
||||||
|
import com.jme3.scene.Geometry;
|
||||||
|
import com.jme3.scene.Node;
|
||||||
|
import com.jme3.texture.Texture;
|
||||||
|
|
||||||
import java.nio.FloatBuffer;
|
import java.util.ArrayList;
|
||||||
import java.util.*;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The class that creates a mesh to display how bones behave. If it is supplied
|
* The class that creates a mesh to display how bones behave. If it is supplied
|
||||||
* with the bones' lengths it will show exactly how the bones look like on the
|
* with the bones' lengths it will show exactly how the bones look like on the
|
||||||
* scene. If not then only connections between each bone heads will be shown.
|
* scene. If not then only connections between each bone heads will be shown.
|
||||||
*/
|
*/
|
||||||
public class ArmatureDebugger extends BatchNode {
|
public class ArmatureDebugger extends Node {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The lines of the bones or the wires between their heads.
|
* The lines of the bones or the wires between their heads.
|
||||||
*/
|
*/
|
||||||
private ArmatureBone bones;
|
private ArmatureNode armatureNode;
|
||||||
|
|
||||||
private Armature armature;
|
private Armature armature;
|
||||||
|
|
||||||
|
Node joints;
|
||||||
|
Node outlines;
|
||||||
|
Node wires;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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 Geometry wires;
|
||||||
private List<Bone> selectedJoints = new ArrayList<Bone>();
|
private List<Bone> selectedJoints = new ArrayList<Bone>();
|
||||||
|
|
||||||
public ArmatureDebugger() {
|
public ArmatureDebugger() {
|
||||||
@ -75,110 +83,74 @@ public class ArmatureDebugger extends BatchNode {
|
|||||||
* @param name the name of the debugger's node
|
* @param name the name of the debugger's node
|
||||||
* @param armature the armature that will be shown
|
* @param armature the armature that will be shown
|
||||||
*/
|
*/
|
||||||
public ArmatureDebugger(String name, Armature armature, boolean guessJointsOrientation) {
|
public ArmatureDebugger(String name, Armature armature) {
|
||||||
super(name);
|
super(name);
|
||||||
this.armature = armature;
|
this.armature = armature;
|
||||||
// armature.reset();
|
|
||||||
armature.update();
|
armature.update();
|
||||||
//Joints have no length we want to display the as bones so we compute their length
|
|
||||||
Map<Integer, Float> bonesLength = new HashMap<Integer, Float>();
|
|
||||||
|
|
||||||
for (Joint joint : armature.getRoots()) {
|
|
||||||
computeLength(joint, bonesLength, armature);
|
|
||||||
}
|
|
||||||
|
|
||||||
bones = new ArmatureBone(armature, bonesLength, guessJointsOrientation);
|
joints = new Node("joints");
|
||||||
|
outlines = new Node("outlines");
|
||||||
|
wires = new Node("bones");
|
||||||
|
this.attachChild(joints);
|
||||||
|
this.attachChild(outlines);
|
||||||
|
this.attachChild(wires);
|
||||||
|
|
||||||
this.attachChild(bones);
|
armatureNode = new ArmatureNode(armature, joints, wires, outlines);
|
||||||
|
|
||||||
interJointWires = new ArmatureInterJointsWire(armature, bonesLength, guessJointsOrientation);
|
this.attachChild(armatureNode);
|
||||||
wires = new Geometry(name + "_interwires", interJointWires);
|
|
||||||
|
//interJointWires = new ArmatureInterJointsWire(armature, bonesLength, guessJointsOrientation);
|
||||||
|
//wires = new Geometry(name + "_interwires", interJointWires);
|
||||||
// this.attachChild(wires);
|
// this.attachChild(wires);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void initialize(AssetManager assetManager) {
|
protected void initialize(AssetManager assetManager) {
|
||||||
Material mat = new Material(assetManager, "Common/MatDefs/Misc/fakeLighting.j3md");
|
|
||||||
mat.setColor("Color", new ColorRGBA(0.2f, 0.2f, 0.2f, 1));
|
|
||||||
setMaterial(mat);
|
|
||||||
|
|
||||||
Material matWires = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
|
Material matWires = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
|
||||||
matWires.setColor("Color", ColorRGBA.Black);
|
matWires.setBoolean("VertexColor", true);
|
||||||
|
matWires.getAdditionalRenderState().setLineWidth(3);
|
||||||
wires.setMaterial(matWires);
|
wires.setMaterial(matWires);
|
||||||
//wires.setQueueBucket(RenderQueue.Bucket.Transparent);
|
|
||||||
// Material mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
|
|
||||||
// mat2.setBoolean("VertexColor", true);
|
|
||||||
// bones.setMaterial(mat2);
|
|
||||||
// batch();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
Material matOutline = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
|
||||||
public final void setMaterial(Material material) {
|
matOutline.setBoolean("VertexColor", true);
|
||||||
if (batches.isEmpty()) {
|
//matOutline.setColor("Color", ColorRGBA.White);
|
||||||
for (int i = 0; i < children.size(); i++) {
|
matOutline.getAdditionalRenderState().setLineWidth(5);
|
||||||
children.get(i).setMaterial(material);
|
outlines.setMaterial(matOutline);
|
||||||
}
|
|
||||||
} else {
|
Material matJoints = new Material(assetManager, "Common/MatDefs/Misc/Billboard.j3md");
|
||||||
super.setMaterial(material);
|
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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Armature getArmature() {
|
public Armature getArmature() {
|
||||||
return armature;
|
return armature;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void computeLength(Joint joint, Map<Integer, Float> jointsLength, Armature armature) {
|
|
||||||
if (joint.getChildren().isEmpty()) {
|
|
||||||
if (joint.getParent() != null) {
|
|
||||||
jointsLength.put(armature.getJointIndex(joint), jointsLength.get(armature.getJointIndex(joint.getParent())) * 0.75f);
|
|
||||||
} else {
|
|
||||||
jointsLength.put(armature.getJointIndex(joint), 0.1f);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
float length = Float.MAX_VALUE;
|
|
||||||
for (Joint child : joint.getChildren()) {
|
|
||||||
float len = joint.getModelTransform().getTranslation().subtract(child.getModelTransform().getTranslation()).length();
|
|
||||||
if (len < length) {
|
|
||||||
length = len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
jointsLength.put(armature.getJointIndex(joint), length);
|
|
||||||
for (Joint child : joint.getChildren()) {
|
|
||||||
computeLength(child, jointsLength, armature);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateLogicalState(float tpf) {
|
public void updateLogicalState(float tpf) {
|
||||||
super.updateLogicalState(tpf);
|
super.updateLogicalState(tpf);
|
||||||
bones.updateGeometry();
|
armatureNode.updateGeometry();
|
||||||
if (interJointWires != null) {
|
if (interJointWires != null) {
|
||||||
// interJointWires.updateGeometry();
|
// interJointWires.updateGeometry();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorRGBA selectedColor = ColorRGBA.Orange;
|
|
||||||
ColorRGBA baseColor = new ColorRGBA(0.05f, 0.05f, 0.05f, 1f);
|
|
||||||
|
|
||||||
protected Joint select(Geometry g) {
|
protected Joint select(Geometry g) {
|
||||||
Node oldNode = bones.getSelectedNode();
|
return armatureNode.select(g);
|
||||||
Joint b = bones.select(g);
|
|
||||||
if (b == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (oldNode != null) {
|
|
||||||
markSelected(oldNode, false);
|
|
||||||
}
|
|
||||||
markSelected(bones.getSelectedNode(), true);
|
|
||||||
return b;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the armature wires
|
* @return the armature wires
|
||||||
*/
|
*/
|
||||||
public ArmatureBone getBoneShapes() {
|
public ArmatureNode getBoneShapes() {
|
||||||
return bones;
|
return armatureNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -187,29 +159,4 @@ public class ArmatureDebugger extends BatchNode {
|
|||||||
public ArmatureInterJointsWire getInterJointWires() {
|
public ArmatureInterJointsWire getInterJointWires() {
|
||||||
return interJointWires;
|
return interJointWires;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void markSelected(Node n, boolean selected) {
|
|
||||||
ColorRGBA c = baseColor;
|
|
||||||
if (selected) {
|
|
||||||
c = selectedColor;
|
|
||||||
}
|
|
||||||
for (Spatial spatial : n.getChildren()) {
|
|
||||||
if (spatial instanceof Geometry) {
|
|
||||||
Geometry geom = (Geometry) spatial;
|
|
||||||
|
|
||||||
Geometry batch = (Geometry) getChild(getName() + "-batch0");
|
|
||||||
VertexBuffer vb = batch.getMesh().getBuffer(VertexBuffer.Type.Color);
|
|
||||||
FloatBuffer color = (FloatBuffer) vb.getData();
|
|
||||||
// System.err.println(getName() + "." + geom.getName() + " index " + getGeometryStartIndex(geom) * 4 + "/" + color.limit());
|
|
||||||
|
|
||||||
color.position(getGeometryStartIndex(geom) * 4);
|
|
||||||
|
|
||||||
for (int i = 0; i < geom.getVertexCount(); i++) {
|
|
||||||
color.put(c.r).put(c.g).put(c.b).put(c.a);
|
|
||||||
}
|
|
||||||
color.rewind();
|
|
||||||
vb.updateData(color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -0,0 +1,245 @@
|
|||||||
|
package com.jme3.scene.debug.custom;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import com.jme3.anim.Armature;
|
||||||
|
import com.jme3.anim.Joint;
|
||||||
|
import com.jme3.collision.*;
|
||||||
|
import com.jme3.math.*;
|
||||||
|
import com.jme3.renderer.queue.RenderQueue;
|
||||||
|
import com.jme3.scene.*;
|
||||||
|
import com.jme3.scene.shape.Line;
|
||||||
|
|
||||||
|
import java.nio.FloatBuffer;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The class that displays either wires between the bones' heads if no length
|
||||||
|
* data is supplied and full bones' shapes otherwise.
|
||||||
|
*/
|
||||||
|
public class ArmatureNode extends Node {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The armature to be displayed.
|
||||||
|
*/
|
||||||
|
private Armature armature;
|
||||||
|
/**
|
||||||
|
* The map between the bone index and its length.
|
||||||
|
*/
|
||||||
|
private Map<Joint, Geometry[]> jointToGeoms = new HashMap<>();
|
||||||
|
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);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a wire with bone lengths data. If the data is supplied then the
|
||||||
|
* wires will show each full bone (from head to tail).
|
||||||
|
*
|
||||||
|
* @param armature the armature that will be shown
|
||||||
|
*/
|
||||||
|
public ArmatureNode(Armature armature, Node joints, Node wires, Node outlines) {
|
||||||
|
this.armature = armature;
|
||||||
|
|
||||||
|
for (Joint joint : armature.getRoots()) {
|
||||||
|
createSkeletonGeoms(joint, joints, wires, outlines);
|
||||||
|
}
|
||||||
|
this.updateModelBound();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final void createSkeletonGeoms(Joint joint, Node joints, Node wires, Node outlines) {
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
Geometry jGeom = new Geometry(joint.getName() + "Joint", new JointShape());
|
||||||
|
jGeom.setLocalTranslation(start);
|
||||||
|
joints.attachChild(jGeom);
|
||||||
|
Geometry bGeom = null;
|
||||||
|
Geometry bGeomO = null;
|
||||||
|
if (end != null) {
|
||||||
|
bGeom = new Geometry(joint.getName() + "Bone", new Line(start, end));
|
||||||
|
setColor(bGeom, 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.setQueueBucket(RenderQueue.Bucket.Transparent);
|
||||||
|
wires.attachChild(bGeom);
|
||||||
|
outlines.attachChild(bGeomO);
|
||||||
|
}
|
||||||
|
|
||||||
|
jointToGeoms.put(joint, new Geometry[]{jGeom, bGeom, bGeomO});
|
||||||
|
|
||||||
|
for (Joint child : joint.getChildren()) {
|
||||||
|
createSkeletonGeoms(child, joints, wires, outlines);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Joint select(Geometry g) {
|
||||||
|
if (g == null) {
|
||||||
|
resetSelection();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Joint j = geomToJoint.get(g);
|
||||||
|
if (j != null) {
|
||||||
|
if (selectedJoint == j) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
resetSelection();
|
||||||
|
selectedJoint = j;
|
||||||
|
Geometry[] geomArray = jointToGeoms.get(selectedJoint);
|
||||||
|
setColor(geomArray[0], selectedColorJ);
|
||||||
|
setColor(geomArray[1], selectedColor);
|
||||||
|
setColor(geomArray[2], baseColor);
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resetSelection() {
|
||||||
|
if (selectedJoint == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Geometry[] geoms = jointToGeoms.get(selectedJoint);
|
||||||
|
setColor(geoms[0], ColorRGBA.White);
|
||||||
|
setColor(geoms[1], baseColor);
|
||||||
|
setColor(geoms[2], ColorRGBA.White);
|
||||||
|
selectedJoint = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Joint getSelectedJoint() {
|
||||||
|
return selectedJoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected final void updateSkeletonGeoms(Joint joint) {
|
||||||
|
Geometry[] geoms = jointToGeoms.get(joint);
|
||||||
|
if (geoms != null) {
|
||||||
|
Geometry jGeom = geoms[0];
|
||||||
|
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);
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Joint child : joint.getChildren()) {
|
||||||
|
updateSkeletonGeoms(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int collideWith(Collidable other, CollisionResults results) {
|
||||||
|
if (!(other instanceof Ray)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nbCol;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateBoneMesh(Geometry bGeom) {
|
||||||
|
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,});
|
||||||
|
pos.updateData(fb);
|
||||||
|
|
||||||
|
bGeom.updateModelBound();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setColor(Geometry g, ColorRGBA color) {
|
||||||
|
float[] colors = new float[g.getMesh().getVertexCount() * 4];
|
||||||
|
for (int i = 0; i < g.getMesh().getVertexCount() * 4; i += 4) {
|
||||||
|
colors[i] = color.r;
|
||||||
|
colors[i + 1] = color.g;
|
||||||
|
colors[i + 2] = color.b;
|
||||||
|
colors[i + 3] = color.a;
|
||||||
|
}
|
||||||
|
VertexBuffer colorBuff = g.getMesh().getBuffer(VertexBuffer.Type.Color);
|
||||||
|
if (colorBuff == null) {
|
||||||
|
g.getMesh().setBuffer(VertexBuffer.Type.Color, 4, colors);
|
||||||
|
} else {
|
||||||
|
FloatBuffer cBuff = (FloatBuffer) colorBuff.getData();
|
||||||
|
cBuff.rewind();
|
||||||
|
cBuff.put(colors);
|
||||||
|
colorBuff.updateData(cBuff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The method updates the geometry according to the positions of the bones.
|
||||||
|
*/
|
||||||
|
public void updateGeometry() {
|
||||||
|
armature.update();
|
||||||
|
for (Joint joint : armature.getRoots()) {
|
||||||
|
updateSkeletonGeoms(joint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,171 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2009-2018 jMonkeyEngine
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are
|
|
||||||
* met:
|
|
||||||
*
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
*
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
|
||||||
* may be used to endorse or promote products derived from this software
|
|
||||||
* without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
||||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
||||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
||||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
||||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
||||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
// $Id: Cylinder.java 4131 2009-03-19 20:15:28Z blaine.dev $
|
|
||||||
package com.jme3.scene.debug.custom;
|
|
||||||
|
|
||||||
import com.jme3.math.*;
|
|
||||||
import com.jme3.scene.VertexBuffer.Type;
|
|
||||||
import com.jme3.scene.shape.AbstractBox;
|
|
||||||
import com.jme3.util.BufferUtils;
|
|
||||||
|
|
||||||
import java.nio.FloatBuffer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A simple cylinder, defined by its height and radius.
|
|
||||||
* (Ported to jME3)
|
|
||||||
*
|
|
||||||
* @author Mark Powell
|
|
||||||
* @version $Revision: 4131 $, $Date: 2009-03-19 16:15:28 -0400 (Thu, 19 Mar 2009) $
|
|
||||||
*/
|
|
||||||
public class BoneShape extends AbstractBox {
|
|
||||||
|
|
||||||
private static Vector3f topN = new Vector3f(0, 1, 0);
|
|
||||||
private static Vector3f botN = new Vector3f(0, -1, 0);
|
|
||||||
private static Vector3f rigN = new Vector3f(1, 0, 0);
|
|
||||||
private static Vector3f lefN = new Vector3f(-1, 0, 0);
|
|
||||||
|
|
||||||
static {
|
|
||||||
Quaternion q = new Quaternion().fromAngleAxis(-FastMath.PI / 16f, Vector3f.UNIT_X);
|
|
||||||
q.multLocal(topN);
|
|
||||||
q.inverseLocal();
|
|
||||||
q.multLocal(botN);
|
|
||||||
q = new Quaternion().fromAngleAxis(FastMath.PI / 16f, Vector3f.UNIT_Y);
|
|
||||||
q.multLocal(rigN);
|
|
||||||
q.inverseLocal();
|
|
||||||
q.multLocal(lefN);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final short[] GEOMETRY_INDICES_DATA = {
|
|
||||||
2, 1, 0, 3, 2, 0, // back
|
|
||||||
6, 5, 4, 7, 6, 4, // right
|
|
||||||
10, 9, 8, 11, 10, 8, // front
|
|
||||||
14, 13, 12, 15, 14, 12, // left
|
|
||||||
18, 17, 16, 19, 18, 16, // top
|
|
||||||
22, 21, 20, 23, 22, 20 // bottom
|
|
||||||
};
|
|
||||||
|
|
||||||
private static final float[] GEOMETRY_NORMALS_DATA = {
|
|
||||||
0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, // back
|
|
||||||
rigN.x, rigN.y, rigN.z, rigN.x, rigN.y, rigN.z, rigN.x, rigN.y, rigN.z, rigN.x, rigN.y, rigN.z, // right
|
|
||||||
0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, // front
|
|
||||||
lefN.x, lefN.y, lefN.z, lefN.x, lefN.y, lefN.z, lefN.x, lefN.y, lefN.z, lefN.x, lefN.y, lefN.z, // left
|
|
||||||
topN.x, topN.y, topN.z, topN.x, topN.y, topN.z, topN.x, topN.y, topN.z, topN.x, topN.y, topN.z, // top
|
|
||||||
botN.x, botN.y, botN.z, botN.x, botN.y, botN.z, botN.x, botN.y, botN.z, botN.x, botN.y, botN.z // bottom
|
|
||||||
};
|
|
||||||
|
|
||||||
private static final float[] GEOMETRY_TEXTURE_DATA = {
|
|
||||||
1, 0, 0, 0, 0, 1, 1, 1, // back
|
|
||||||
1, 0, 0, 0, 0, 1, 1, 1, // right
|
|
||||||
1, 0, 0, 0, 0, 1, 1, 1, // front
|
|
||||||
1, 0, 0, 0, 0, 1, 1, 1, // left
|
|
||||||
1, 0, 0, 0, 0, 1, 1, 1, // top
|
|
||||||
1, 0, 0, 0, 0, 1, 1, 1 // bottom
|
|
||||||
};
|
|
||||||
|
|
||||||
private static final float[] GEOMETRY_POSITION_DATA = {
|
|
||||||
-0.5f, -0.5f, 0, 0.5f, -0.5f, 0, 0.5f, 0.5f, 0, -0.5f, 0.5f, 0, //back
|
|
||||||
0.5f, -0.5f, 0, 0.25f, -0.25f, 1, 0.25f, 0.25f, 1, 0.5f, 0.5f, 0, //right
|
|
||||||
0.25f, -0.25f, 1, -0.25f, -0.25f, 1, -0.25f, 0.25f, 1, 0.25f, 0.25f, 1, //front
|
|
||||||
-0.25f, -0.25f, 1, -0.5f, -0.5f, 0, -0.5f, 0.5f, 0, -0.25f, 0.25f, 1, //left
|
|
||||||
0.5f, 0.5f, 0, 0.25f, 0.25f, 1, -0.25f, 0.25f, 1, -0.5f, 0.5f, 0, // top
|
|
||||||
-0.5f, -0.5f, 0, -0.25f, -0.25f, 1, 0.25f, -0.25f, 1, 0.5f, -0.5f, 0 // bottom
|
|
||||||
};
|
|
||||||
|
|
||||||
//0,1,2,3
|
|
||||||
//1,4,6,2
|
|
||||||
//4,5,7,6
|
|
||||||
//5,0,3,7,
|
|
||||||
//2,6,7,3
|
|
||||||
//0,5,4,1
|
|
||||||
|
|
||||||
|
|
||||||
// v[0].x, v[0].y, v[0].z, v[1].x, v[1].y, v[1].z, v[2].x, v[2].y, v[2].z, v[3].x, v[3].y, v[3].z, // back
|
|
||||||
// v[1].x, v[1].y, v[1].z, v[4].x, v[4].y, v[4].z, v[6].x, v[6].y, v[6].z, v[2].x, v[2].y, v[2].z, // right
|
|
||||||
// v[4].x, v[4].y, v[4].z, v[5].x, v[5].y, v[5].z, v[7].x, v[7].y, v[7].z, v[6].x, v[6].y, v[6].z, // front
|
|
||||||
// v[5].x, v[5].y, v[5].z, v[0].x, v[0].y, v[0].z, v[3].x, v[3].y, v[3].z, v[7].x, v[7].y, v[7].z, // left
|
|
||||||
// v[2].x, v[2].y, v[2].z, v[6].x, v[6].y, v[6].z, v[7].x, v[7].y, v[7].z, v[3].x, v[3].y, v[3].z, // top
|
|
||||||
// v[0].x, v[0].y, v[0].z, v[5].x, v[5].y, v[5].z, v[4].x, v[4].y, v[4].z, v[1].x, v[1].y, v[1].z // bottom
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new box.
|
|
||||||
* <p>
|
|
||||||
* The box has a center of 0,0,0 and extends in the out from the center by
|
|
||||||
* the given amount in <em>each</em> direction. So, for example, a box
|
|
||||||
* with extent of 0.5 would be the unit cube.
|
|
||||||
*
|
|
||||||
* @param x the size of the box along the x axis, in both directions.
|
|
||||||
* @param y the size of the box along the y axis, in both directions.
|
|
||||||
* @param z the size of the box along the z axis, in both directions.
|
|
||||||
*/
|
|
||||||
public BoneShape() {
|
|
||||||
super();
|
|
||||||
updateGeometry();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a clone of this box.
|
|
||||||
* <p>
|
|
||||||
* The cloned box will have '_clone' appended to it's name, but all other
|
|
||||||
* properties will be the same as this box.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public BoneShape clone() {
|
|
||||||
return new BoneShape();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void doUpdateGeometryIndices() {
|
|
||||||
if (getBuffer(Type.Index) == null) {
|
|
||||||
setBuffer(Type.Index, 3, BufferUtils.createShortBuffer(GEOMETRY_INDICES_DATA));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void doUpdateGeometryNormals() {
|
|
||||||
if (getBuffer(Type.Normal) == null) {
|
|
||||||
setBuffer(Type.Normal, 3, BufferUtils.createFloatBuffer(GEOMETRY_NORMALS_DATA));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void doUpdateGeometryTextures() {
|
|
||||||
if (getBuffer(Type.TexCoord) == null) {
|
|
||||||
setBuffer(Type.TexCoord, 2, BufferUtils.createFloatBuffer(GEOMETRY_TEXTURE_DATA));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void doUpdateGeometryVertices() {
|
|
||||||
FloatBuffer fpb = BufferUtils.createVector3Buffer(24);
|
|
||||||
fpb.put(GEOMETRY_POSITION_DATA);
|
|
||||||
setBuffer(Type.Position, 3, fpb);
|
|
||||||
updateBound();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2010 jMonkeyEngine
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.jme3.scene.debug.custom;
|
||||||
|
|
||||||
|
import com.jme3.scene.Mesh;
|
||||||
|
import com.jme3.scene.VertexBuffer.Type;
|
||||||
|
|
||||||
|
|
||||||
|
public class JointShape extends Mesh {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serialization only. Do not use.
|
||||||
|
*/
|
||||||
|
public JointShape() {
|
||||||
|
float width = 1;
|
||||||
|
float height = 1;
|
||||||
|
setBuffer(Type.Position, 3, new float[]{-width * 0.5f, -width * 0.5f, 0,
|
||||||
|
width * 0.5f, -width * 0.5f, 0,
|
||||||
|
width * 0.5f, height * 0.5f, 0,
|
||||||
|
-width * 0.5f, height * 0.5f, 0
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
setBuffer(Type.TexCoord, 2, new float[]{0, 0,
|
||||||
|
1, 0,
|
||||||
|
1, 1,
|
||||||
|
0, 1});
|
||||||
|
|
||||||
|
setBuffer(Type.Normal, 3, new float[]{0, 0, 1,
|
||||||
|
0, 0, 1,
|
||||||
|
0, 0, 1,
|
||||||
|
0, 0, 1});
|
||||||
|
|
||||||
|
setBuffer(Type.Color, 4, new float[]{1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1});
|
||||||
|
|
||||||
|
setBuffer(Type.Index, 3, new short[]{0, 1, 2,
|
||||||
|
0, 2, 3});
|
||||||
|
|
||||||
|
|
||||||
|
updateBound();
|
||||||
|
setStatic();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
MaterialDef Billboard {
|
||||||
|
MaterialParameters {
|
||||||
|
Float SpriteHeight : 10
|
||||||
|
Texture2D Texture
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique {
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewMatrix
|
||||||
|
ProjectionMatrix
|
||||||
|
WorldMatrix
|
||||||
|
CameraDirection
|
||||||
|
ViewPort
|
||||||
|
CameraPosition
|
||||||
|
}
|
||||||
|
|
||||||
|
VertexShaderNodes {
|
||||||
|
ShaderNode TexCoord {
|
||||||
|
Definition: AttributeToVarying: Common/MatDefs/ShaderNodes/Basic/AttributeToVarying.j3sn
|
||||||
|
InputMappings {
|
||||||
|
vec2Variable = Attr.inTexCoord
|
||||||
|
vec4Variable = Attr.inColor
|
||||||
|
}
|
||||||
|
OutputMappings {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ShaderNode FixedScale {
|
||||||
|
Definition: FixedScale: Common/MatDefs/ShaderNodes/Common/FixedScale.j3sn
|
||||||
|
InputMappings {
|
||||||
|
projectionMatrix = WorldParam.ProjectionMatrix
|
||||||
|
worldMatrix = WorldParam.WorldMatrix
|
||||||
|
cameraDir = WorldParam.CameraDirection
|
||||||
|
viewport = WorldParam.ViewPort
|
||||||
|
modelPosition = Attr.inPosition
|
||||||
|
cameraPos = WorldParam.CameraPosition
|
||||||
|
spriteHeight = MatParam.SpriteHeight
|
||||||
|
}
|
||||||
|
OutputMappings {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ShaderNode Billboard {
|
||||||
|
Definition: Billboard: Common/MatDefs/ShaderNodes/Common/Billboard.j3sn
|
||||||
|
InputMappings {
|
||||||
|
worldViewMatrix = WorldParam.WorldViewMatrix
|
||||||
|
projectionMatrix = WorldParam.ProjectionMatrix
|
||||||
|
modelPosition = Attr.inPosition
|
||||||
|
scale = FixedScale.scale
|
||||||
|
}
|
||||||
|
OutputMappings {
|
||||||
|
Global.position = projPosition
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FragmentShaderNodes {
|
||||||
|
ShaderNode TextureFetch {
|
||||||
|
Definition: TextureFetch: Common/MatDefs/ShaderNodes/Basic/TextureFetch.j3sn
|
||||||
|
InputMappings {
|
||||||
|
textureMap = MatParam.Texture
|
||||||
|
texCoord = TexCoord.vec2Variable
|
||||||
|
}
|
||||||
|
OutputMappings {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ShaderNode ColorMult {
|
||||||
|
Definition: ColorMult: Common/MatDefs/ShaderNodes/Basic/ColorMult.j3sn
|
||||||
|
InputMappings {
|
||||||
|
color1 = TextureFetch.outColor
|
||||||
|
color2 = TexCoord.vec4Variable
|
||||||
|
}
|
||||||
|
OutputMappings {
|
||||||
|
Global.color = outColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
ShaderNodeDefinitions{
|
||||||
|
ShaderNodeDefinition Billboard {
|
||||||
|
//Vertex/Fragment
|
||||||
|
Type: Vertex
|
||||||
|
|
||||||
|
//Shader GLSL<version>: <Path to shader>
|
||||||
|
Shader GLSL100: Common/MatDefs/ShaderNodes/Common/Billboard100.frag
|
||||||
|
|
||||||
|
Documentation{
|
||||||
|
//type documentation here. This is optional but recommended
|
||||||
|
|
||||||
|
//@input <glsltype> <varName> <description>
|
||||||
|
@input mat4 worldViewMatrix The worldView matrix
|
||||||
|
@input mat4 projectionMatrix The projection matrix
|
||||||
|
@input vec3 modelPosition the vertex position
|
||||||
|
@input float scale the scale of the billboard (defautl 1)
|
||||||
|
|
||||||
|
//@output <glslType> <varName> <description>
|
||||||
|
@output vec4 projPosition The position in projection space
|
||||||
|
}
|
||||||
|
Input {
|
||||||
|
//all the node inputs
|
||||||
|
//<glslType> <varName>
|
||||||
|
mat4 worldViewMatrix
|
||||||
|
mat4 projectionMatrix
|
||||||
|
vec3 modelPosition
|
||||||
|
float scale 1
|
||||||
|
}
|
||||||
|
Output {
|
||||||
|
//all the node outputs
|
||||||
|
//<glslType> <varName>
|
||||||
|
vec4 projPosition
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
void main(){
|
||||||
|
// First colunm.
|
||||||
|
worldViewMatrix[0][0] = scale;
|
||||||
|
worldViewMatrix[0][1] = 0.0;
|
||||||
|
worldViewMatrix[0][2] = 0.0;
|
||||||
|
|
||||||
|
// Second colunm.
|
||||||
|
worldViewMatrix[1][0] = 0.0;
|
||||||
|
worldViewMatrix[1][1] = scale;
|
||||||
|
worldViewMatrix[1][2] = 0.0;
|
||||||
|
|
||||||
|
// Thrid colunm.
|
||||||
|
worldViewMatrix[2][0] = 0.0;
|
||||||
|
worldViewMatrix[2][1] = 0.0;
|
||||||
|
worldViewMatrix[2][2] = scale;
|
||||||
|
|
||||||
|
vec4 position = worldViewMatrix * vec4(modelPosition,1.0);
|
||||||
|
projPosition = projectionMatrix * position;
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
ShaderNodeDefinitions{
|
||||||
|
ShaderNodeDefinition FixedScale {
|
||||||
|
//Vertex/Fragment
|
||||||
|
Type: Vertex
|
||||||
|
|
||||||
|
//Shader GLSL<version>: <Path to shader>
|
||||||
|
Shader GLSL100: Common/MatDefs/ShaderNodes/Common/FixedScale100.frag
|
||||||
|
|
||||||
|
Documentation{
|
||||||
|
//type documentation here. This is optional but recommended
|
||||||
|
|
||||||
|
//@input <glsltype> <varName> <description>
|
||||||
|
@input vec4 viewport The viewport information (right, top, left, bottom)
|
||||||
|
@input vec3 cameraDir The direction of the camera
|
||||||
|
@input vec3 cameraPos The position of the camera
|
||||||
|
@input mat4 worldMatrix The world matrix
|
||||||
|
@input mat4 projectionMatrix The projection matrix
|
||||||
|
@input vec3 modelPosition the vertex position
|
||||||
|
@input float spriteHeight the desired image height in pixel
|
||||||
|
|
||||||
|
//@output <glslType> <varName> <description>
|
||||||
|
@output float scale The constant scale
|
||||||
|
}
|
||||||
|
Input {
|
||||||
|
//all the node inputs
|
||||||
|
//<glslType> <varName>
|
||||||
|
vec4 viewport
|
||||||
|
vec3 cameraDir
|
||||||
|
vec3 cameraPos
|
||||||
|
mat4 worldMatrix
|
||||||
|
mat4 projectionMatrix
|
||||||
|
vec3 modelPosition
|
||||||
|
float spriteHeight 10.0
|
||||||
|
}
|
||||||
|
Output {
|
||||||
|
//all the node outputs
|
||||||
|
//<glslType> <varName>
|
||||||
|
float scale
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
void main(){
|
||||||
|
vec4 worldPos = worldMatrix * vec4(modelPosition, 1.0);
|
||||||
|
vec3 dir = worldPos.xyz - cameraPos;
|
||||||
|
float distance = dot(cameraDir, dir);
|
||||||
|
float m11 = projectionMatrix[1][1];
|
||||||
|
float halfHeight = (viewport.w - viewport.y) * 0.5;
|
||||||
|
scale = ((distance/halfHeight) * spriteHeight)/m11;
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
ShaderNodeDefinitions{
|
||||||
|
ShaderNodeDefinition TexCoord {
|
||||||
|
//Vertex/Fragment
|
||||||
|
Type: Vertex
|
||||||
|
|
||||||
|
//Shader GLSL<version>: <Path to shader>
|
||||||
|
Shader GLSL100: Common/MatDefs/ShaderNodes/Common/texCoord100.frag
|
||||||
|
|
||||||
|
Documentation{
|
||||||
|
//type documentation here. This is optional but recommended
|
||||||
|
|
||||||
|
//@input <glsltype> <varName> <description>
|
||||||
|
@input vec2 texCoord The input texture Coord
|
||||||
|
@input vec2 texCoord2 The input texture Coord
|
||||||
|
@input vec2 texCoord3 The input texture Coord
|
||||||
|
@input vec2 texCoord4 The input texture Coord
|
||||||
|
@input vec2 texCoord5 The input texture Coord
|
||||||
|
@input vec2 texCoord6 The input texture Coord
|
||||||
|
@input vec2 texCoord7 The input texture Coord
|
||||||
|
@input vec2 texCoord8 The input texture Coord
|
||||||
|
|
||||||
|
//@output <glslType> <varName> <description>
|
||||||
|
@output vec2 texCoord The input texture Coord
|
||||||
|
@output vec2 texCoord2 The input texture Coord
|
||||||
|
@output vec2 texCoord3 The input texture Coord
|
||||||
|
@output vec2 texCoord4 The input texture Coord
|
||||||
|
@output vec2 texCoord5 The input texture Coord
|
||||||
|
@output vec2 texCoord6 The input texture Coord
|
||||||
|
@output vec2 texCoord7 The input texture Coord
|
||||||
|
@output vec2 texCoord8 The input texture Coord
|
||||||
|
}
|
||||||
|
Input {
|
||||||
|
//all the node inputs
|
||||||
|
//<glslType> <varName>
|
||||||
|
vec2 texCoord
|
||||||
|
vec2 texCoord2
|
||||||
|
vec2 texCoord3
|
||||||
|
vec2 texCoord4
|
||||||
|
vec2 texCoord5
|
||||||
|
vec2 texCoord6
|
||||||
|
vec2 texCoord7
|
||||||
|
vec2 texCoord8
|
||||||
|
}
|
||||||
|
Output {
|
||||||
|
//all the node outputs
|
||||||
|
//<glslType> <varName>
|
||||||
|
vec2 texCoord
|
||||||
|
vec2 texCoord2
|
||||||
|
vec2 texCoord3
|
||||||
|
vec2 texCoord4
|
||||||
|
vec2 texCoord5
|
||||||
|
vec2 texCoord6
|
||||||
|
vec2 texCoord7
|
||||||
|
vec2 texCoord8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
void main(){
|
||||||
|
}
|
BIN
jme3-core/src/main/resources/Common/Textures/dot.png
Normal file
BIN
jme3-core/src/main/resources/Common/Textures/dot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 367 B |
@ -40,12 +40,15 @@ public class TestArmature extends SimpleApplication {
|
|||||||
Joint root = new Joint("Root_Joint");
|
Joint root = new Joint("Root_Joint");
|
||||||
j1 = new Joint("Joint_1");
|
j1 = new Joint("Joint_1");
|
||||||
j2 = new Joint("Joint_2");
|
j2 = new Joint("Joint_2");
|
||||||
|
Joint j3 = new Joint("Joint_3");
|
||||||
root.addChild(j1);
|
root.addChild(j1);
|
||||||
j1.addChild(j2);
|
j1.addChild(j2);
|
||||||
|
j2.addChild(j3);
|
||||||
root.setLocalTranslation(new Vector3f(0, 0, 0.5f));
|
root.setLocalTranslation(new Vector3f(0, 0, 0.5f));
|
||||||
j1.setLocalTranslation(new Vector3f(0, 0.0f, -0.5f));
|
j1.setLocalTranslation(new Vector3f(0, 0.0f, -0.5f));
|
||||||
j2.setLocalTranslation(new Vector3f(0, 0.0f, -0.2f));
|
j2.setLocalTranslation(new Vector3f(0, 0.0f, -0.3f));
|
||||||
Joint[] joints = new Joint[]{root, j1, j2};
|
j3.setLocalTranslation(new Vector3f(0, 0, -0.2f));
|
||||||
|
Joint[] joints = new Joint[]{root, j1, j2, j3};
|
||||||
|
|
||||||
final Armature armature = new Armature(joints);
|
final Armature armature = new Armature(joints);
|
||||||
armature.setBindPose();
|
armature.setBindPose();
|
||||||
@ -64,16 +67,16 @@ public class TestArmature extends SimpleApplication {
|
|||||||
};
|
};
|
||||||
Vector3f[] scales = new Vector3f[]{
|
Vector3f[] scales = new Vector3f[]{
|
||||||
new Vector3f(1, 1, 1),
|
new Vector3f(1, 1, 1),
|
||||||
new Vector3f(2, 2, 2),
|
new Vector3f(1, 1, 2),
|
||||||
new Vector3f(1, 1, 1),
|
new Vector3f(1, 1, 1),
|
||||||
};
|
};
|
||||||
Vector3f[] scales2 = new Vector3f[]{
|
Vector3f[] scales2 = new Vector3f[]{
|
||||||
new Vector3f(1, 1, 1),
|
new Vector3f(1, 1, 1),
|
||||||
new Vector3f(0.5f, 0.5f, 0.5f),
|
new Vector3f(1, 1, 0.5f),
|
||||||
new Vector3f(1, 1, 1),
|
new Vector3f(1, 1, 1),
|
||||||
};
|
};
|
||||||
|
|
||||||
JointTrack track1 = new JointTrack(j1, times, null, rotations, null);
|
JointTrack track1 = new JointTrack(j1, times, null, rotations, scales);
|
||||||
JointTrack track2 = new JointTrack(j2, times, null, rotations, null);
|
JointTrack track2 = new JointTrack(j2, times, null, rotations, null);
|
||||||
clip.addTrack(track1);
|
clip.addTrack(track1);
|
||||||
clip.addTrack(track2);
|
clip.addTrack(track2);
|
||||||
@ -98,7 +101,7 @@ public class TestArmature extends SimpleApplication {
|
|||||||
composer.setCurrentAnimClip("anim");
|
composer.setCurrentAnimClip("anim");
|
||||||
|
|
||||||
ArmatureDebugAppState debugAppState = new ArmatureDebugAppState();
|
ArmatureDebugAppState debugAppState = new ArmatureDebugAppState();
|
||||||
debugAppState.addArmature(ac, true);
|
debugAppState.addArmature(ac);
|
||||||
stateManager.attach(debugAppState);
|
stateManager.attach(debugAppState);
|
||||||
|
|
||||||
rootNode.addLight(new DirectionalLight(new Vector3f(-1f, -1f, -1f).normalizeLocal()));
|
rootNode.addLight(new DirectionalLight(new Vector3f(-1f, -1f, -1f).normalizeLocal()));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user