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