bonedebugger.java
来自「java 3d game jme 工程开发源代码」· Java 代码 · 共 199 行
JAVA
199 行
/*
* Copyright (c) 2003-2009 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.jme.util;
import com.jme.animation.Bone;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.scene.shape.Box;
import com.jme.scene.shape.Cylinder;
import com.jme.scene.shape.Sphere;
import com.jme.scene.state.TextureState;
import com.jme.scene.state.ZBufferState;
/**
* BoneDebugger is responsible for visually representing a skeletal system (a
* heirarchy of Bone nodes). To visualize the skeleton, a Bone is represented
* as a red sphere and the connection between bones as a white cylinder. Additionally,
* hardpoints are presented as green boxes.
*
* Standard usage requires the passing in of the model that contains a skeleton
* to the drawBones method. This method will render the bones on screen as
* required.
*
* @see com.jme.animation.Bone
*
*/
public final class BoneDebugger {
private static Sphere boneSphere = new Sphere("boneSphere", new Vector3f(), 6, 6, .125f);
private static Box hardpointBox = new Box("hardpoint", new Vector3f(), 0.125f, 0.125f, 0.125f);
private static Cylinder boneCylinder = new Cylinder("boneCylinder", 3, 8, .03f, 1f);
static {
boneSphere.setLightCombineMode(Spatial.LightCombineMode.Off);
boneSphere.setTextureCombineMode(Spatial.TextureCombineMode.Off);
boneSphere.setSolidColor(ColorRGBA.red.clone());
boneSphere.setRenderQueueMode(Renderer.QUEUE_SKIP);
hardpointBox.setLightCombineMode(Spatial.LightCombineMode.Off);
hardpointBox.setTextureCombineMode(Spatial.TextureCombineMode.Off);
hardpointBox.setSolidColor(ColorRGBA.green.clone());
hardpointBox.setRenderQueueMode(Renderer.QUEUE_SKIP);
boneCylinder.setLightCombineMode(Spatial.LightCombineMode.Off);
boneCylinder.setTextureCombineMode(Spatial.TextureCombineMode.Off);
boneCylinder.setSolidColor(ColorRGBA.white.clone());
boneCylinder.setRenderQueueMode(Renderer.QUEUE_SKIP);
}
private static boolean inited = false;
private static Vector3f tempTrans = new Vector3f();
private static Vector3f tempScale = new Vector3f();
private static Quaternion tempRot = new Quaternion();
private static Quaternion tempQ = new Quaternion();
private static Vector3f tempA = new Vector3f();
private static Vector3f tempB = new Vector3f();
private static Vector3f tempC = new Vector3f();
private static Vector3f tempD = new Vector3f();
public static void drawBones(Spatial spat, Renderer r) {
drawBones(spat, r, true);
}
public static void drawBones(Spatial spat, Renderer r, boolean drawChildren) {
if (!inited) {
TextureState noTextureState = r.createTextureState();
noTextureState.setEnabled(false);
boneSphere.setRenderState(noTextureState);
hardpointBox.setRenderState(noTextureState);
boneCylinder.setRenderState(noTextureState);
ZBufferState noBufferState = r.createZBufferState();
noBufferState.setEnabled(true);
noBufferState.setWritable(true);
noBufferState.setFunction(ZBufferState.TestFunction.Always);
boneSphere.setRenderState(noBufferState);
hardpointBox.setRenderState(noBufferState);
boneCylinder.setRenderState(noBufferState);
boneSphere.updateRenderState();
boneSphere.updateGeometricState(0, false);
hardpointBox.updateRenderState();
hardpointBox.updateGeometricState(0, false);
boneCylinder.updateRenderState();
boneCylinder.updateGeometricState(0, false);
boneSphere.lockMeshes();
hardpointBox.lockMeshes();
boneCylinder.lockMeshes();
inited = true;
}
if (spat instanceof Bone) {
drawTheBones(null, (Bone)spat, r);
}
if ((spat instanceof Node) && drawChildren) {
Node n = (Node) spat;
for (int x = 0, count = n.getQuantity(); x < count; x++) {
drawBones(n.getChild(x), r, true);
}
}
}
private static void drawTheBones(Spatial skin, Bone bone, Renderer r) {
if(skin == null) {
tempTrans.set(0,0,0);
tempRot.set(0, 0, 0, 1);
tempScale.set(1,1,1);
} else {
tempTrans.set(skin.getWorldTranslation());
tempRot.set(skin.getWorldRotation());
tempScale.set(skin.getWorldScale());
}
if(bone.isHardpoint()) {
hardpointBox.getWorldTranslation().set(tempTrans).addLocal(tempRot.mult(bone.getWorldTranslation(), tempA));
hardpointBox.getWorldRotation().set(tempRot).multLocal(bone.getWorldRotation());
hardpointBox.getWorldScale().set(tempScale).multLocal(bone.getWorldScale());
hardpointBox.draw(r);
} else {
boneSphere.getWorldTranslation().set(tempTrans).addLocal(tempRot.mult(bone.getWorldTranslation(), tempA));
boneSphere.getWorldRotation().set(tempRot).multLocal(bone.getWorldRotation());
boneSphere.getWorldScale().set(tempScale).multLocal(bone.getWorldScale());
boneSphere.draw(r);
}
Vector3f here = tempA;
Vector3f there = tempB;
Vector3f diff = tempC;
if (bone.getQuantity() > 0) {
bone.localToWorld(Vector3f.ZERO, here);
float hX, hY, hZ;
hX = here.getX();
hY = here.getY();
hZ = here.getZ();
for (int x = 0, count = bone.getQuantity(); x < count; x++) {
Spatial child = bone.getChild(x);
if (child instanceof Bone) {
child.localToWorld(Vector3f.ZERO, there);
diff.set(there).subtractLocal(here);
float distance = here.distance(there);
boneCylinder.getWorldScale().set(1, 1, distance);
boneCylinder.getWorldTranslation().set(diff).multLocal(0.5f).addLocal(here);
tempD.set(boneCylinder.getWorldTranslation());
boneCylinder.getWorldTranslation().set(tempTrans).addLocal(tempRot.mult(tempD, tempD));
diff.normalizeLocal();
boneCylinder.getWorldRotation().set(bone.getWorldRotation()).lookAt(diff, Vector3f.UNIT_Z);
tempQ.set(boneCylinder.getWorldRotation());
boneCylinder.getWorldRotation().set(tempRot).multLocal(tempQ);
boneCylinder.draw(r);
drawTheBones(skin, (Bone)child, r);
here.set(hX, hY, hZ);
}
}
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?