2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
11 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
16 #include "btStridingMeshInterface.h"
17 #include "LinearMath/btSerializer.h"
19 btStridingMeshInterface::~btStridingMeshInterface()
23 void btStridingMeshInterface::InternalProcessAllTriangles(btInternalTriangleIndexCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax) const
27 int numtotalphysicsverts = 0;
28 int part, graphicssubparts = getNumSubParts();
29 const unsigned char* vertexbase;
30 const unsigned char* indexbase;
33 PHY_ScalarType gfxindextype;
34 int stride, numverts, numtriangles;
36 btVector3 triangle[3];
38 btVector3 meshScaling = getScaling();
40 ///if the number of parts is big, the performance might drop due to the innerloop switch on indextype
41 for (part = 0; part < graphicssubparts; part++)
43 getLockedReadOnlyVertexIndexBase(&vertexbase, numverts, type, stride, &indexbase, indexstride, numtriangles, gfxindextype, part);
44 numtotalphysicsverts += numtriangles * 3; //upper bound
46 ///unlike that developers want to pass in double-precision meshes in single-precision Bullet build
47 ///so disable this feature by default
48 ///see patch http://code.google.com/p/bullet/issues/detail?id=213
60 for (gfxindex = 0; gfxindex < numtriangles; gfxindex++)
62 unsigned int* tri_indices = (unsigned int*)(indexbase + gfxindex * indexstride);
63 graphicsbase = (float*)(vertexbase + tri_indices[0] * stride);
64 triangle[0].setValue(graphicsbase[0] * meshScaling.getX(), graphicsbase[1] * meshScaling.getY(), graphicsbase[2] * meshScaling.getZ());
65 graphicsbase = (float*)(vertexbase + tri_indices[1] * stride);
66 triangle[1].setValue(graphicsbase[0] * meshScaling.getX(), graphicsbase[1] * meshScaling.getY(), graphicsbase[2] * meshScaling.getZ());
67 graphicsbase = (float*)(vertexbase + tri_indices[2] * stride);
68 triangle[2].setValue(graphicsbase[0] * meshScaling.getX(), graphicsbase[1] * meshScaling.getY(), graphicsbase[2] * meshScaling.getZ());
69 callback->internalProcessTriangleIndex(triangle, part, gfxindex);
75 for (gfxindex = 0; gfxindex < numtriangles; gfxindex++)
77 unsigned short int* tri_indices = (unsigned short int*)(indexbase + gfxindex * indexstride);
78 graphicsbase = (float*)(vertexbase + tri_indices[0] * stride);
79 triangle[0].setValue(graphicsbase[0] * meshScaling.getX(), graphicsbase[1] * meshScaling.getY(), graphicsbase[2] * meshScaling.getZ());
80 graphicsbase = (float*)(vertexbase + tri_indices[1] * stride);
81 triangle[1].setValue(graphicsbase[0] * meshScaling.getX(), graphicsbase[1] * meshScaling.getY(), graphicsbase[2] * meshScaling.getZ());
82 graphicsbase = (float*)(vertexbase + tri_indices[2] * stride);
83 triangle[2].setValue(graphicsbase[0] * meshScaling.getX(), graphicsbase[1] * meshScaling.getY(), graphicsbase[2] * meshScaling.getZ());
84 callback->internalProcessTriangleIndex(triangle, part, gfxindex);
90 for (gfxindex = 0; gfxindex < numtriangles; gfxindex++)
92 unsigned char* tri_indices = (unsigned char*)(indexbase + gfxindex * indexstride);
93 graphicsbase = (float*)(vertexbase + tri_indices[0] * stride);
94 triangle[0].setValue(graphicsbase[0] * meshScaling.getX(), graphicsbase[1] * meshScaling.getY(), graphicsbase[2] * meshScaling.getZ());
95 graphicsbase = (float*)(vertexbase + tri_indices[1] * stride);
96 triangle[1].setValue(graphicsbase[0] * meshScaling.getX(), graphicsbase[1] * meshScaling.getY(), graphicsbase[2] * meshScaling.getZ());
97 graphicsbase = (float*)(vertexbase + tri_indices[2] * stride);
98 triangle[2].setValue(graphicsbase[0] * meshScaling.getX(), graphicsbase[1] * meshScaling.getY(), graphicsbase[2] * meshScaling.getZ());
99 callback->internalProcessTriangleIndex(triangle, part, gfxindex);
104 btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT));
111 double* graphicsbase;
113 switch (gfxindextype)
117 for (gfxindex = 0; gfxindex < numtriangles; gfxindex++)
119 unsigned int* tri_indices = (unsigned int*)(indexbase + gfxindex * indexstride);
120 graphicsbase = (double*)(vertexbase + tri_indices[0] * stride);
121 triangle[0].setValue((btScalar)graphicsbase[0] * meshScaling.getX(), (btScalar)graphicsbase[1] * meshScaling.getY(), (btScalar)graphicsbase[2] * meshScaling.getZ());
122 graphicsbase = (double*)(vertexbase + tri_indices[1] * stride);
123 triangle[1].setValue((btScalar)graphicsbase[0] * meshScaling.getX(), (btScalar)graphicsbase[1] * meshScaling.getY(), (btScalar)graphicsbase[2] * meshScaling.getZ());
124 graphicsbase = (double*)(vertexbase + tri_indices[2] * stride);
125 triangle[2].setValue((btScalar)graphicsbase[0] * meshScaling.getX(), (btScalar)graphicsbase[1] * meshScaling.getY(), (btScalar)graphicsbase[2] * meshScaling.getZ());
126 callback->internalProcessTriangleIndex(triangle, part, gfxindex);
132 for (gfxindex = 0; gfxindex < numtriangles; gfxindex++)
134 unsigned short int* tri_indices = (unsigned short int*)(indexbase + gfxindex * indexstride);
135 graphicsbase = (double*)(vertexbase + tri_indices[0] * stride);
136 triangle[0].setValue((btScalar)graphicsbase[0] * meshScaling.getX(), (btScalar)graphicsbase[1] * meshScaling.getY(), (btScalar)graphicsbase[2] * meshScaling.getZ());
137 graphicsbase = (double*)(vertexbase + tri_indices[1] * stride);
138 triangle[1].setValue((btScalar)graphicsbase[0] * meshScaling.getX(), (btScalar)graphicsbase[1] * meshScaling.getY(), (btScalar)graphicsbase[2] * meshScaling.getZ());
139 graphicsbase = (double*)(vertexbase + tri_indices[2] * stride);
140 triangle[2].setValue((btScalar)graphicsbase[0] * meshScaling.getX(), (btScalar)graphicsbase[1] * meshScaling.getY(), (btScalar)graphicsbase[2] * meshScaling.getZ());
141 callback->internalProcessTriangleIndex(triangle, part, gfxindex);
147 for (gfxindex = 0; gfxindex < numtriangles; gfxindex++)
149 unsigned char* tri_indices = (unsigned char*)(indexbase + gfxindex * indexstride);
150 graphicsbase = (double*)(vertexbase + tri_indices[0] * stride);
151 triangle[0].setValue((btScalar)graphicsbase[0] * meshScaling.getX(), (btScalar)graphicsbase[1] * meshScaling.getY(), (btScalar)graphicsbase[2] * meshScaling.getZ());
152 graphicsbase = (double*)(vertexbase + tri_indices[1] * stride);
153 triangle[1].setValue((btScalar)graphicsbase[0] * meshScaling.getX(), (btScalar)graphicsbase[1] * meshScaling.getY(), (btScalar)graphicsbase[2] * meshScaling.getZ());
154 graphicsbase = (double*)(vertexbase + tri_indices[2] * stride);
155 triangle[2].setValue((btScalar)graphicsbase[0] * meshScaling.getX(), (btScalar)graphicsbase[1] * meshScaling.getY(), (btScalar)graphicsbase[2] * meshScaling.getZ());
156 callback->internalProcessTriangleIndex(triangle, part, gfxindex);
161 btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT));
166 btAssert((type == PHY_FLOAT) || (type == PHY_DOUBLE));
169 unLockReadOnlyVertexBase(part);
173 void btStridingMeshInterface::calculateAabbBruteForce(btVector3& aabbMin, btVector3& aabbMax)
175 struct AabbCalculationCallback : public btInternalTriangleIndexCallback
180 AabbCalculationCallback()
182 m_aabbMin.setValue(btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT));
183 m_aabbMax.setValue(btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT));
186 virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex)
191 m_aabbMin.setMin(triangle[0]);
192 m_aabbMax.setMax(triangle[0]);
193 m_aabbMin.setMin(triangle[1]);
194 m_aabbMax.setMax(triangle[1]);
195 m_aabbMin.setMin(triangle[2]);
196 m_aabbMax.setMax(triangle[2]);
200 //first calculate the total aabb for all triangles
201 AabbCalculationCallback aabbCallback;
202 aabbMin.setValue(btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT));
203 aabbMax.setValue(btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT));
204 InternalProcessAllTriangles(&aabbCallback, aabbMin, aabbMax);
206 aabbMin = aabbCallback.m_aabbMin;
207 aabbMax = aabbCallback.m_aabbMax;
210 ///fills the dataBuffer and returns the struct name (and 0 on failure)
211 const char* btStridingMeshInterface::serialize(void* dataBuffer, btSerializer* serializer) const
213 btStridingMeshInterfaceData* trimeshData = (btStridingMeshInterfaceData*)dataBuffer;
215 trimeshData->m_numMeshParts = getNumSubParts();
217 //void* uniquePtr = 0;
219 trimeshData->m_meshPartsPtr = 0;
221 if (trimeshData->m_numMeshParts)
223 btChunk* chunk = serializer->allocate(sizeof(btMeshPartData), trimeshData->m_numMeshParts);
224 btMeshPartData* memPtr = (btMeshPartData*)chunk->m_oldPtr;
225 trimeshData->m_meshPartsPtr = (btMeshPartData*)serializer->getUniquePointer(memPtr);
227 // int numtotalphysicsverts = 0;
228 int part, graphicssubparts = getNumSubParts();
229 const unsigned char* vertexbase;
230 const unsigned char* indexbase;
233 PHY_ScalarType gfxindextype;
234 int stride, numverts, numtriangles;
236 // btVector3 triangle[3];
238 // btVector3 meshScaling = getScaling();
240 ///if the number of parts is big, the performance might drop due to the innerloop switch on indextype
241 for (part = 0; part < graphicssubparts; part++, memPtr++)
243 getLockedReadOnlyVertexIndexBase(&vertexbase, numverts, type, stride, &indexbase, indexstride, numtriangles, gfxindextype, part);
244 memPtr->m_numTriangles = numtriangles; //indices = 3*numtriangles
245 memPtr->m_numVertices = numverts;
246 memPtr->m_indices16 = 0;
247 memPtr->m_indices32 = 0;
248 memPtr->m_3indices16 = 0;
249 memPtr->m_3indices8 = 0;
250 memPtr->m_vertices3f = 0;
251 memPtr->m_vertices3d = 0;
253 switch (gfxindextype)
257 int numindices = numtriangles * 3;
261 btChunk* chunk = serializer->allocate(sizeof(btIntIndexData), numindices);
262 btIntIndexData* tmpIndices = (btIntIndexData*)chunk->m_oldPtr;
263 memPtr->m_indices32 = (btIntIndexData*)serializer->getUniquePointer(tmpIndices);
264 for (gfxindex = 0; gfxindex < numtriangles; gfxindex++)
266 unsigned int* tri_indices = (unsigned int*)(indexbase + gfxindex * indexstride);
267 tmpIndices[gfxindex * 3].m_value = tri_indices[0];
268 tmpIndices[gfxindex * 3 + 1].m_value = tri_indices[1];
269 tmpIndices[gfxindex * 3 + 2].m_value = tri_indices[2];
271 serializer->finalizeChunk(chunk, "btIntIndexData", BT_ARRAY_CODE, (void*)chunk->m_oldPtr);
279 btChunk* chunk = serializer->allocate(sizeof(btShortIntIndexTripletData), numtriangles);
280 btShortIntIndexTripletData* tmpIndices = (btShortIntIndexTripletData*)chunk->m_oldPtr;
281 memPtr->m_3indices16 = (btShortIntIndexTripletData*)serializer->getUniquePointer(tmpIndices);
282 for (gfxindex = 0; gfxindex < numtriangles; gfxindex++)
284 unsigned short int* tri_indices = (unsigned short int*)(indexbase + gfxindex * indexstride);
285 tmpIndices[gfxindex].m_values[0] = tri_indices[0];
286 tmpIndices[gfxindex].m_values[1] = tri_indices[1];
287 tmpIndices[gfxindex].m_values[2] = tri_indices[2];
288 // Fill padding with zeros to appease msan.
289 tmpIndices[gfxindex].m_pad[0] = 0;
290 tmpIndices[gfxindex].m_pad[1] = 0;
292 serializer->finalizeChunk(chunk, "btShortIntIndexTripletData", BT_ARRAY_CODE, (void*)chunk->m_oldPtr);
300 btChunk* chunk = serializer->allocate(sizeof(btCharIndexTripletData), numtriangles);
301 btCharIndexTripletData* tmpIndices = (btCharIndexTripletData*)chunk->m_oldPtr;
302 memPtr->m_3indices8 = (btCharIndexTripletData*)serializer->getUniquePointer(tmpIndices);
303 for (gfxindex = 0; gfxindex < numtriangles; gfxindex++)
305 unsigned char* tri_indices = (unsigned char*)(indexbase + gfxindex * indexstride);
306 tmpIndices[gfxindex].m_values[0] = tri_indices[0];
307 tmpIndices[gfxindex].m_values[1] = tri_indices[1];
308 tmpIndices[gfxindex].m_values[2] = tri_indices[2];
309 // Fill padding with zeros to appease msan.
310 tmpIndices[gfxindex].m_pad = 0;
312 serializer->finalizeChunk(chunk, "btCharIndexTripletData", BT_ARRAY_CODE, (void*)chunk->m_oldPtr);
331 btChunk* chunk = serializer->allocate(sizeof(btVector3FloatData), numverts);
332 btVector3FloatData* tmpVertices = (btVector3FloatData*)chunk->m_oldPtr;
333 memPtr->m_vertices3f = (btVector3FloatData*)serializer->getUniquePointer(tmpVertices);
334 for (int i = 0; i < numverts; i++)
336 graphicsbase = (float*)(vertexbase + i * stride);
337 tmpVertices[i].m_floats[0] = graphicsbase[0];
338 tmpVertices[i].m_floats[1] = graphicsbase[1];
339 tmpVertices[i].m_floats[2] = graphicsbase[2];
341 serializer->finalizeChunk(chunk, "btVector3FloatData", BT_ARRAY_CODE, (void*)chunk->m_oldPtr);
350 btChunk* chunk = serializer->allocate(sizeof(btVector3DoubleData), numverts);
351 btVector3DoubleData* tmpVertices = (btVector3DoubleData*)chunk->m_oldPtr;
352 memPtr->m_vertices3d = (btVector3DoubleData*)serializer->getUniquePointer(tmpVertices);
353 for (int i = 0; i < numverts; i++)
355 double* graphicsbase = (double*)(vertexbase + i * stride); //for now convert to float, might leave it at double
356 tmpVertices[i].m_floats[0] = graphicsbase[0];
357 tmpVertices[i].m_floats[1] = graphicsbase[1];
358 tmpVertices[i].m_floats[2] = graphicsbase[2];
360 serializer->finalizeChunk(chunk, "btVector3DoubleData", BT_ARRAY_CODE, (void*)chunk->m_oldPtr);
366 btAssert((type == PHY_FLOAT) || (type == PHY_DOUBLE));
369 unLockReadOnlyVertexBase(part);
372 serializer->finalizeChunk(chunk, "btMeshPartData", BT_ARRAY_CODE, chunk->m_oldPtr);
375 // Fill padding with zeros to appease msan.
376 memset(trimeshData->m_padding, 0, sizeof(trimeshData->m_padding));
378 m_scaling.serializeFloat(trimeshData->m_scaling);
379 return "btStridingMeshInterfaceData";