159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/* 259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Copyright (c) 2009-2010 jMonkeyEngine 359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * All rights reserved. 459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Redistribution and use in source and binary forms, with or without 659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * modification, are permitted provided that the following conditions are 759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * met: 859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions of source code must retain the above copyright 1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * notice, this list of conditions and the following disclaimer. 1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions in binary form must reproduce the above copyright 1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * notice, this list of conditions and the following disclaimer in the 1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * documentation and/or other materials provided with the distribution. 1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Neither the name of 'jMonkeyEngine' nor the names of its contributors 1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * may be used to endorse or promote products derived from this software 1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * without specific prior written permission. 1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage com.jme3.bullet.collision.shapes; 3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.bullet.util.NativeMeshUtil; 3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.InputCapsule; 3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.JmeExporter; 3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.JmeImporter; 3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.OutputCapsule; 3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.Mesh; 4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.VertexBuffer.Type; 4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.mesh.IndexBuffer; 4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.util.BufferUtils; 4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.io.IOException; 4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.nio.ByteBuffer; 4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.nio.ByteOrder; 4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.nio.FloatBuffer; 4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.logging.Level; 4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.logging.Logger; 4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/** 5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Basic mesh collision shape 5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @author normenhansen 5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapublic class MeshCollisionShape extends CollisionShape { 5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta protected int numVertices, numTriangles, vertexStride, triangleIndexStride; 5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta protected ByteBuffer triangleIndexBase, vertexBase; 5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta protected long meshId = 0; 5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public MeshCollisionShape() { 6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * creates a collision shape from the given TriMesh 6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param mesh the TriMesh to use 6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public MeshCollisionShape(Mesh mesh) { 6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta createCollisionMesh(mesh); 6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private void createCollisionMesh(Mesh mesh) { 7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta triangleIndexBase = BufferUtils.createByteBuffer(mesh.getTriangleCount() * 3 * 4); 7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vertexBase = BufferUtils.createByteBuffer(mesh.getVertexCount() * 3 * 4); 7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta numVertices = mesh.getVertexCount(); 7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vertexStride = 12; //3 verts * 4 bytes per. 7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta numTriangles = mesh.getTriangleCount(); 7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta triangleIndexStride = 12; //3 index entries * 4 bytes each. 7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta IndexBuffer indices = mesh.getIndexBuffer(); 8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta FloatBuffer vertices = mesh.getFloatBuffer(Type.Position); 8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vertices.rewind(); 8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int verticesLength = mesh.getVertexCount() * 3; 8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int i = 0; i < verticesLength; i++) { 8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float tempFloat = vertices.get(); 8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vertexBase.putFloat(tempFloat); 8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int indicesLength = mesh.getTriangleCount() * 3; 9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int i = 0; i < indicesLength; i++) { 9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta triangleIndexBase.putInt(indices.get(i)); 9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vertices.rewind(); 9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vertices.clear(); 9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta createShape(); 9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * creates a jme mesh from the collision shape, only needed for debugging 10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// public Mesh createJmeMesh(){ 10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// return Converter.convert(bulletMesh); 10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// } 10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void write(JmeExporter ex) throws IOException { 10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta super.write(ex); 10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta OutputCapsule capsule = ex.getCapsule(this); 10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta capsule.write(numVertices, "numVertices", 0); 10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta capsule.write(numTriangles, "numTriangles", 0); 11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta capsule.write(vertexStride, "vertexStride", 0); 11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta capsule.write(triangleIndexStride, "triangleIndexStride", 0); 11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta capsule.write(triangleIndexBase.array(), "triangleIndexBase", new byte[0]); 11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta capsule.write(vertexBase.array(), "vertexBase", new byte[0]); 11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void read(JmeImporter im) throws IOException { 11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta super.read(im); 11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta InputCapsule capsule = im.getCapsule(this); 12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta numVertices = capsule.readInt("numVertices", 0); 12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta numTriangles = capsule.readInt("numTriangles", 0); 12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vertexStride = capsule.readInt("vertexStride", 0); 12359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta triangleIndexStride = capsule.readInt("triangleIndexStride", 0); 12459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 12559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta triangleIndexBase = ByteBuffer.wrap(capsule.readByteArray("triangleIndexBase", new byte[0])); 12659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vertexBase = ByteBuffer.wrap(capsule.readByteArray("vertexBase", new byte[0])).order(ByteOrder.nativeOrder()); 12759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta createShape(); 12859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 12959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 13059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta protected void createShape() { 13159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// bulletMesh = new IndexedMesh(); 13259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// bulletMesh.numVertices = numVertices; 13359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// bulletMesh.numTriangles = numTriangles; 13459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// bulletMesh.vertexStride = vertexStride; 13559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// bulletMesh.triangleIndexStride = triangleIndexStride; 13659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// bulletMesh.triangleIndexBase = triangleIndexBase; 13759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// bulletMesh.vertexBase = vertexBase; 13859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// bulletMesh.triangleIndexBase = triangleIndexBase; 13959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// TriangleIndexVertexArray tiv = new TriangleIndexVertexArray(numTriangles, triangleIndexBase, triangleIndexStride, numVertices, vertexBase, vertexStride); 14059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// objectId = new BvhTriangleMeshShape(tiv, true); 14159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// objectId.setLocalScaling(Converter.convert(getScale())); 14259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// objectId.setMargin(margin); 14359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta meshId = NativeMeshUtil.createTriangleIndexVertexArray(triangleIndexBase, vertexBase, numTriangles, numVertices, vertexStride, triangleIndexStride); 14459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Created Mesh {0}", Long.toHexString(meshId)); 14559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta objectId = createShape(meshId); 14659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Created Shape {0}", Long.toHexString(objectId)); 14759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta setScale(scale); 14859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta setMargin(margin); 14959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 15059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 15159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private native long createShape(long meshId); 15259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 15359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta @Override 15459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta protected void finalize() throws Throwable { 15559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta super.finalize(); 15659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Finalizing Mesh {0}", Long.toHexString(meshId)); 15759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta finalizeNative(meshId); 15859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 15959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 16059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private native void finalizeNative(long objectId); 16159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta} 162