debugger.java
来自「java 3d game jme 工程开发源代码」· Java 代码 · 共 681 行 · 第 1/2 页
JAVA
681 行
/*
* 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.geom;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import com.jme.animation.SkinNode;
import com.jme.bounding.BoundingBox;
import com.jme.bounding.BoundingCapsule;
import com.jme.bounding.BoundingSphere;
import com.jme.bounding.BoundingVolume;
import com.jme.bounding.OrientedBoundingBox;
import com.jme.image.Texture;
import com.jme.image.Texture2D;
import com.jme.math.FastMath;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.renderer.TextureRenderer;
import com.jme.scene.Geometry;
import com.jme.scene.Line;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.scene.shape.AxisRods;
import com.jme.scene.shape.Box;
import com.jme.scene.shape.Capsule;
import com.jme.scene.shape.OrientedBox;
import com.jme.scene.shape.Quad;
import com.jme.scene.shape.Sphere;
import com.jme.scene.state.BlendState;
import com.jme.scene.state.RenderState;
import com.jme.scene.state.TextureState;
import com.jme.scene.state.WireframeState;
import com.jme.scene.state.ZBufferState;
import com.jme.system.DisplaySystem;
/**
* <code>Debugger</code> provides tools for viewing scene data such as
* boundings and normals.
*
* @author Joshua Slack
* @author Emond Papegaaij (normals ideas and previous normal tool)
* @version $Id: Debugger.java,v 1.31 2007/09/21 15:45:28 nca Exp $
*/
public final class Debugger {
// -- **** METHODS FOR DRAWING BOUNDING VOLUMES **** -- //
private static final Sphere boundingSphere = new Sphere("bsphere", 10, 10, 1);
private static final Box boundingBox = new Box("bbox", new Vector3f(), 1, 1, 1);
private static final OrientedBox boundingOB = new OrientedBox("bobox");
private static final Capsule boundingCapsule = new Capsule("bcap", 3, 10, 10, 1, 1);
static {
boundingSphere.setRenderQueueMode(Renderer.QUEUE_SKIP);
boundingBox.setRenderQueueMode(Renderer.QUEUE_SKIP);
boundingOB.setRenderQueueMode(Renderer.QUEUE_SKIP);
boundingCapsule.setRenderQueueMode(Renderer.QUEUE_SKIP);
}
private static WireframeState boundsWireState;
private static ZBufferState boundsZState;
/**
* <code>drawBounds</code> draws the bounding volume for a given Spatial
* and its children.
*
* @param se
* the Spatial to draw boundings for.
* @param r
* the Renderer to use to draw the bounding.
*/
public static void drawBounds(Spatial se, Renderer r) {
drawBounds(se, r, true);
}
/**
* <code>drawBounds</code> draws the bounding volume for a given Spatial
* and optionally its children.
*
* @param se
* the Spatial to draw boundings for.
* @param r
* the Renderer to use to draw the bounding.
* @param doChildren
* if true, boundings for any children will also be drawn
*/
public static void drawBounds(Spatial se, Renderer r,
boolean doChildren) {
if (se == null)
return;
if (boundsWireState == null) {
boundsWireState = r.createWireframeState();
boundsZState = r.createZBufferState();
boundingBox.setRenderState(boundsWireState);
boundingBox.setRenderState(boundsZState);
boundingBox.updateRenderState();
boundingOB.setRenderState(boundsWireState);
boundingOB.setRenderState(boundsZState);
boundingOB.updateRenderState();
boundingSphere.setRenderState(boundsWireState);
boundingSphere.setRenderState(boundsZState);
boundingSphere.updateRenderState();
boundingCapsule.setRenderState(boundsWireState);
boundingCapsule.setRenderState(boundsZState);
boundingCapsule.updateRenderState();
}
if (se.getWorldBound() != null
&& se.getCullHint() != Spatial.CullHint.Always) {
int state = r.getCamera().getPlaneState();
if (r.getCamera().contains(se.getWorldBound()) != Camera.FrustumIntersect.Outside)
drawBounds(se.getWorldBound(), r);
else
doChildren = false;
r.getCamera().setPlaneState(state);
}
if (doChildren && se instanceof Node) {
Node n = (Node) se;
if (n.getChildren() != null) {
for (int i = n.getChildren().size(); --i >= 0;)
drawBounds(n.getChild(i), r, true);
}
}
}
private static void drawBounds(BoundingVolume bv, Renderer r) {
switch (bv.getType()) {
case AABB:
drawBoundingBox((BoundingBox) bv, r);
break;
case Sphere:
drawBoundingSphere((BoundingSphere) bv, r);
break;
case OBB:
drawOBB((OrientedBoundingBox) bv, r);
break;
case Capsule:
drawBoundingCapsule((BoundingCapsule) bv, r);
break;
default:
break;
}
}
public static void setBoundsColor(ColorRGBA color) {
boundingBox.setSolidColor(color);
boundingOB.setSolidColor(color);
boundingCapsule.setSolidColor(color);
boundingSphere.setSolidColor(color);
}
private static void drawBoundingSphere(BoundingSphere sphere, Renderer r) {
boundingSphere.getCenter().set(sphere.getCenter());
boundingSphere.updateGeometry(boundingSphere.getCenter(), 10, 10, sphere
.getRadius()); // pass back bs center to prevent accidently
// data access.
boundingSphere.draw(r);
}
private static void drawBoundingBox(BoundingBox box, Renderer r) {
boundingBox.getCenter().set(box.getCenter());
boundingBox.updateGeometry(boundingBox.getCenter(),
box.xExtent,
box.yExtent,
box.zExtent);
boundingBox.draw(r);
}
private static void drawOBB(OrientedBoundingBox box, Renderer r) {
boundingOB.getCenter().set(box.getCenter());
boundingOB.getXAxis().set(box.getXAxis());
boundingOB.getYAxis().set(box.getYAxis());
boundingOB.getZAxis().set(box.getZAxis());
boundingOB.getExtent().set(box.getExtent());
boundingOB.updateGeometry();
boundingOB.draw(r);
}
private static final Vector3f start = new Vector3f();
private static final Vector3f end = new Vector3f();
private static void drawBoundingCapsule(BoundingCapsule cap, Renderer r) {
boundingCapsule.updateGeometry(
cap.getLineSegment().getNegativeEnd(start),
cap.getLineSegment().getPositiveEnd(end),
cap.getRadius());
boundingCapsule.draw(r);
}
// -- **** METHODS FOR DRAWING NORMALS **** -- //
private static final Line normalLines = new Line("normLine");
static {
normalLines.setLineWidth(3.0f);
normalLines.setMode(Line.Mode.Segments);
normalLines.setVertexBuffer(BufferUtils.createVector3Buffer(500));
normalLines.setColorBuffer(BufferUtils.createColorBuffer(500));
}
private static final Vector3f _normalVect = new Vector3f();
private static ZBufferState normZState;
public static ColorRGBA NORMAL_COLOR_BASE = ColorRGBA.red.clone();
public static ColorRGBA NORMAL_COLOR_TIP = ColorRGBA.pink.clone();
public static ColorRGBA TANGENT_COLOR_BASE = ColorRGBA.red.clone();
public static BoundingBox measureBox = new BoundingBox();
public static float AUTO_NORMAL_RATIO = .05f;
/**
* <code>drawNormals</code> draws lines representing normals for a given
* Spatial and its children.
*
* @param element
* the Spatial to draw normals for.
* @param r
* the Renderer to use to draw the normals.
*/
public static void drawNormals(Spatial element, Renderer r) {
drawNormals(element, r, -1f, true);
}
public static void drawTangents(Spatial element, Renderer r) {
drawTangents(element, r, -1f, true);
}
/**
* <code>drawNormals</code> draws the normals for a given Spatial and
* optionally its children.
*
* @param element
* the Spatial to draw normals for.
* @param r
* the Renderer to use to draw the normals.
* @param size
* the length of the drawn normal (default is -1.0f which means
* autocalc based on boundings - if any).
* @param doChildren
* if true, normals for any children will also be drawn
*/
public static void drawNormals(Spatial element, Renderer r,
float size, boolean doChildren) {
if (element == null)
return;
if (normZState == null) {
normZState = r.createZBufferState();
normalLines.setRenderState(normZState);
normalLines.updateRenderState();
}
int state = r.getCamera().getPlaneState();
if (element.getWorldBound() != null
&& r.getCamera().contains(element.getWorldBound()) == Camera.FrustumIntersect.Outside) {
r.getCamera().setPlaneState(state);
return;
}
r.getCamera().setPlaneState(state);
if (element instanceof Geometry
&& element.getCullHint() != Spatial.CullHint.Always) {
Geometry geom = (Geometry) element;
float rSize = size;
if (rSize == -1) {
BoundingVolume vol = element.getWorldBound();
if (vol != null) {
measureBox.setCenter(vol.getCenter());
measureBox.xExtent = 0;
measureBox.yExtent = 0;
measureBox.zExtent = 0;
measureBox.mergeLocal(vol);
rSize = AUTO_NORMAL_RATIO
* ((measureBox.xExtent + measureBox.yExtent + measureBox.zExtent) / 3f);
} else
rSize = 1.0f;
}
FloatBuffer norms = geom.getNormalBuffer();
FloatBuffer verts = geom.getVertexBuffer();
if (norms != null && verts != null
&& norms.limit() == verts.limit()) {
FloatBuffer lineVerts = normalLines.getVertexBuffer();
if (lineVerts.capacity() < (3 * (2 * geom.getVertexCount()))) {
normalLines.setVertexBuffer(null);
System.gc();
lineVerts = BufferUtils.createVector3Buffer(geom
.getVertexCount() * 2);
normalLines.setVertexBuffer(lineVerts);
} else {
normalLines.setVertexCount(2 * geom.getVertexCount());
lineVerts.clear();
}
FloatBuffer lineColors = normalLines.getColorBuffer();
if (lineColors.capacity() < (4 * (2 * geom.getVertexCount()))) {
normalLines.setColorBuffer(null);
System.gc();
lineColors = BufferUtils.createColorBuffer(geom
.getVertexCount() * 2);
normalLines.setColorBuffer(lineColors);
} else {
lineColors.clear();
}
IntBuffer lineInds = normalLines.getIndexBuffer();
if (lineInds == null
|| lineInds.capacity() < (normalLines.getVertexCount())) {
normalLines.setIndexBuffer(null);
System.gc();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?