Bullet Collision Detection & Physics Library
btStridingMeshInterface.cpp
Go to the documentation of this file.
1/*
2Bullet Continuous Collision Detection and Physics Library
3Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org
4
5This software is provided 'as-is', without any express or implied warranty.
6In no event will the authors be held liable for any damages arising from the use of this software.
7Permission is granted to anyone to use this software for any purpose,
8including commercial applications, and to alter it and redistribute it freely,
9subject to the following restrictions:
10
111. 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.
122. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
133. This notice may not be removed or altered from any source distribution.
14*/
15
18
20{
21}
22
24{
25 (void)aabbMin;
26 (void)aabbMax;
27 int numtotalphysicsverts = 0;
28 int part, graphicssubparts = getNumSubParts();
29 const unsigned char* vertexbase;
30 const unsigned char* indexbase;
31 int indexstride;
32 PHY_ScalarType type;
33 PHY_ScalarType gfxindextype;
34 int stride, numverts, numtriangles;
35 int gfxindex;
36 btVector3 triangle[3];
37
38 btVector3 meshScaling = getScaling();
39
41 for (part = 0; part < graphicssubparts; part++)
42 {
43 getLockedReadOnlyVertexIndexBase(&vertexbase, numverts, type, stride, &indexbase, indexstride, numtriangles, gfxindextype, part);
44 numtotalphysicsverts += numtriangles * 3; //upper bound
45
49
50 switch (type)
51 {
52 case PHY_FLOAT:
53 {
54 float* graphicsbase;
55
56 switch (gfxindextype)
57 {
58 case PHY_INTEGER:
59 {
60 for (gfxindex = 0; gfxindex < numtriangles; gfxindex++)
61 {
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);
70 }
71 break;
72 }
73 case PHY_SHORT:
74 {
75 for (gfxindex = 0; gfxindex < numtriangles; gfxindex++)
76 {
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);
85 }
86 break;
87 }
88 case PHY_UCHAR:
89 {
90 for (gfxindex = 0; gfxindex < numtriangles; gfxindex++)
91 {
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);
100 }
101 break;
102 }
103 default:
104 btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT));
105 }
106 break;
107 }
108
109 case PHY_DOUBLE:
110 {
111 double* graphicsbase;
112
113 switch (gfxindextype)
114 {
115 case PHY_INTEGER:
116 {
117 for (gfxindex = 0; gfxindex < numtriangles; gfxindex++)
118 {
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);
127 }
128 break;
129 }
130 case PHY_SHORT:
131 {
132 for (gfxindex = 0; gfxindex < numtriangles; gfxindex++)
133 {
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);
142 }
143 break;
144 }
145 case PHY_UCHAR:
146 {
147 for (gfxindex = 0; gfxindex < numtriangles; gfxindex++)
148 {
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);
157 }
158 break;
159 }
160 default:
161 btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT));
162 }
163 break;
164 }
165 default:
166 btAssert((type == PHY_FLOAT) || (type == PHY_DOUBLE));
167 }
168
170 }
171}
172
174{
175 struct AabbCalculationCallback : public btInternalTriangleIndexCallback
176 {
177 btVector3 m_aabbMin;
178 btVector3 m_aabbMax;
179
180 AabbCalculationCallback()
181 {
184 }
185
186 virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex)
187 {
188 (void)partId;
189 (void)triangleIndex;
190
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]);
197 }
198 };
199
200 //first calculate the total aabb for all triangles
201 AabbCalculationCallback aabbCallback;
204 InternalProcessAllTriangles(&aabbCallback, aabbMin, aabbMax);
205
206 aabbMin = aabbCallback.m_aabbMin;
207 aabbMax = aabbCallback.m_aabbMax;
208}
209
211const char* btStridingMeshInterface::serialize(void* dataBuffer, btSerializer* serializer) const
212{
214
215 trimeshData->m_numMeshParts = getNumSubParts();
216
217 //void* uniquePtr = 0;
218
219 trimeshData->m_meshPartsPtr = 0;
220
221 if (trimeshData->m_numMeshParts)
222 {
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);
226
227 // int numtotalphysicsverts = 0;
228 int part, graphicssubparts = getNumSubParts();
229 const unsigned char* vertexbase;
230 const unsigned char* indexbase;
231 int indexstride;
232 PHY_ScalarType type;
233 PHY_ScalarType gfxindextype;
234 int stride, numverts, numtriangles;
235 int gfxindex;
236 // btVector3 triangle[3];
237
238 // btVector3 meshScaling = getScaling();
239
241 for (part = 0; part < graphicssubparts; part++, memPtr++)
242 {
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;
252
253 switch (gfxindextype)
254 {
255 case PHY_INTEGER:
256 {
257 int numindices = numtriangles * 3;
258
259 if (numindices)
260 {
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++)
265 {
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];
270 }
271 serializer->finalizeChunk(chunk, "btIntIndexData", BT_ARRAY_CODE, (void*)chunk->m_oldPtr);
272 }
273 break;
274 }
275 case PHY_SHORT:
276 {
277 if (numtriangles)
278 {
279 btChunk* chunk = serializer->allocate(sizeof(btShortIntIndexTripletData), numtriangles);
281 memPtr->m_3indices16 = (btShortIntIndexTripletData*)serializer->getUniquePointer(tmpIndices);
282 for (gfxindex = 0; gfxindex < numtriangles; gfxindex++)
283 {
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;
291 }
292 serializer->finalizeChunk(chunk, "btShortIntIndexTripletData", BT_ARRAY_CODE, (void*)chunk->m_oldPtr);
293 }
294 break;
295 }
296 case PHY_UCHAR:
297 {
298 if (numtriangles)
299 {
300 btChunk* chunk = serializer->allocate(sizeof(btCharIndexTripletData), numtriangles);
302 memPtr->m_3indices8 = (btCharIndexTripletData*)serializer->getUniquePointer(tmpIndices);
303 for (gfxindex = 0; gfxindex < numtriangles; gfxindex++)
304 {
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;
311 }
312 serializer->finalizeChunk(chunk, "btCharIndexTripletData", BT_ARRAY_CODE, (void*)chunk->m_oldPtr);
313 }
314 break;
315 }
316 default:
317 {
318 btAssert(0);
319 //unknown index type
320 }
321 }
322
323 switch (type)
324 {
325 case PHY_FLOAT:
326 {
327 float* graphicsbase;
328
329 if (numverts)
330 {
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++)
335 {
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];
340 }
341 serializer->finalizeChunk(chunk, "btVector3FloatData", BT_ARRAY_CODE, (void*)chunk->m_oldPtr);
342 }
343 break;
344 }
345
346 case PHY_DOUBLE:
347 {
348 if (numverts)
349 {
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++)
354 {
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];
359 }
360 serializer->finalizeChunk(chunk, "btVector3DoubleData", BT_ARRAY_CODE, (void*)chunk->m_oldPtr);
361 }
362 break;
363 }
364
365 default:
366 btAssert((type == PHY_FLOAT) || (type == PHY_DOUBLE));
367 }
368
370 }
371
372 serializer->finalizeChunk(chunk, "btMeshPartData", BT_ARRAY_CODE, chunk->m_oldPtr);
373 }
374
375 // Fill padding with zeros to appease msan.
376 memset(trimeshData->m_padding, 0, sizeof(trimeshData->m_padding));
377
378 m_scaling.serializeFloat(trimeshData->m_scaling);
379 return "btStridingMeshInterfaceData";
380}
PHY_ScalarType
PHY_ScalarType enumerates possible scalar types.
@ PHY_FLOAT
@ PHY_UCHAR
@ PHY_DOUBLE
@ PHY_SHORT
@ PHY_INTEGER
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:314
#define BT_LARGE_FLOAT
Definition: btScalar.h:316
#define btAssert(x)
Definition: btScalar.h:153
#define BT_ARRAY_CODE
Definition: btSerializer.h:118
void * m_oldPtr
Definition: btSerializer.h:52
virtual void internalProcessTriangleIndex(btVector3 *triangle, int partId, int triangleIndex)=0
virtual btChunk * allocate(size_t size, int numElements)=0
virtual void * getUniquePointer(void *oldPtr)=0
virtual void finalizeChunk(btChunk *chunk, const char *structType, int chunkCode, void *oldPtr)=0
void calculateAabbBruteForce(btVector3 &aabbMin, btVector3 &aabbMax)
brute force method to calculate aabb
const btVector3 & getScaling() const
virtual void getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int &numverts, PHY_ScalarType &type, int &stride, const unsigned char **indexbase, int &indexstride, int &numfaces, PHY_ScalarType &indicestype, int subpart=0) const =0
virtual int getNumSubParts() const =0
getNumSubParts returns the number of separate subparts each subpart has a continuous array of vertice...
virtual const char * serialize(void *dataBuffer, btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
virtual void unLockReadOnlyVertexBase(int subpart) const =0
virtual void InternalProcessAllTriangles(btInternalTriangleIndexCallback *callback, const btVector3 &aabbMin, const btVector3 &aabbMax) const
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:82
const btScalar & getZ() const
Return the z value.
Definition: btVector3.h:565
void setMax(const btVector3 &other)
Set each element to the max of the current values and the values of another btVector3.
Definition: btVector3.h:609
void serializeFloat(struct btVector3FloatData &dataOut) const
Definition: btVector3.h:1291
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
Definition: btVector3.h:640
const btScalar & getY() const
Return the y value.
Definition: btVector3.h:563
void setMin(const btVector3 &other)
Set each element to the min of the current values and the values of another btVector3.
Definition: btVector3.h:626
const btScalar & getX() const
Return the x value.
Definition: btVector3.h:561
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
btShortIntIndexData * m_indices16
btCharIndexTripletData * m_3indices8
btVector3FloatData * m_vertices3f
btShortIntIndexTripletData * m_3indices16
btIntIndexData * m_indices32
btVector3DoubleData * m_vertices3d
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
double m_floats[4]
Definition: btVector3.h:1288