Bullet Collision Detection & Physics Library
btStridingMeshInterface.cpp
Go to the documentation of this file.
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org
4 
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:
10 
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.
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 
217 const 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 }
#define BT_LARGE_FLOAT
Definition: btScalar.h:294
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
Definition: btVector3.h:652
double m_floats[4]
Definition: btVector3.h:1320
virtual void * getUniquePointer(void *oldPtr)=0
#define btAssert(x)
Definition: btScalar.h:131
const btVector3 & getScaling() const
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 ...
btVector3FloatData * m_vertices3f
const btScalar & getZ() const
Return the z value.
Definition: btVector3.h:577
btShortIntIndexData * m_indices16
btCharIndexTripletData * m_3indices8
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 ...
btShortIntIndexTripletData * m_3indices16
const btScalar & getY() const
Return the y value.
Definition: btVector3.h:575
const btScalar & getX() const
Return the x value.
Definition: btVector3.h:573
void serializeFloat(struct btVector3FloatData &dataOut) const
Definition: btVector3.h:1324
#define BT_ARRAY_CODE
Definition: btSerializer.h:128
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:83
virtual int getNumSubParts() const =0
getNumSubParts returns the number of seperate subparts each subpart has a continuous array of vertice...
virtual void finalizeChunk(btChunk *chunk, const char *structType, int chunkCode, void *oldPtr)=0
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 void internalProcessTriangleIndex(btVector3 *triangle, int partId, int triangleIndex)=0
btIntIndexData * m_indices32
virtual void unLockReadOnlyVertexBase(int subpart) const =0
virtual const char * serialize(void *dataBuffer, btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
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 * m_oldPtr
Definition: btSerializer.h:56
virtual btChunk * allocate(size_t size, int numElements)=0
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
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:292
PHY_ScalarType
PHY_ScalarType enumerates possible scalar types.
virtual void InternalProcessAllTriangles(btInternalTriangleIndexCallback *callback, const btVector3 &aabbMin, const btVector3 &aabbMax) const
void calculateAabbBruteForce(btVector3 &aabbMin, btVector3 &aabbMax)
brute force method to calculate aabb
btVector3DoubleData * m_vertices3d