Imported Upstream version 2.81
[platform/upstream/libbullet.git] / src / BulletCollision / CollisionShapes / btStridingMeshInterface.cpp
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
16 #include "btStridingMeshInterface.h"
17 #include "LinearMath/btSerializer.h"
18
19 btStridingMeshInterface::~btStridingMeshInterface()
20 {
21
22 }
23
24
25 void    btStridingMeshInterface::InternalProcessAllTriangles(btInternalTriangleIndexCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
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
42         ///if the number of parts is big, the performance might drop due to the innerloop switch on indextype
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
48                 ///unlike that developers want to pass in double-precision meshes in single-precision Bullet build
49                 ///so disable this feature by default
50                 ///see patch http://code.google.com/p/bullet/issues/detail?id=213
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
172                 unLockReadOnlyVertexBase(part);
173         }
174 }
175
176 void    btStridingMeshInterface::calculateAabbBruteForce(btVector3& aabbMin,btVector3& aabbMax)
177 {
178
179         struct  AabbCalculationCallback : public btInternalTriangleIndexCallback
180         {
181                 btVector3       m_aabbMin;
182                 btVector3       m_aabbMax;
183
184                 AabbCalculationCallback()
185                 {
186                         m_aabbMin.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
187                         m_aabbMax.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
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;
206         aabbMin.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
207         aabbMax.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
208         InternalProcessAllTriangles(&aabbCallback,aabbMin,aabbMax);
209
210         aabbMin = aabbCallback.m_aabbMin;
211         aabbMax = aabbCallback.m_aabbMax;
212 }
213
214
215
216 ///fills the dataBuffer and returns the struct name (and 0 on failure)
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
247                 ///if the number of parts is big, the performance might drop due to the innerloop switch on indextype
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);
288                                                 btShortIntIndexTripletData* tmpIndices = (btShortIntIndexTripletData*)chunk->m_oldPtr;
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);
306                                                 btCharIndexTripletData* tmpIndices = (btCharIndexTripletData*)chunk->m_oldPtr;
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
372                         unLockReadOnlyVertexBase(part);
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 }