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}
23
24
26{
27 (void)aabbMin;
28 (void)aabbMax;
29 int numtotalphysicsverts = 0;
30 int part,graphicssubparts = getNumSubParts();
31 const unsigned char * vertexbase;
32 const unsigned char * indexbase;
33 int indexstride;
34 PHY_ScalarType type;
35 PHY_ScalarType gfxindextype;
36 int stride,numverts,numtriangles;
37 int gfxindex;
38 btVector3 triangle[3];
39
40 btVector3 meshScaling = getScaling();
41
43 for (part=0;part<graphicssubparts ;part++)
44 {
45 getLockedReadOnlyVertexIndexBase(&vertexbase,numverts,type,stride,&indexbase,indexstride,numtriangles,gfxindextype,part);
46 numtotalphysicsverts+=numtriangles*3; //upper bound
47
51
52 switch (type)
53 {
54 case PHY_FLOAT:
55 {
56
57 float* graphicsbase;
58
59 switch (gfxindextype)
60 {
61 case PHY_INTEGER:
62 {
63 for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
64 {
65 unsigned int* tri_indices= (unsigned int*)(indexbase+gfxindex*indexstride);
66 graphicsbase = (float*)(vertexbase+tri_indices[0]*stride);
67 triangle[0].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
68 graphicsbase = (float*)(vertexbase+tri_indices[1]*stride);
69 triangle[1].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(), graphicsbase[2]*meshScaling.getZ());
70 graphicsbase = (float*)(vertexbase+tri_indices[2]*stride);
71 triangle[2].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(), graphicsbase[2]*meshScaling.getZ());
72 callback->internalProcessTriangleIndex(triangle,part,gfxindex);
73 }
74 break;
75 }
76 case PHY_SHORT:
77 {
78 for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
79 {
80 unsigned short int* tri_indices= (unsigned short int*)(indexbase+gfxindex*indexstride);
81 graphicsbase = (float*)(vertexbase+tri_indices[0]*stride);
82 triangle[0].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
83 graphicsbase = (float*)(vertexbase+tri_indices[1]*stride);
84 triangle[1].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(), graphicsbase[2]*meshScaling.getZ());
85 graphicsbase = (float*)(vertexbase+tri_indices[2]*stride);
86 triangle[2].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(), graphicsbase[2]*meshScaling.getZ());
87 callback->internalProcessTriangleIndex(triangle,part,gfxindex);
88 }
89 break;
90 }
91 case PHY_UCHAR:
92 {
93 for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
94 {
95 unsigned char* tri_indices= (unsigned char*)(indexbase+gfxindex*indexstride);
96 graphicsbase = (float*)(vertexbase+tri_indices[0]*stride);
97 triangle[0].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
98 graphicsbase = (float*)(vertexbase+tri_indices[1]*stride);
99 triangle[1].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(), graphicsbase[2]*meshScaling.getZ());
100 graphicsbase = (float*)(vertexbase+tri_indices[2]*stride);
101 triangle[2].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(), graphicsbase[2]*meshScaling.getZ());
102 callback->internalProcessTriangleIndex(triangle,part,gfxindex);
103 }
104 break;
105 }
106 default:
107 btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT));
108 }
109 break;
110 }
111
112 case PHY_DOUBLE:
113 {
114 double* graphicsbase;
115
116 switch (gfxindextype)
117 {
118 case PHY_INTEGER:
119 {
120 for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
121 {
122 unsigned int* tri_indices= (unsigned int*)(indexbase+gfxindex*indexstride);
123 graphicsbase = (double*)(vertexbase+tri_indices[0]*stride);
124 triangle[0].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),(btScalar)graphicsbase[2]*meshScaling.getZ());
125 graphicsbase = (double*)(vertexbase+tri_indices[1]*stride);
126 triangle[1].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(), (btScalar)graphicsbase[2]*meshScaling.getZ());
127 graphicsbase = (double*)(vertexbase+tri_indices[2]*stride);
128 triangle[2].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(), (btScalar)graphicsbase[2]*meshScaling.getZ());
129 callback->internalProcessTriangleIndex(triangle,part,gfxindex);
130 }
131 break;
132 }
133 case PHY_SHORT:
134 {
135 for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
136 {
137 unsigned short int* tri_indices= (unsigned short int*)(indexbase+gfxindex*indexstride);
138 graphicsbase = (double*)(vertexbase+tri_indices[0]*stride);
139 triangle[0].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),(btScalar)graphicsbase[2]*meshScaling.getZ());
140 graphicsbase = (double*)(vertexbase+tri_indices[1]*stride);
141 triangle[1].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(), (btScalar)graphicsbase[2]*meshScaling.getZ());
142 graphicsbase = (double*)(vertexbase+tri_indices[2]*stride);
143 triangle[2].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(), (btScalar)graphicsbase[2]*meshScaling.getZ());
144 callback->internalProcessTriangleIndex(triangle,part,gfxindex);
145 }
146 break;
147 }
148 case PHY_UCHAR:
149 {
150 for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
151 {
152 unsigned char* tri_indices= (unsigned char*)(indexbase+gfxindex*indexstride);
153 graphicsbase = (double*)(vertexbase+tri_indices[0]*stride);
154 triangle[0].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),(btScalar)graphicsbase[2]*meshScaling.getZ());
155 graphicsbase = (double*)(vertexbase+tri_indices[1]*stride);
156 triangle[1].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(), (btScalar)graphicsbase[2]*meshScaling.getZ());
157 graphicsbase = (double*)(vertexbase+tri_indices[2]*stride);
158 triangle[2].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(), (btScalar)graphicsbase[2]*meshScaling.getZ());
159 callback->internalProcessTriangleIndex(triangle,part,gfxindex);
160 }
161 break;
162 }
163 default:
164 btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT));
165 }
166 break;
167 }
168 default:
169 btAssert((type == PHY_FLOAT) || (type == PHY_DOUBLE));
170 }
171
173 }
174}
175
177{
178
179 struct AabbCalculationCallback : public btInternalTriangleIndexCallback
180 {
181 btVector3 m_aabbMin;
182 btVector3 m_aabbMax;
183
184 AabbCalculationCallback()
185 {
188 }
189
190 virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex)
191 {
192 (void)partId;
193 (void)triangleIndex;
194
195 m_aabbMin.setMin(triangle[0]);
196 m_aabbMax.setMax(triangle[0]);
197 m_aabbMin.setMin(triangle[1]);
198 m_aabbMax.setMax(triangle[1]);
199 m_aabbMin.setMin(triangle[2]);
200 m_aabbMax.setMax(triangle[2]);
201 }
202 };
203
204 //first calculate the total aabb for all triangles
205 AabbCalculationCallback aabbCallback;
208 InternalProcessAllTriangles(&aabbCallback,aabbMin,aabbMax);
209
210 aabbMin = aabbCallback.m_aabbMin;
211 aabbMax = aabbCallback.m_aabbMax;
212}
213
214
215
217const char* btStridingMeshInterface::serialize(void* dataBuffer, btSerializer* serializer) const
218{
219 btStridingMeshInterfaceData* trimeshData = (btStridingMeshInterfaceData*) dataBuffer;
220
221 trimeshData->m_numMeshParts = getNumSubParts();
222
223 //void* uniquePtr = 0;
224
225 trimeshData->m_meshPartsPtr = 0;
226
227 if (trimeshData->m_numMeshParts)
228 {
229 btChunk* chunk = serializer->allocate(sizeof(btMeshPartData),trimeshData->m_numMeshParts);
230 btMeshPartData* memPtr = (btMeshPartData*)chunk->m_oldPtr;
231 trimeshData->m_meshPartsPtr = (btMeshPartData *)serializer->getUniquePointer(memPtr);
232
233
234 // int numtotalphysicsverts = 0;
235 int part,graphicssubparts = getNumSubParts();
236 const unsigned char * vertexbase;
237 const unsigned char * indexbase;
238 int indexstride;
239 PHY_ScalarType type;
240 PHY_ScalarType gfxindextype;
241 int stride,numverts,numtriangles;
242 int gfxindex;
243 // btVector3 triangle[3];
244
245 // btVector3 meshScaling = getScaling();
246
248 for (part=0;part<graphicssubparts ;part++,memPtr++)
249 {
250 getLockedReadOnlyVertexIndexBase(&vertexbase,numverts,type,stride,&indexbase,indexstride,numtriangles,gfxindextype,part);
251 memPtr->m_numTriangles = numtriangles;//indices = 3*numtriangles
252 memPtr->m_numVertices = numverts;
253 memPtr->m_indices16 = 0;
254 memPtr->m_indices32 = 0;
255 memPtr->m_3indices16 = 0;
256 memPtr->m_3indices8 = 0;
257 memPtr->m_vertices3f = 0;
258 memPtr->m_vertices3d = 0;
259
260
261 switch (gfxindextype)
262 {
263 case PHY_INTEGER:
264 {
265 int numindices = numtriangles*3;
266
267 if (numindices)
268 {
269 btChunk* chunk = serializer->allocate(sizeof(btIntIndexData),numindices);
270 btIntIndexData* tmpIndices = (btIntIndexData*)chunk->m_oldPtr;
271 memPtr->m_indices32 = (btIntIndexData*)serializer->getUniquePointer(tmpIndices);
272 for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
273 {
274 unsigned int* tri_indices= (unsigned int*)(indexbase+gfxindex*indexstride);
275 tmpIndices[gfxindex*3].m_value = tri_indices[0];
276 tmpIndices[gfxindex*3+1].m_value = tri_indices[1];
277 tmpIndices[gfxindex*3+2].m_value = tri_indices[2];
278 }
279 serializer->finalizeChunk(chunk,"btIntIndexData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
280 }
281 break;
282 }
283 case PHY_SHORT:
284 {
285 if (numtriangles)
286 {
287 btChunk* chunk = serializer->allocate(sizeof(btShortIntIndexTripletData),numtriangles);
289 memPtr->m_3indices16 = (btShortIntIndexTripletData*) serializer->getUniquePointer(tmpIndices);
290 for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
291 {
292 unsigned short int* tri_indices= (unsigned short int*)(indexbase+gfxindex*indexstride);
293 tmpIndices[gfxindex].m_values[0] = tri_indices[0];
294 tmpIndices[gfxindex].m_values[1] = tri_indices[1];
295 tmpIndices[gfxindex].m_values[2] = tri_indices[2];
296 // Fill padding with zeros to appease msan.
297 tmpIndices[gfxindex].m_pad[0] = 0;
298 tmpIndices[gfxindex].m_pad[1] = 0;
299 }
300 serializer->finalizeChunk(chunk,"btShortIntIndexTripletData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
301 }
302 break;
303 }
304 case PHY_UCHAR:
305 {
306 if (numtriangles)
307 {
308 btChunk* chunk = serializer->allocate(sizeof(btCharIndexTripletData),numtriangles);
310 memPtr->m_3indices8 = (btCharIndexTripletData*) serializer->getUniquePointer(tmpIndices);
311 for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
312 {
313 unsigned char* tri_indices= (unsigned char*)(indexbase+gfxindex*indexstride);
314 tmpIndices[gfxindex].m_values[0] = tri_indices[0];
315 tmpIndices[gfxindex].m_values[1] = tri_indices[1];
316 tmpIndices[gfxindex].m_values[2] = tri_indices[2];
317 // Fill padding with zeros to appease msan.
318 tmpIndices[gfxindex].m_pad = 0;
319 }
320 serializer->finalizeChunk(chunk,"btCharIndexTripletData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
321 }
322 break;
323 }
324 default:
325 {
326 btAssert(0);
327 //unknown index type
328 }
329 }
330
331 switch (type)
332 {
333 case PHY_FLOAT:
334 {
335 float* graphicsbase;
336
337 if (numverts)
338 {
339 btChunk* chunk = serializer->allocate(sizeof(btVector3FloatData),numverts);
340 btVector3FloatData* tmpVertices = (btVector3FloatData*) chunk->m_oldPtr;
341 memPtr->m_vertices3f = (btVector3FloatData *)serializer->getUniquePointer(tmpVertices);
342 for (int i=0;i<numverts;i++)
343 {
344 graphicsbase = (float*)(vertexbase+i*stride);
345 tmpVertices[i].m_floats[0] = graphicsbase[0];
346 tmpVertices[i].m_floats[1] = graphicsbase[1];
347 tmpVertices[i].m_floats[2] = graphicsbase[2];
348 }
349 serializer->finalizeChunk(chunk,"btVector3FloatData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
350 }
351 break;
352 }
353
354 case PHY_DOUBLE:
355 {
356 if (numverts)
357 {
358 btChunk* chunk = serializer->allocate(sizeof(btVector3DoubleData),numverts);
359 btVector3DoubleData* tmpVertices = (btVector3DoubleData*) chunk->m_oldPtr;
360 memPtr->m_vertices3d = (btVector3DoubleData *) serializer->getUniquePointer(tmpVertices);
361 for (int i=0;i<numverts;i++)
362 {
363 double* graphicsbase = (double*)(vertexbase+i*stride);//for now convert to float, might leave it at double
364 tmpVertices[i].m_floats[0] = graphicsbase[0];
365 tmpVertices[i].m_floats[1] = graphicsbase[1];
366 tmpVertices[i].m_floats[2] = graphicsbase[2];
367 }
368 serializer->finalizeChunk(chunk,"btVector3DoubleData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
369 }
370 break;
371 }
372
373 default:
374 btAssert((type == PHY_FLOAT) || (type == PHY_DOUBLE));
375 }
376
378 }
379
380 serializer->finalizeChunk(chunk,"btMeshPartData",BT_ARRAY_CODE,chunk->m_oldPtr);
381 }
382
383 // Fill padding with zeros to appease msan.
384 memset(trimeshData->m_padding, 0, sizeof(trimeshData->m_padding));
385
386 m_scaling.serializeFloat(trimeshData->m_scaling);
387 return "btStridingMeshInterfaceData";
388}
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:292
#define BT_LARGE_FLOAT
Definition: btScalar.h:294
#define btAssert(x)
Definition: btScalar.h:131
#define BT_ARRAY_CODE
Definition: btSerializer.h:126
void * m_oldPtr
Definition: btSerializer.h:56
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 seperate 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:84
const btScalar & getZ() const
Return the z value.
Definition: btVector3.h:577
void setMax(const btVector3 &other)
Set each element to the max of the current values and the values of another btVector3.
Definition: btVector3.h:621
void serializeFloat(struct btVector3FloatData &dataOut) const
Definition: btVector3.h:1323
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
Definition: btVector3.h:652
const btScalar & getY() const
Return the y value.
Definition: btVector3.h:575
void setMin(const btVector3 &other)
Set each element to the min of the current values and the values of another btVector3.
Definition: btVector3.h:638
const btScalar & getX() const
Return the x value.
Definition: btVector3.h:573
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:1319