== SoC Bullet - Bullet Upgrade to 2.76 ==
[blender.git] / extern / bullet2 / 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                          default:
92                                  btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT));
93                          }
94                          break;
95                  }
96
97                 case PHY_DOUBLE:
98                         {
99                                 double* graphicsbase;
100
101                                 switch (gfxindextype)
102                                 {
103                                 case PHY_INTEGER:
104                                         {
105                                                 for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
106                                                 {
107                                                         unsigned int* tri_indices= (unsigned int*)(indexbase+gfxindex*indexstride);
108                                                         graphicsbase = (double*)(vertexbase+tri_indices[0]*stride);
109                                                         triangle[0].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),(btScalar)graphicsbase[2]*meshScaling.getZ());
110                                                         graphicsbase = (double*)(vertexbase+tri_indices[1]*stride);
111                                                         triangle[1].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),  (btScalar)graphicsbase[2]*meshScaling.getZ());
112                                                         graphicsbase = (double*)(vertexbase+tri_indices[2]*stride);
113                                                         triangle[2].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),  (btScalar)graphicsbase[2]*meshScaling.getZ());
114                                                         callback->internalProcessTriangleIndex(triangle,part,gfxindex);
115                                                 }
116                                                 break;
117                                         }
118                                 case PHY_SHORT:
119                                         {
120                                                 for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
121                                                 {
122                                                         unsigned short int* tri_indices= (unsigned short 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                                 default:
134                                         btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT));
135                                 }
136                                 break;
137                         }
138                 default:
139                         btAssert((type == PHY_FLOAT) || (type == PHY_DOUBLE));
140                 }
141
142                 unLockReadOnlyVertexBase(part);
143         }
144 }
145
146 void    btStridingMeshInterface::calculateAabbBruteForce(btVector3& aabbMin,btVector3& aabbMax)
147 {
148
149         struct  AabbCalculationCallback : public btInternalTriangleIndexCallback
150         {
151                 btVector3       m_aabbMin;
152                 btVector3       m_aabbMax;
153
154                 AabbCalculationCallback()
155                 {
156                         m_aabbMin.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
157                         m_aabbMax.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
158                 }
159
160                 virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int  triangleIndex)
161                 {
162                         (void)partId;
163                         (void)triangleIndex;
164
165                         m_aabbMin.setMin(triangle[0]);
166                         m_aabbMax.setMax(triangle[0]);
167                         m_aabbMin.setMin(triangle[1]);
168                         m_aabbMax.setMax(triangle[1]);
169                         m_aabbMin.setMin(triangle[2]);
170                         m_aabbMax.setMax(triangle[2]);
171                 }
172         };
173
174         //first calculate the total aabb for all triangles
175         AabbCalculationCallback aabbCallback;
176         aabbMin.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
177         aabbMax.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
178         InternalProcessAllTriangles(&aabbCallback,aabbMin,aabbMax);
179
180         aabbMin = aabbCallback.m_aabbMin;
181         aabbMax = aabbCallback.m_aabbMax;
182 }
183
184
185
186 ///fills the dataBuffer and returns the struct name (and 0 on failure)
187 const char*     btStridingMeshInterface::serialize(void* dataBuffer, btSerializer* serializer) const
188 {
189         btStridingMeshInterfaceData* trimeshData = (btStridingMeshInterfaceData*) dataBuffer;
190
191         trimeshData->m_numMeshParts = getNumSubParts();
192
193         //void* uniquePtr = 0;
194
195         trimeshData->m_meshPartsPtr = 0;
196
197         if (trimeshData->m_numMeshParts)
198         {
199                 btChunk* chunk = serializer->allocate(sizeof(btMeshPartData),trimeshData->m_numMeshParts);
200                 btMeshPartData* memPtr = (btMeshPartData*)chunk->m_oldPtr;
201                 trimeshData->m_meshPartsPtr = (btMeshPartData *)serializer->getUniquePointer(memPtr);
202
203
204         //      int numtotalphysicsverts = 0;
205                 int part,graphicssubparts = getNumSubParts();
206                 const unsigned char * vertexbase;
207                 const unsigned char * indexbase;
208                 int indexstride;
209                 PHY_ScalarType type;
210                 PHY_ScalarType gfxindextype;
211                 int stride,numverts,numtriangles;
212                 int gfxindex;
213         //      btVector3 triangle[3];
214
215                 btVector3 meshScaling = getScaling();
216
217                 ///if the number of parts is big, the performance might drop due to the innerloop switch on indextype
218                 for (part=0;part<graphicssubparts ;part++,memPtr++)
219                 {
220                         getLockedReadOnlyVertexIndexBase(&vertexbase,numverts,type,stride,&indexbase,indexstride,numtriangles,gfxindextype,part);
221                         memPtr->m_numTriangles = numtriangles;//indices = 3*numtriangles
222                         memPtr->m_numVertices = numverts;
223                         memPtr->m_indices16 = 0;
224                         memPtr->m_indices32 = 0;
225                         memPtr->m_3indices16 = 0;
226                         memPtr->m_vertices3f = 0;
227                         memPtr->m_vertices3d = 0;
228
229                         switch (gfxindextype)
230                         {
231                         case PHY_INTEGER:
232                                 {
233                                         int numindices = numtriangles*3;
234                                 
235                                         if (numindices)
236                                         {
237                                                 btChunk* chunk = serializer->allocate(sizeof(btIntIndexData),numindices);
238                                                 btIntIndexData* tmpIndices = (btIntIndexData*)chunk->m_oldPtr;
239                                                 memPtr->m_indices32 = (btIntIndexData*)serializer->getUniquePointer(tmpIndices);
240                                                 for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
241                                                 {
242                                                         unsigned int* tri_indices= (unsigned int*)(indexbase+gfxindex*indexstride);
243                                                         tmpIndices[gfxindex*3].m_value = tri_indices[0];
244                                                         tmpIndices[gfxindex*3+1].m_value = tri_indices[1];
245                                                         tmpIndices[gfxindex*3+2].m_value = tri_indices[2];
246                                                 }
247                                                 serializer->finalizeChunk(chunk,"btIntIndexData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
248                                         }
249                                         break;
250                                 }
251                         case PHY_SHORT:
252                                 {
253                                         if (numtriangles)
254                                         {
255                                                 btChunk* chunk = serializer->allocate(sizeof(btShortIntIndexTripletData),numtriangles);
256                                                 btShortIntIndexTripletData* tmpIndices = (btShortIntIndexTripletData*)chunk->m_oldPtr;
257                                                 memPtr->m_3indices16 = (btShortIntIndexTripletData*) serializer->getUniquePointer(tmpIndices);
258                                                 for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
259                                                 {
260                                                         unsigned short int* tri_indices= (unsigned short int*)(indexbase+gfxindex*indexstride);
261                                                         tmpIndices[gfxindex].m_values[0] = tri_indices[0];
262                                                         tmpIndices[gfxindex].m_values[1] = tri_indices[1];
263                                                         tmpIndices[gfxindex].m_values[2] = tri_indices[2];
264                                                 }
265                                                 serializer->finalizeChunk(chunk,"btShortIntIndexTripletData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
266                                         }
267                                         break;
268                                 }
269                         default:
270                                 {
271                                         btAssert(0);
272                                         //unknown index type
273                                 }
274                         }
275
276                         switch (type)
277                         {
278                         case PHY_FLOAT:
279                          {
280                                  float* graphicsbase;
281
282                                  if (numverts)
283                                  {
284                                          btChunk* chunk = serializer->allocate(sizeof(btVector3FloatData),numverts);
285                                          btVector3FloatData* tmpVertices = (btVector3FloatData*) chunk->m_oldPtr;
286                                          memPtr->m_vertices3f = (btVector3FloatData *)serializer->getUniquePointer(tmpVertices);
287                                          for (int i=0;i<numverts;i++)
288                                          {
289                                                  graphicsbase = (float*)(vertexbase+i*stride);
290                                                  tmpVertices[i].m_floats[0] = graphicsbase[0];
291                                                  tmpVertices[i].m_floats[1] = graphicsbase[1];
292                                                  tmpVertices[i].m_floats[2] = graphicsbase[2];
293                                          }
294                                          serializer->finalizeChunk(chunk,"btVector3FloatData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
295                                  }
296                                  break;
297                                 }
298
299                         case PHY_DOUBLE:
300                                 {
301                                         if (numverts)
302                                         {
303                                                 btChunk* chunk = serializer->allocate(sizeof(btVector3DoubleData),numverts);
304                                                 btVector3DoubleData* tmpVertices = (btVector3DoubleData*) chunk->m_oldPtr;
305                                                 memPtr->m_vertices3d = (btVector3DoubleData *) serializer->getUniquePointer(tmpVertices);
306                                                 for (int i=0;i<numverts;i++)
307                                          {
308                                                  double* graphicsbase = (double*)(vertexbase+i*stride);//for now convert to float, might leave it at double
309                                                  tmpVertices[i].m_floats[0] = graphicsbase[0];
310                                                  tmpVertices[i].m_floats[1] = graphicsbase[1];
311                                                  tmpVertices[i].m_floats[2] = graphicsbase[2];
312                                          }
313                                                 serializer->finalizeChunk(chunk,"btVector3DoubleData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
314                                         }
315                                         break;
316                                 }
317
318                         default:
319                                 btAssert((type == PHY_FLOAT) || (type == PHY_DOUBLE));
320                         }
321
322                         unLockReadOnlyVertexBase(part);
323                 }
324
325                 serializer->finalizeChunk(chunk,"btMeshPartData",BT_ARRAY_CODE,chunk->m_oldPtr);
326         }
327
328
329         m_scaling.serializeFloat(trimeshData->m_scaling);
330         return "btStridingMeshInterfaceData";
331 }