quadmesh.java
来自「java 3d game jme 工程开发源代码」· Java 代码 · 共 392 行
JAVA
392 行
/*
* 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.logging.Logger;
import com.jme.intersection.CollisionResults;
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>QuadMesh</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 quads based on the mode set.
*
* @author Joshua Slack
* @version $Id: $
*/
public class QuadMesh extends Geometry implements Serializable {
private static final Logger logger = Logger.getLogger(QuadMesh.class
.getName());
private static final long serialVersionUID = 2L;
public enum Mode {
/**
* Every four vertices referenced by the indexbuffer will be considered
* a stand-alone quad.
*/
Quads,
/**
* The first four vertices referenced by the indexbuffer create a
* triangle, from there, every two additional vertices are paired with
* the two preceding vertices to make a new quad.
*/
Strip;
}
protected transient IntBuffer indexBuffer;
protected Mode mode = Mode.Quads;
protected int quadQuantity;
private static Vector3f[] quads;
/**
* Empty Constructor to be used internally only.
*/
public QuadMesh() {
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 QuadMesh(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 QuadMesh(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("QuadMesh 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;
recalcQuadQuantity();
}
protected void recalcQuadQuantity() {
if (indexBuffer == null) {
quadQuantity = 0;
return;
}
switch (mode) {
case Quads:
quadQuantity = indexBuffer.limit() / 4;
break;
case Strip:
quadQuantity = indexBuffer.limit() / 2 - 1;
break;
}
}
/**
* Returns the number of triangles contained in this mesh.
*/
public int getQuadCount() {
return quadQuantity;
}
public void setQuadQuantity(int quadQuantity) {
this.quadQuantity = quadQuantity;
}
/**
* Clears the buffers of this QuadMesh. The buffers include its indexBuffer
* only.
*/
public void clearBuffers() {
super.clearBuffers();
setIndexBuffer(null);
}
public static Vector3f[] getQuads() {
return quads;
}
public static void setQuads(Vector3f[] quads) {
QuadMesh.quads = quads;
}
/**
* Stores in the <code>storage</code> array the indices of quad
* <code>i</code>. If <code>i</code> is an invalid index, or if
* <code>storage.length<4</code>, then nothing happens
*
* @param i
* The index of the quad to get.
* @param storage
* The array that will hold the i's indexes.
*/
public void getQuad(int i, int[] storage) {
if (i < getQuadCount() && storage.length >= 4) {
IntBuffer indices = getIndexBuffer();
storage[0] = indices.get(getVertIndex(i, 0));
storage[1] = indices.get(getVertIndex(i, 1));
storage[2] = indices.get(getVertIndex(i, 2));
storage[3] = indices.get(getVertIndex(i, 3));
}
}
/**
* Stores in the <code>vertices</code> array the vertex values of quad
* <code>i</code>. If <code>i</code> is an invalid quad index,
* nothing happens.
*
* @param i
* @param vertices
*/
public void getQuad(int i, Vector3f[] vertices) {
if (i < getQuadCount() && i >= 0) {
for (int x = 0; x < 4; x++) {
if (vertices[x] == null)
vertices[x] = new Vector3f();
BufferUtils.populateFromBuffer(vertices[x], getVertexBuffer(),
getIndexBuffer().get(getVertIndex(i, x)));
}
}
}
/**
* Return this mesh object as quads. Every 4 vertices returned compose a
* single quad.
*
* @param verts
* a storage array to place the results in
* @return view of current mesh as group of quad vertices
*/
public Vector3f[] getMeshAsQuadsVertices(Vector3f[] verts) {
int maxCount = getQuadCount() * 4;
if (verts == null
|| verts.length != maxCount)
verts = new Vector3f[maxCount];
getIndexBuffer().rewind();
for (int i = 0; i < maxCount; i++) {
if (verts[i] == null)
verts[i] = new Vector3f();
int index = getVertIndex(i/4, i%4);
BufferUtils.populateFromBuffer(verts[i], getVertexBuffer(),
getIndexBuffer().get(index));
}
return verts;
}
protected int getVertIndex(int quad, int point) {
switch (mode) {
case Quads:
return quad * 4 + point;
case Strip:
return quad * 2 + point;
default:
throw new JmeException("mode is set to invalid type: "+mode);
}
}
public int getMaxIndex() {
if (indexBuffer == null) return -1;
switch (mode) {
case Quads:
return quadQuantity * 4;
case Strip:
return 2 + (quadQuantity * 2);
}
return 0;
}
/**
* Used with Serialization. Do not call this directly.
*
* @param s
* @throws IOException
* @see java.io.Serializable
*/
private void writeObject(java.io.ObjectOutputStream s) throws IOException {
s.defaultWriteObject();
if (getIndexBuffer() == null)
s.writeInt(0);
else {
s.writeInt(getIndexBuffer().limit());
getIndexBuffer().rewind();
for (int x = 0, len = getIndexBuffer().limit(); x < len; x++)
s.writeInt(getIndexBuffer().get());
}
}
/**
* Used with Serialization. Do not call this directly.
*
* @param s
* @throws IOException
* @throws ClassNotFoundException
* @see java.io.Serializable
*/
private void readObject(java.io.ObjectInputStream s) throws IOException,
ClassNotFoundException {
s.defaultReadObject();
int len = s.readInt();
if (len == 0) {
setIndexBuffer(null);
} else {
IntBuffer buf = BufferUtils.createIntBuffer(len);
for (int x = 0; x < len; x++)
buf.put(s.readInt());
setIndexBuffer(buf);
}
}
public void write(JMEExporter e) throws IOException {
super.write(e);
OutputCapsule capsule = e.getCapsule(this);
capsule.write(indexBuffer, "indexBuffer", null);
capsule.write(mode, "mode", Mode.Quads);
}
public void read(JMEImporter e) throws IOException {
super.read(e);
InputCapsule capsule = e.getCapsule(this);
indexBuffer = capsule.readIntBuffer("indexBuffer", null);
recalcQuadQuantity();
mode = (Mode) capsule.readEnum("mode", Mode.class, Mode.Quads);
}
public void draw(Renderer r) {
if (!r.isProcessingQueue()) {
if (r.checkAndAdd(this))
return;
}
r.draw(this);
}
@Override
public void findCollisions(Spatial scene, CollisionResults results) {
; // unsupported
}
@Override
public boolean hasCollision(Spatial scene, boolean checkTriangles) {
return false;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?