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 */ 32package com.jme3.bullet.collision.shapes; 33 34import com.jme3.bullet.util.NativeMeshUtil; 35import com.jme3.export.InputCapsule; 36import com.jme3.export.JmeExporter; 37import com.jme3.export.JmeImporter; 38import com.jme3.export.OutputCapsule; 39import com.jme3.scene.Mesh; 40import com.jme3.scene.VertexBuffer.Type; 41import com.jme3.scene.mesh.IndexBuffer; 42import com.jme3.util.BufferUtils; 43import java.io.IOException; 44import java.nio.ByteBuffer; 45import java.nio.FloatBuffer; 46import java.util.logging.Level; 47import java.util.logging.Logger; 48 49/** 50 * Basic mesh collision shape 51 * @author normenhansen 52 */ 53public 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 61 public GImpactCollisionShape() { 62 } 63 64 /** 65 * creates a collision shape from the given Mesh 66 * @param mesh the Mesh to use 67 */ 68 public GImpactCollisionShape(Mesh mesh) { 69 createCollisionMesh(mesh); 70 } 71 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// } 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 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 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 158 private native long createShape(long meshId); 159 160 @Override 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 167 private native void finalizeNative(long objectId); 168} 169