1%module btIndexedMesh 2 3%{ 4#include <BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h> 5%} 6 7%extend btIndexedMesh { 8 void setTriangleIndexBase(short *data) { 9 $self->m_triangleIndexBase = (unsigned char*)data; 10 } 11 void setVertexBase(float *data) { 12 $self->m_vertexBase = (unsigned char*)data; 13 } 14 void setVertices(float *vertices, int sizeInBytesOfEachVertex, int vertexCount, int positionOffsetInBytes) { 15 unsigned char *data = (unsigned char *)vertices; 16 $self->m_vertexBase = &(data[positionOffsetInBytes]); 17 $self->m_vertexStride = sizeInBytesOfEachVertex; 18 $self->m_numVertices = vertexCount; 19 $self->m_vertexType = PHY_FLOAT; 20 } 21 void setIndices(short *indices, int indexOffset, int indexCount) { 22 $self->m_triangleIndexBase = (unsigned char*)&(indices[indexOffset]); 23 $self->m_triangleIndexStride = 3 * sizeof(short); 24 $self->m_numTriangles = indexCount / 3; 25 $self->m_indexType = PHY_SHORT; 26 } 27}; 28 29%typemap(javaimports) btIndexedMesh %{ 30import com.badlogic.gdx.physics.bullet.BulletBase; 31import com.badlogic.gdx.physics.bullet.linearmath.*; 32import com.badlogic.gdx.graphics.Mesh; 33import com.badlogic.gdx.graphics.VertexAttribute; 34import com.badlogic.gdx.graphics.VertexAttributes.Usage; 35import com.badlogic.gdx.graphics.g3d.model.MeshPart; 36import com.badlogic.gdx.utils.Array; 37import com.badlogic.gdx.utils.GdxRuntimeException; 38import java.nio.FloatBuffer; 39import java.nio.ShortBuffer; 40%} 41 42%typemap(javacode) btIndexedMesh %{ 43 protected final static Array<btIndexedMesh> instances = new Array<btIndexedMesh>(); 44 protected static btIndexedMesh getInstance(final Object tag) { 45 final int n = instances.size; 46 for (int i = 0; i < n; i++) { 47 final btIndexedMesh mesh = instances.get(i); 48 if (tag.equals(mesh.tag)) 49 return mesh; 50 } 51 return null; 52 } 53 54 /** Create or reuse a btIndexedMesh instance based on the specified {@link MeshPart}. 55 * Use {@link #release()} to release the mesh when it's no longer needed. */ 56 public static btIndexedMesh obtain(final MeshPart meshPart) { 57 if (meshPart == null) 58 throw new GdxRuntimeException("meshPart cannot be null"); 59 60 btIndexedMesh result = getInstance(meshPart); 61 if (result == null) { 62 result = new btIndexedMesh(meshPart); 63 instances.add(result); 64 } 65 result.obtain(); 66 return result; 67 } 68 69 /** Create or reuse a btIndexedMesh instance based on the specified tag. 70 * Use {@link #release()} to release the mesh when it's no longer needed. */ 71 public static btIndexedMesh obtain(final Object tag, 72 final FloatBuffer vertices, int sizeInBytesOfEachVertex, int vertexCount, int positionOffsetInBytes, 73 final ShortBuffer indices, int indexOffset, int indexCount) { 74 if (tag == null) 75 throw new GdxRuntimeException("tag cannot be null"); 76 77 btIndexedMesh result = getInstance(tag); 78 if (result == null) { 79 result = new btIndexedMesh(vertices, sizeInBytesOfEachVertex, vertexCount, positionOffsetInBytes, indices, indexOffset, indexCount); 80 result.tag = tag; 81 instances.add(result); 82 } 83 result.obtain(); 84 return result; 85 } 86 87 /** The tag to identify this btIndexedMesh, may be null. Typically this is the {@link Mesh} or {@link MeshPart} used to create or set 88 * this btIndexedMesh. Use by the static obtain(...) methods to avoid creating duplicate instances. */ 89 public Object tag; 90 91 /** Construct a new btIndexedMesh based on the supplied {@link Mesh} 92 * The specified mesh must be indexed and triangulated and must outlive this btIndexedMesh. 93 * The buffers for the vertices and indices are shared amonst both. */ 94 public btIndexedMesh(final Mesh mesh) { 95 this(); 96 set(mesh); 97 } 98 99 /** Construct a new btIndexedMesh based on the supplied {@link MeshPart} 100 * The specified mesh must be indexed and triangulated and must outlive this btIndexedMesh. 101 * The buffers for the vertices and indices are shared amonst both. */ 102 public btIndexedMesh(final MeshPart meshPart) { 103 this(); 104 set(meshPart); 105 } 106 107 /** Construct a new btIndexedMesh based on the supplied {@link Mesh} 108 * The specified mesh must be indexed and triangulated and must outlive this btIndexedMesh. 109 * The buffers for the vertices and indices are shared amonst both. */ 110 public btIndexedMesh(final Mesh mesh, int offset, int count) { 111 this(); 112 set(mesh, offset, count); 113 } 114 115 /** Construct a new btIndexedMesh based on the supplied vertex and index data. 116 * The specified data must be indexed and triangulated and must outlive this btIndexedMesh. 117 * The buffers for the vertices and indices are shared amonst both. */ 118 public btIndexedMesh(final FloatBuffer vertices, int sizeInBytesOfEachVertex, int vertexCount, int positionOffsetInBytes, 119 final ShortBuffer indices, int indexOffset, int indexCount) { 120 this(); 121 set(vertices, sizeInBytesOfEachVertex, vertexCount, positionOffsetInBytes, indices, indexOffset, indexCount); 122 } 123 124 /** Convenience method to set this btIndexedMesh to the specified {@link Mesh} 125 * The specified mesh must be indexed and triangulated and must outlive this btIndexedMesh. 126 * The buffers for the vertices and indices are shared amonst both. */ 127 public void set(final Mesh mesh) { 128 set(mesh, mesh, 0, mesh.getNumIndices()); 129 } 130 131 /** Convenience method to set this btIndexedMesh to the specified {@link Mesh} 132 * The specified mesh must be indexed and triangulated and must outlive this btIndexedMesh. 133 * The buffers for the vertices and indices are shared amonst both. */ 134 public void set(final Object tag, final Mesh mesh) { 135 set(tag, mesh, 0, mesh.getNumIndices()); 136 } 137 138 /** Convenience method to set this btIndexedMesh to the specified {@link MeshPart} 139 * The specified mesh must be indexed and triangulated and must outlive this btIndexedMesh. 140 * The buffers for the vertices and indices are shared amonst both. */ 141 public void set(final MeshPart meshPart) { 142 if (meshPart.primitiveType != com.badlogic.gdx.graphics.GL20.GL_TRIANGLES) 143 throw new com.badlogic.gdx.utils.GdxRuntimeException("Mesh must be indexed and triangulated"); 144 set(meshPart, meshPart.mesh, meshPart.offset, meshPart.size); 145 } 146 147 /** Convenience method to set this btIndexedMesh to the specified {@link Mesh} 148 * The specified mesh must be indexed and triangulated and must outlive this btIndexedMesh. 149 * The buffers for the vertices and indices are shared amonst both. */ 150 public void set(final Mesh mesh, int offset, int count) { 151 set(null, mesh, offset, count); 152 } 153 154 /** Convenience method to set this btIndexedMesh to the specified {@link Mesh} 155 * The specified mesh must be indexed and triangulated and must outlive this btIndexedMesh. 156 * The buffers for the vertices and indices are shared amonst both. */ 157 public void set(final Object tag, final Mesh mesh, int offset, int count) { 158 if ((count <= 0) || ((count % 3) != 0)) 159 throw new com.badlogic.gdx.utils.GdxRuntimeException("Mesh must be indexed and triangulated"); 160 161 VertexAttribute posAttr = mesh.getVertexAttribute(Usage.Position); 162 163 if (posAttr == null) 164 throw new com.badlogic.gdx.utils.GdxRuntimeException("Mesh doesn't have a position attribute"); 165 166 set(tag, mesh.getVerticesBuffer(), mesh.getVertexSize(), mesh.getNumVertices(), posAttr.offset, mesh.getIndicesBuffer(), offset, count); 167 } 168 169 /** Convenience method to set this btIndexedMesh to the specified vertex and index data. 170 * The specified data must be indexed and triangulated and must outlive this btIndexedMesh. */ 171 public void set(final FloatBuffer vertices, int sizeInBytesOfEachVertex, int vertexCount, int positionOffsetInBytes, 172 final ShortBuffer indices, int indexOffset, int indexCount) { 173 set(null, vertices, sizeInBytesOfEachVertex, vertexCount, positionOffsetInBytes, indices, indexOffset, indexCount); 174 } 175 176 /** Convenience method to set this btIndexedMesh to the specified vertex and index data. 177 * The specified data must be indexed and triangulated and must outlive this btIndexedMesh. */ 178 public void set(final Object tag, 179 final FloatBuffer vertices, int sizeInBytesOfEachVertex, int vertexCount, int positionOffsetInBytes, 180 final ShortBuffer indices, int indexOffset, int indexCount) { 181 setVertices(vertices, sizeInBytesOfEachVertex, vertexCount, positionOffsetInBytes); 182 setIndices(indices, indexOffset, indexCount); 183 this.tag = tag; 184 } 185%} 186 187%rename(internalAddIndexedMesh) btTriangleIndexVertexArray::addIndexedMesh; 188%javamethodmodifiers btTriangleIndexVertexArray::addIndexedMesh "private"; 189%ignore btTriangleIndexVertexArray::btTriangleIndexVertexArray(int numTriangles,int* triangleIndexBase,int triangleIndexStride,int numVertices,btScalar* vertexBase,int vertexStride); 190%ignore btTriangleIndexVertexArray::getIndexedMeshArray(); 191 192%typemap(javaimports) btTriangleIndexVertexArray %{ 193import com.badlogic.gdx.physics.bullet.BulletBase; 194import com.badlogic.gdx.physics.bullet.linearmath.*; 195import com.badlogic.gdx.math.Vector3; 196import com.badlogic.gdx.math.Quaternion; 197import com.badlogic.gdx.math.Matrix3; 198import com.badlogic.gdx.math.Matrix4; 199import com.badlogic.gdx.graphics.Mesh; 200import com.badlogic.gdx.graphics.g3d.Model; 201import com.badlogic.gdx.graphics.g3d.model.MeshPart; 202import com.badlogic.gdx.graphics.g3d.model.NodePart; 203import com.badlogic.gdx.utils.Array; 204import com.badlogic.gdx.utils.GdxRuntimeException; 205%} 206 207%typemap(javacode) btTriangleIndexVertexArray %{ 208 protected final static Array<btTriangleIndexVertexArray> instances = new Array<btTriangleIndexVertexArray>(); 209 210 /** @return Whether the supplied array contains all specified tags. */ 211 public static <T extends Object> boolean compare(final btTriangleIndexVertexArray array, final Array<T> tags) { 212 if (array.meshes.size != tags.size) 213 return false; 214 for (final btIndexedMesh mesh : array.meshes) { 215 boolean found = false; 216 final Object tag = mesh.tag; 217 if (tag == null) 218 return false; 219 for (final T t : tags) { 220 if (t.equals(tag)) { 221 found = true; 222 break; 223 } 224 } 225 if (!found) 226 return false; 227 } 228 return true; 229 } 230 231 protected static <T extends Object> btTriangleIndexVertexArray getInstance(final Array<T> tags) { 232 for (final btTriangleIndexVertexArray instance : instances) { 233 if (compare(instance, tags)) 234 return instance; 235 } 236 return null; 237 } 238 239 /** Create or reuse a btTriangleIndexVertexArray instance based on the specified {@link MeshPart} array. 240 * Use {@link #release()} to release the mesh when it's no longer needed. */ 241 public static <T extends MeshPart> btTriangleIndexVertexArray obtain(final Array<T> meshParts) { 242 btTriangleIndexVertexArray result = getInstance(meshParts); 243 if (result == null) { 244 result = new btTriangleIndexVertexArray(meshParts); 245 instances.add(result); 246 } 247 result.obtain(); 248 return result; 249 } 250 251 protected final Array<btIndexedMesh> meshes = new Array<btIndexedMesh>(1); 252 253 public btTriangleIndexVertexArray(final MeshPart meshPart) { 254 this(); 255 addMeshPart(meshPart); 256 } 257 258 public <T extends MeshPart> btTriangleIndexVertexArray(final Iterable<T> meshParts) { 259 this(); 260 addMeshParts(meshParts); 261 } 262 263 /** The amount of meshes this array contains. */ 264 public int getIndexedMeshCount() { 265 return meshes.size; 266 } 267 268 /** Return the {@link btIndexedMesh} at the specified index. */ 269 public btIndexedMesh getIndexedMesh(int index) { 270 return meshes.get(index); 271 } 272 273 /** Add a {@link MeshPart} instance to this btTriangleIndexVertexArray. 274 * The specified mesh must be indexed and triangulated and must outlive this btTriangleIndexVertexArray. 275 * The buffers for the vertices and indices are shared amongst both. */ 276 public btTriangleIndexVertexArray addMeshPart(final MeshPart meshPart) { 277 btIndexedMesh mesh = btIndexedMesh.obtain(meshPart); 278 addIndexedMesh(mesh, PHY_ScalarType.PHY_SHORT); 279 mesh.release(); 280 return this; 281 } 282 283 /** Add one or more {@link MeshPart} instances to this btTriangleIndexVertexArray. 284 * The specified meshes must be indexed and triangulated and must outlive this btTriangleIndexVertexArray. 285 * The buffers for the vertices and indices are shared amongst both. */ 286 public btTriangleIndexVertexArray addMeshParts(final MeshPart... meshParts) { 287 for (int i = 0; i < meshParts.length; i++) 288 addMeshPart(meshParts[i]); 289 return this; 290 } 291 292 /** Add one or more {@link MeshPart} instances to this btTriangleIndexVertexArray. 293 * The specified meshes must be indexed and triangulated and must outlive this btTriangleIndexVertexArray. 294 * The buffers for the vertices and indices are shared amongst both. */ 295 public <T extends MeshPart> btTriangleIndexVertexArray addMeshParts(final Iterable<T> meshParts) { 296 for (final MeshPart meshPart : meshParts) 297 addMeshPart(meshPart); 298 return this; 299 } 300 301 /** Add one or more {@link NodePart} instances to this btTriangleIndexVertexArray. 302 * The specified meshes must be indexed and triangulated and must outlive this btTriangleIndexVertexArray. 303 * The buffers for the vertices and indices are shared amongst both. */ 304 public <T extends NodePart> btTriangleIndexVertexArray addNodeParts(final Iterable<T> nodeParts) { 305 for (final NodePart nodePart : nodeParts) 306 addMeshPart(nodePart.meshPart); 307 return this; 308 } 309 310 /** Add a {@link btIndexedMesh} to this array */ 311 public btTriangleIndexVertexArray addIndexedMesh(final btIndexedMesh mesh, int indexType) { 312 mesh.obtain(); 313 internalAddIndexedMesh(mesh, indexType); 314 meshes.add(mesh); 315 return this; 316 } 317 318 /** Add a {@link btIndexedMesh} to this array */ 319 public btTriangleIndexVertexArray addIndexedMesh(final btIndexedMesh mesh) { 320 return addIndexedMesh(mesh, PHY_ScalarType.PHY_SHORT); 321 } 322 323 @Override 324 public void dispose() { 325 for (final btIndexedMesh mesh : meshes) 326 mesh.release(); 327 meshes.clear(); 328 super.dispose(); 329 } 330%} 331 332%include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h" 333