trimesh.java
来自「java 3d game jme 工程开发源代码」· Java 代码 · 共 634 行 · 第 1/2 页
JAVA
634 行
/*
* 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.scene;
import java.io.IOException;
import java.io.Serializable;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.logging.Logger;
import com.jme.bounding.CollisionTree;
import com.jme.bounding.CollisionTreeManager;
import com.jme.intersection.CollisionResults;
import com.jme.math.FastMath;
import com.jme.math.Ray;
import com.jme.math.Triangle;
import com.jme.math.Vector3f;
import com.jme.renderer.Renderer;
import com.jme.system.JmeException;
import com.jme.util.export.InputCapsule;
import com.jme.util.export.JMEExporter;
import com.jme.util.export.JMEImporter;
import com.jme.util.export.OutputCapsule;
import com.jme.util.geom.BufferUtils;
/**
* <code>TriMesh</code> defines a geometry mesh. This mesh defines a three
* dimensional object via a collection of points, colors, normals and textures.
* The points are referenced via a indices array. This array instructs the
* renderer the order in which to draw the points, creating triangles based on the mode set.
*
* @author Mark Powell
* @author Joshua Slack
* @version $Id: TriMesh.java,v 1.69 2007/08/02 21:54:36 nca Exp $
*/
public class TriMesh extends Geometry implements Serializable {
private static final Logger logger = Logger.getLogger(TriMesh.class
.getName());
private static final long serialVersionUID = 2L;
public enum Mode {
/**
* Every three vertices referenced by the indexbuffer will be considered
* a stand-alone triangle.
*/
Triangles,
/**
* The first three vertices referenced by the indexbuffer create a
* triangle, from there, every additional vertex is paired with the two
* preceding vertices to make a new triangle.
*/
Strip,
/**
* The first three vertices (V0, V1, V2) referenced by the indexbuffer
* create a triangle, from there, every additional vertex is paired with
* the preceding vertex and the initial vertex (V0) to make a new
* triangle.
*/
Fan;
}
protected transient IntBuffer indexBuffer;
protected Mode mode = Mode.Triangles;
protected int triangleQuantity;
/**
* Empty Constructor to be used internally only.
*/
public TriMesh() {
super();
}
/**
* Constructor instantiates a new <code>TriMesh</code> object.
*
* @param name
* the name of the scene element. This is required for
* identification and comparision purposes.
*/
public TriMesh(String name) {
super(name);
}
/**
* Constructor instantiates a new <code>TriMesh</code> object. Provided
* are the attributes that make up the mesh all attributes may be null,
* except for vertices and indices.
*
* @param name
* the name of the scene element. This is required for
* identification and comparision purposes.
* @param vertices
* the vertices of the geometry.
* @param normal
* the normals of the geometry.
* @param color
* the colors of the geometry.
* @param coords
* the texture coordinates of the mesh.
* @param indices
* the indices of the vertex array.
*/
public TriMesh(String name, FloatBuffer vertices, FloatBuffer normal,
FloatBuffer color, TexCoords coords, IntBuffer indices) {
super(name);
reconstruct(vertices, normal, color, coords);
if (null == indices) {
logger.severe("Indices may not be null.");
throw new JmeException("Indices may not be null.");
}
setIndexBuffer(indices);
logger.info("TriMesh created.");
}
/**
* Recreates the geometric information of this TriMesh from scratch. The
* index and vertex array must not be null, but the others may be. Every 3
* indices define an index in the <code>vertices</code> array that
* refrences a vertex of a triangle.
*
* @param vertices
* The vertex information for this TriMesh.
* @param normal
* The normal information for this TriMesh.
* @param color
* The color information for this TriMesh.
* @param coords
* The texture information for this TriMesh.
* @param indices
* The index information for this TriMesh.
*/
public void reconstruct(FloatBuffer vertices, FloatBuffer normal,
FloatBuffer color, TexCoords coords, IntBuffer indices) {
super.reconstruct(vertices, normal, color, coords);
if (null == indices) {
logger.severe("Indices may not be null.");
throw new JmeException("Indices may not be null.");
}
setIndexBuffer(indices);
}
public void setMode(Mode mode) {
this.mode = mode;
}
public Mode getMode() {
return mode;
}
public IntBuffer getIndexBuffer() {
return indexBuffer;
}
public void setIndexBuffer(IntBuffer indices) {
this.indexBuffer = indices;
recalcTriangleQuantity();
}
protected void recalcTriangleQuantity() {
if (indexBuffer == null) {
triangleQuantity = 0;
return;
}
switch (mode) {
case Triangles:
triangleQuantity = indexBuffer.limit() / 3;
break;
case Strip:
case Fan:
triangleQuantity = indexBuffer.limit() - 2;
break;
}
}
/**
* Returns the number of triangles contained in this mesh.
*/
@Override
public int getTriangleCount() {
return triangleQuantity;
}
public void setTriangleQuantity(int triangleQuantity) {
this.triangleQuantity = triangleQuantity;
}
/**
* <code>draw</code> calls super to set the render state then passes
* itself to the renderer. LOGIC: 1. If we're not RenderQueue calling draw
* goto 2, if we are, goto 3 2. If we are supposed to use queue, add to
* queue and RETURN, else 3 3. call super draw 4. tell renderer to draw me.
*
* @param r
* the renderer to display
*/
public void draw(Renderer r) {
if (!r.isProcessingQueue()) {
if (r.checkAndAdd(this))
return;
}
super.draw(r);
r.draw(this);
}
/**
* Clears the buffers of this TriMesh. The buffers include its indexBuffer
* only.
*/
public void clearBuffers() {
super.clearBuffers();
setIndexBuffer(null);
}
/**
* determines if a collision between this trimesh and a given spatial occurs
* if it has true is returned, otherwise false is returned.
*/
public boolean hasCollision(Spatial scene, boolean checkTriangles) {
if (this == scene || !isCollidable || !scene.isCollidable()) {
return false;
}
if (getWorldBound().intersects(scene.getWorldBound())) {
if (scene instanceof Node) {
Node parent = (Node) scene;
for (int i = 0; i < parent.getQuantity(); i++) {
if (hasCollision(parent.getChild(i), checkTriangles)) {
return true;
}
}
return false;
}
if (!checkTriangles) {
return true;
}
return hasTriangleCollision((TriMesh) scene);
}
return false;
}
/**
* determines if this TriMesh has made contact with the give scene. The
* scene is recursively transversed until a trimesh is found, at which time
* the two trimesh OBBTrees are then compared to find the triangles that
* hit.
*/
public void findCollisions(Spatial scene, CollisionResults results) {
if (this == scene || !isCollidable || !scene.isCollidable()) {
return;
}
if (getWorldBound().intersects(scene.getWorldBound())) {
if (scene instanceof Node) {
Node parent = (Node) scene;
for (int i = 0; i < parent.getQuantity(); i++) {
findCollisions(parent.getChild(i), results);
}
} else {
results.addCollision(this, (Geometry) scene);
}
}
}
/**
* This function checks for intersection between this trimesh and the given
* one. On the first intersection, true is returned.
*
* @param toCheck
* The intersection testing mesh.
* @return True if they intersect.
*/
public boolean hasTriangleCollision(TriMesh toCheck) {
CollisionTree thisCT = CollisionTreeManager.getInstance()
.getCollisionTree(this);
CollisionTree checkCT = CollisionTreeManager.getInstance()
.getCollisionTree(toCheck);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?