1 /* 2 * Copyright (c) 2009-2010 jMonkeyEngine 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 package com.jme3.bullet.collision.shapes; 33 34 import com.jme3.bullet.util.NativeMeshUtil; 35 import com.jme3.export.InputCapsule; 36 import com.jme3.export.JmeExporter; 37 import com.jme3.export.JmeImporter; 38 import com.jme3.export.OutputCapsule; 39 import com.jme3.scene.Mesh; 40 import com.jme3.scene.VertexBuffer.Type; 41 import com.jme3.scene.mesh.IndexBuffer; 42 import com.jme3.util.BufferUtils; 43 import java.io.IOException; 44 import java.nio.ByteBuffer; 45 import java.nio.FloatBuffer; 46 import java.util.logging.Level; 47 import java.util.logging.Logger; 48 49 /** 50 * Basic mesh collision shape 51 * @author normenhansen 52 */ 53 public class GImpactCollisionShape extends CollisionShape { 54 55 // protected Vector3f worldScale; 56 protected int numVertices, numTriangles, vertexStride, triangleIndexStride; 57 protected ByteBuffer triangleIndexBase, vertexBase; 58 protected long meshId = 0; 59 // protected IndexedMesh bulletMesh; 60 GImpactCollisionShape()61 public GImpactCollisionShape() { 62 } 63 64 /** 65 * creates a collision shape from the given Mesh 66 * @param mesh the Mesh to use 67 */ GImpactCollisionShape(Mesh mesh)68 public GImpactCollisionShape(Mesh mesh) { 69 createCollisionMesh(mesh); 70 } 71 createCollisionMesh(Mesh mesh)72 private void createCollisionMesh(Mesh mesh) { 73 triangleIndexBase = BufferUtils.createByteBuffer(mesh.getTriangleCount() * 3 * 4); 74 vertexBase = BufferUtils.createByteBuffer(mesh.getVertexCount() * 3 * 4); 75 // triangleIndexBase = ByteBuffer.allocate(mesh.getTriangleCount() * 3 * 4); 76 // vertexBase = ByteBuffer.allocate(mesh.getVertexCount() * 3 * 4); 77 numVertices = mesh.getVertexCount(); 78 vertexStride = 12; //3 verts * 4 bytes per. 79 numTriangles = mesh.getTriangleCount(); 80 triangleIndexStride = 12; //3 index entries * 4 bytes each. 81 82 IndexBuffer indices = mesh.getIndexBuffer(); 83 FloatBuffer vertices = mesh.getFloatBuffer(Type.Position); 84 vertices.rewind(); 85 86 int verticesLength = mesh.getVertexCount() * 3; 87 for (int i = 0; i < verticesLength; i++) { 88 float tempFloat = vertices.get(); 89 vertexBase.putFloat(tempFloat); 90 } 91 92 int indicesLength = mesh.getTriangleCount() * 3; 93 for (int i = 0; i < indicesLength; i++) { 94 triangleIndexBase.putInt(indices.get(i)); 95 } 96 vertices.rewind(); 97 vertices.clear(); 98 99 createShape(); 100 } 101 102 // /** 103 // * creates a jme mesh from the collision shape, only needed for debugging 104 // */ 105 // public Mesh createJmeMesh() { 106 // return Converter.convert(bulletMesh); 107 // } write(JmeExporter ex)108 public void write(JmeExporter ex) throws IOException { 109 super.write(ex); 110 OutputCapsule capsule = ex.getCapsule(this); 111 // capsule.write(worldScale, "worldScale", new Vector3f(1, 1, 1)); 112 capsule.write(numVertices, "numVertices", 0); 113 capsule.write(numTriangles, "numTriangles", 0); 114 capsule.write(vertexStride, "vertexStride", 0); 115 capsule.write(triangleIndexStride, "triangleIndexStride", 0); 116 117 capsule.write(triangleIndexBase.array(), "triangleIndexBase", new byte[0]); 118 capsule.write(vertexBase.array(), "vertexBase", new byte[0]); 119 } 120 read(JmeImporter im)121 public void read(JmeImporter im) throws IOException { 122 super.read(im); 123 InputCapsule capsule = im.getCapsule(this); 124 // worldScale = (Vector3f) capsule.readSavable("worldScale", new Vector3f(1, 1, 1)); 125 numVertices = capsule.readInt("numVertices", 0); 126 numTriangles = capsule.readInt("numTriangles", 0); 127 vertexStride = capsule.readInt("vertexStride", 0); 128 triangleIndexStride = capsule.readInt("triangleIndexStride", 0); 129 130 triangleIndexBase = ByteBuffer.wrap(capsule.readByteArray("triangleIndexBase", new byte[0])); 131 vertexBase = ByteBuffer.wrap(capsule.readByteArray("vertexBase", new byte[0])); 132 createShape(); 133 } 134 createShape()135 protected void createShape() { 136 // bulletMesh = new IndexedMesh(); 137 // bulletMesh.numVertices = numVertices; 138 // bulletMesh.numTriangles = numTriangles; 139 // bulletMesh.vertexStride = vertexStride; 140 // bulletMesh.triangleIndexStride = triangleIndexStride; 141 // bulletMesh.triangleIndexBase = triangleIndexBase; 142 // bulletMesh.vertexBase = vertexBase; 143 // bulletMesh.triangleIndexBase = triangleIndexBase; 144 // TriangleIndexVertexArray tiv = new TriangleIndexVertexArray(numTriangles, triangleIndexBase, triangleIndexStride, numVertices, vertexBase, vertexStride); 145 // objectId = new GImpactMeshShape(tiv); 146 // objectId.setLocalScaling(Converter.convert(worldScale)); 147 // ((GImpactMeshShape)objectId).updateBound(); 148 // objectId.setLocalScaling(Converter.convert(getScale())); 149 // objectId.setMargin(margin); 150 meshId = NativeMeshUtil.createTriangleIndexVertexArray(triangleIndexBase, vertexBase, numTriangles, numVertices, vertexStride, triangleIndexStride); 151 Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Created Mesh {0}", Long.toHexString(meshId)); 152 objectId = createShape(meshId); 153 Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Created Shape {0}", Long.toHexString(objectId)); 154 setScale(scale); 155 setMargin(margin); 156 } 157 createShape(long meshId)158 private native long createShape(long meshId); 159 160 @Override finalize()161 protected void finalize() throws Throwable { 162 super.finalize(); 163 Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Finalizing Mesh {0}", Long.toHexString(meshId)); 164 finalizeNative(meshId); 165 } 166 finalizeNative(long objectId)167 private native void finalizeNative(long objectId); 168 } 169