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