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  }
297  serializer->finalizeChunk(chunk,"btShortIntIndexTripletData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
298  }
299  break;
300  }
301  case PHY_UCHAR:
302  {
303  if (numtriangles)
304  {
305  btChunk* chunk = serializer->allocate(sizeof(btCharIndexTripletData),numtriangles);
307  memPtr->m_3indices8 = (btCharIndexTripletData*) serializer->getUniquePointer(tmpIndices);
308  for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
309  {
310  unsigned char* tri_indices= (unsigned char*)(indexbase+gfxindex*indexstride);
311  tmpIndices[gfxindex].m_values[0] = tri_indices[0];
312  tmpIndices[gfxindex].m_values[1] = tri_indices[1];
313  tmpIndices[gfxindex].m_values[2] = tri_indices[2];
314  }
315  serializer->finalizeChunk(chunk,"btCharIndexTripletData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
316  }
317  break;
318  }
319  default:
320  {
321  btAssert(0);
322  //unknown index type
323  }
324  }
325 
326  switch (type)
327  {
328  case PHY_FLOAT:
329  {
330  float* graphicsbase;
331 
332  if (numverts)
333  {
334  btChunk* chunk = serializer->allocate(sizeof(btVector3FloatData),numverts);
335  btVector3FloatData* tmpVertices = (btVector3FloatData*) chunk->m_oldPtr;
336  memPtr->m_vertices3f = (btVector3FloatData *)serializer->getUniquePointer(tmpVertices);
337  for (int i=0;i<numverts;i++)
338  {
339  graphicsbase = (float*)(vertexbase+i*stride);
340  tmpVertices[i].m_floats[0] = graphicsbase[0];
341  tmpVertices[i].m_floats[1] = graphicsbase[1];
342  tmpVertices[i].m_floats[2] = graphicsbase[2];
343  }
344  serializer->finalizeChunk(chunk,"btVector3FloatData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
345  }
346  break;
347  }
348 
349  case PHY_DOUBLE:
350  {
351  if (numverts)
352  {
353  btChunk* chunk = serializer->allocate(sizeof(btVector3DoubleData),numverts);
354  btVector3DoubleData* tmpVertices = (btVector3DoubleData*) chunk->m_oldPtr;
355  memPtr->m_vertices3d = (btVector3DoubleData *) serializer->getUniquePointer(tmpVertices);
356  for (int i=0;i<numverts;i++)
357  {
358  double* graphicsbase = (double*)(vertexbase+i*stride);//for now convert to float, might leave it at double
359  tmpVertices[i].m_floats[0] = graphicsbase[0];
360  tmpVertices[i].m_floats[1] = graphicsbase[1];
361  tmpVertices[i].m_floats[2] = graphicsbase[2];
362  }
363  serializer->finalizeChunk(chunk,"btVector3DoubleData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
364  }
365  break;
366  }
367 
368  default:
369  btAssert((type == PHY_FLOAT) || (type == PHY_DOUBLE));
370  }
371 
373  }
374 
375  serializer->finalizeChunk(chunk,"btMeshPartData",BT_ARRAY_CODE,chunk->m_oldPtr);
376  }
377 
378 
379  m_scaling.serializeFloat(trimeshData->m_scaling);
380  return "btStridingMeshInterfaceData";
381 }
#define BT_LARGE_FLOAT
Definition: btScalar.h:268
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
Definition: btVector3.h:640
double m_floats[4]
Definition: btVector3.h:1307
virtual void * getUniquePointer(void *oldPtr)=0
#define btAssert(x)
Definition: btScalar.h:101
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:565
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:563
const btScalar & getX() const
Return the x value.
Definition: btVector3.h:561
void serializeFloat(struct btVector3FloatData &dataOut) const
Definition: btVector3.h:1311
#define BT_ARRAY_CODE
Definition: btSerializer.h:121
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 * m_oldPtr
Definition: btSerializer.h:56
virtual btChunk * allocate(size_t size, int numElements)=0
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:266
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