[dali_2.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-physics / third-party / bullet3 / src / BulletCollision / CollisionDispatch / btCollisionWorldImporter.cpp
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2014 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 "btCollisionWorldImporter.h"
17 #include "btBulletCollisionCommon.h"
18 #include "LinearMath/btSerializer.h"  //for btBulletSerializedArrays definition
19
20 #ifdef SUPPORT_GIMPACT_SHAPE_IMPORT
21 #include "BulletCollision/Gimpact/btGImpactShape.h"
22 #endif  //SUPPORT_GIMPACT_SHAPE_IMPORT
23
24 btCollisionWorldImporter::btCollisionWorldImporter(btCollisionWorld* world)
25         : m_collisionWorld(world),
26           m_verboseMode(0)
27 {
28 }
29
30 btCollisionWorldImporter::~btCollisionWorldImporter()
31 {
32 }
33
34 bool btCollisionWorldImporter::convertAllObjects(btBulletSerializedArrays* arrays)
35 {
36         m_shapeMap.clear();
37         m_bodyMap.clear();
38
39         int i;
40
41         for (i = 0; i < arrays->m_bvhsDouble.size(); i++)
42         {
43                 btOptimizedBvh* bvh = createOptimizedBvh();
44                 btQuantizedBvhDoubleData* bvhData = arrays->m_bvhsDouble[i];
45                 bvh->deSerializeDouble(*bvhData);
46                 m_bvhMap.insert(arrays->m_bvhsDouble[i], bvh);
47         }
48         for (i = 0; i < arrays->m_bvhsFloat.size(); i++)
49         {
50                 btOptimizedBvh* bvh = createOptimizedBvh();
51                 btQuantizedBvhFloatData* bvhData = arrays->m_bvhsFloat[i];
52                 bvh->deSerializeFloat(*bvhData);
53                 m_bvhMap.insert(arrays->m_bvhsFloat[i], bvh);
54         }
55
56         for (i = 0; i < arrays->m_colShapeData.size(); i++)
57         {
58                 btCollisionShapeData* shapeData = arrays->m_colShapeData[i];
59                 btCollisionShape* shape = convertCollisionShape(shapeData);
60                 if (shape)
61                 {
62                         //              printf("shapeMap.insert(%x,%x)\n",shapeData,shape);
63                         m_shapeMap.insert(shapeData, shape);
64                 }
65
66                 if (shape && shapeData->m_name)
67                 {
68                         char* newname = duplicateName(shapeData->m_name);
69                         m_objectNameMap.insert(shape, newname);
70                         m_nameShapeMap.insert(newname, shape);
71                 }
72         }
73
74         for (i = 0; i < arrays->m_collisionObjectDataDouble.size(); i++)
75         {
76                 btCollisionObjectDoubleData* colObjData = arrays->m_collisionObjectDataDouble[i];
77                 btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionShape);
78                 if (shapePtr && *shapePtr)
79                 {
80                         btTransform startTransform;
81                         colObjData->m_worldTransform.m_origin.m_floats[3] = 0.f;
82                         startTransform.deSerializeDouble(colObjData->m_worldTransform);
83
84                         btCollisionShape* shape = (btCollisionShape*)*shapePtr;
85                         btCollisionObject* body = createCollisionObject(startTransform, shape, colObjData->m_name);
86                         body->setFriction(btScalar(colObjData->m_friction));
87                         body->setRestitution(btScalar(colObjData->m_restitution));
88
89 #ifdef USE_INTERNAL_EDGE_UTILITY
90                         if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
91                         {
92                                 btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape;
93                                 if (trimesh->getTriangleInfoMap())
94                                 {
95                                         body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
96                                 }
97                         }
98 #endif  //USE_INTERNAL_EDGE_UTILITY
99                         m_bodyMap.insert(colObjData, body);
100                 }
101                 else
102                 {
103                         printf("error: no shape found\n");
104                 }
105         }
106         for (i = 0; i < arrays->m_collisionObjectDataFloat.size(); i++)
107         {
108                 btCollisionObjectFloatData* colObjData = arrays->m_collisionObjectDataFloat[i];
109                 btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionShape);
110                 if (shapePtr && *shapePtr)
111                 {
112                         btTransform startTransform;
113                         colObjData->m_worldTransform.m_origin.m_floats[3] = 0.f;
114                         startTransform.deSerializeFloat(colObjData->m_worldTransform);
115
116                         btCollisionShape* shape = (btCollisionShape*)*shapePtr;
117                         btCollisionObject* body = createCollisionObject(startTransform, shape, colObjData->m_name);
118
119 #ifdef USE_INTERNAL_EDGE_UTILITY
120                         if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
121                         {
122                                 btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape;
123                                 if (trimesh->getTriangleInfoMap())
124                                 {
125                                         body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
126                                 }
127                         }
128 #endif  //USE_INTERNAL_EDGE_UTILITY
129                         m_bodyMap.insert(colObjData, body);
130                 }
131                 else
132                 {
133                         printf("error: no shape found\n");
134                 }
135         }
136
137         return true;
138 }
139
140 void btCollisionWorldImporter::deleteAllData()
141 {
142         int i;
143
144         for (i = 0; i < m_allocatedCollisionObjects.size(); i++)
145         {
146                 if (m_collisionWorld)
147                         m_collisionWorld->removeCollisionObject(m_allocatedCollisionObjects[i]);
148                 delete m_allocatedCollisionObjects[i];
149         }
150
151         m_allocatedCollisionObjects.clear();
152
153         for (i = 0; i < m_allocatedCollisionShapes.size(); i++)
154         {
155                 delete m_allocatedCollisionShapes[i];
156         }
157         m_allocatedCollisionShapes.clear();
158
159         for (i = 0; i < m_allocatedBvhs.size(); i++)
160         {
161                 delete m_allocatedBvhs[i];
162         }
163         m_allocatedBvhs.clear();
164
165         for (i = 0; i < m_allocatedTriangleInfoMaps.size(); i++)
166         {
167                 delete m_allocatedTriangleInfoMaps[i];
168         }
169         m_allocatedTriangleInfoMaps.clear();
170         for (i = 0; i < m_allocatedTriangleIndexArrays.size(); i++)
171         {
172                 delete m_allocatedTriangleIndexArrays[i];
173         }
174         m_allocatedTriangleIndexArrays.clear();
175         for (i = 0; i < m_allocatedNames.size(); i++)
176         {
177                 delete[] m_allocatedNames[i];
178         }
179         m_allocatedNames.clear();
180
181         for (i = 0; i < m_allocatedbtStridingMeshInterfaceDatas.size(); i++)
182         {
183                 btStridingMeshInterfaceData* curData = m_allocatedbtStridingMeshInterfaceDatas[i];
184
185                 for (int a = 0; a < curData->m_numMeshParts; a++)
186                 {
187                         btMeshPartData* curPart = &curData->m_meshPartsPtr[a];
188                         if (curPart->m_vertices3f)
189                                 delete[] curPart->m_vertices3f;
190
191                         if (curPart->m_vertices3d)
192                                 delete[] curPart->m_vertices3d;
193
194                         if (curPart->m_indices32)
195                                 delete[] curPart->m_indices32;
196
197                         if (curPart->m_3indices16)
198                                 delete[] curPart->m_3indices16;
199
200                         if (curPart->m_indices16)
201                                 delete[] curPart->m_indices16;
202
203                         if (curPart->m_3indices8)
204                                 delete[] curPart->m_3indices8;
205                 }
206                 delete[] curData->m_meshPartsPtr;
207                 delete curData;
208         }
209         m_allocatedbtStridingMeshInterfaceDatas.clear();
210
211         for (i = 0; i < m_indexArrays.size(); i++)
212         {
213                 btAlignedFree(m_indexArrays[i]);
214         }
215         m_indexArrays.clear();
216
217         for (i = 0; i < m_shortIndexArrays.size(); i++)
218         {
219                 btAlignedFree(m_shortIndexArrays[i]);
220         }
221         m_shortIndexArrays.clear();
222
223         for (i = 0; i < m_charIndexArrays.size(); i++)
224         {
225                 btAlignedFree(m_charIndexArrays[i]);
226         }
227         m_charIndexArrays.clear();
228
229         for (i = 0; i < m_floatVertexArrays.size(); i++)
230         {
231                 btAlignedFree(m_floatVertexArrays[i]);
232         }
233         m_floatVertexArrays.clear();
234
235         for (i = 0; i < m_doubleVertexArrays.size(); i++)
236         {
237                 btAlignedFree(m_doubleVertexArrays[i]);
238         }
239         m_doubleVertexArrays.clear();
240 }
241
242 btCollisionShape* btCollisionWorldImporter::convertCollisionShape(btCollisionShapeData* shapeData)
243 {
244         btCollisionShape* shape = 0;
245
246         switch (shapeData->m_shapeType)
247         {
248                 case STATIC_PLANE_PROXYTYPE:
249                 {
250                         btStaticPlaneShapeData* planeData = (btStaticPlaneShapeData*)shapeData;
251                         btVector3 planeNormal, localScaling;
252                         planeNormal.deSerializeFloat(planeData->m_planeNormal);
253                         localScaling.deSerializeFloat(planeData->m_localScaling);
254                         shape = createPlaneShape(planeNormal, planeData->m_planeConstant);
255                         shape->setLocalScaling(localScaling);
256
257                         break;
258                 }
259                 case SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE:
260                 {
261                         btScaledTriangleMeshShapeData* scaledMesh = (btScaledTriangleMeshShapeData*)shapeData;
262                         btCollisionShapeData* colShapeData = (btCollisionShapeData*)&scaledMesh->m_trimeshShapeData;
263                         colShapeData->m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE;
264                         btCollisionShape* childShape = convertCollisionShape(colShapeData);
265                         btBvhTriangleMeshShape* meshShape = (btBvhTriangleMeshShape*)childShape;
266                         btVector3 localScaling;
267                         localScaling.deSerializeFloat(scaledMesh->m_localScaling);
268
269                         shape = createScaledTrangleMeshShape(meshShape, localScaling);
270                         break;
271                 }
272 #ifdef SUPPORT_GIMPACT_SHAPE_IMPORT
273                 case GIMPACT_SHAPE_PROXYTYPE:
274                 {
275                         btGImpactMeshShapeData* gimpactData = (btGImpactMeshShapeData*)shapeData;
276                         if (gimpactData->m_gimpactSubType == CONST_GIMPACT_TRIMESH_SHAPE)
277                         {
278                                 btStridingMeshInterfaceData* interfaceData = createStridingMeshInterfaceData(&gimpactData->m_meshInterface);
279                                 btTriangleIndexVertexArray* meshInterface = createMeshInterface(*interfaceData);
280
281                                 btGImpactMeshShape* gimpactShape = createGimpactShape(meshInterface);
282                                 btVector3 localScaling;
283                                 localScaling.deSerializeFloat(gimpactData->m_localScaling);
284                                 gimpactShape->setLocalScaling(localScaling);
285                                 gimpactShape->setMargin(btScalar(gimpactData->m_collisionMargin));
286                                 gimpactShape->updateBound();
287                                 shape = gimpactShape;
288                         }
289                         else
290                         {
291                                 printf("unsupported gimpact sub type\n");
292                         }
293                         break;
294                 }
295 #endif  //SUPPORT_GIMPACT_SHAPE_IMPORT
296                 //The btCapsuleShape* API has issue passing the margin/scaling/halfextents unmodified through the API
297                 //so deal with this
298                 case CAPSULE_SHAPE_PROXYTYPE:
299                 {
300                         btCapsuleShapeData* capData = (btCapsuleShapeData*)shapeData;
301
302                         switch (capData->m_upAxis)
303                         {
304                                 case 0:
305                                 {
306                                         shape = createCapsuleShapeX(1, 1);
307                                         break;
308                                 }
309                                 case 1:
310                                 {
311                                         shape = createCapsuleShapeY(1, 1);
312                                         break;
313                                 }
314                                 case 2:
315                                 {
316                                         shape = createCapsuleShapeZ(1, 1);
317                                         break;
318                                 }
319                                 default:
320                                 {
321                                         printf("error: wrong up axis for btCapsuleShape\n");
322                                 }
323                         };
324                         if (shape)
325                         {
326                                 btCapsuleShape* cap = (btCapsuleShape*)shape;
327                                 cap->deSerializeFloat(capData);
328                         }
329                         break;
330                 }
331                 case CYLINDER_SHAPE_PROXYTYPE:
332                 case CONE_SHAPE_PROXYTYPE:
333                 case BOX_SHAPE_PROXYTYPE:
334                 case SPHERE_SHAPE_PROXYTYPE:
335                 case MULTI_SPHERE_SHAPE_PROXYTYPE:
336                 case CONVEX_HULL_SHAPE_PROXYTYPE:
337                 {
338                         btConvexInternalShapeData* bsd = (btConvexInternalShapeData*)shapeData;
339                         btVector3 implicitShapeDimensions;
340                         implicitShapeDimensions.deSerializeFloat(bsd->m_implicitShapeDimensions);
341                         btVector3 localScaling;
342                         localScaling.deSerializeFloat(bsd->m_localScaling);
343                         btVector3 margin(bsd->m_collisionMargin, bsd->m_collisionMargin, bsd->m_collisionMargin);
344                         switch (shapeData->m_shapeType)
345                         {
346                                 case BOX_SHAPE_PROXYTYPE:
347                                 {
348                                         btBoxShape* box = (btBoxShape*)createBoxShape(implicitShapeDimensions / localScaling + margin);
349                                         //box->initializePolyhedralFeatures();
350                                         shape = box;
351
352                                         break;
353                                 }
354                                 case SPHERE_SHAPE_PROXYTYPE:
355                                 {
356                                         shape = createSphereShape(implicitShapeDimensions.getX());
357                                         break;
358                                 }
359
360                                 case CYLINDER_SHAPE_PROXYTYPE:
361                                 {
362                                         btCylinderShapeData* cylData = (btCylinderShapeData*)shapeData;
363                                         btVector3 halfExtents = implicitShapeDimensions + margin;
364                                         switch (cylData->m_upAxis)
365                                         {
366                                                 case 0:
367                                                 {
368                                                         shape = createCylinderShapeX(halfExtents.getY(), halfExtents.getX());
369                                                         break;
370                                                 }
371                                                 case 1:
372                                                 {
373                                                         shape = createCylinderShapeY(halfExtents.getX(), halfExtents.getY());
374                                                         break;
375                                                 }
376                                                 case 2:
377                                                 {
378                                                         shape = createCylinderShapeZ(halfExtents.getX(), halfExtents.getZ());
379                                                         break;
380                                                 }
381                                                 default:
382                                                 {
383                                                         printf("unknown Cylinder up axis\n");
384                                                 }
385                                         };
386
387                                         break;
388                                 }
389                                 case CONE_SHAPE_PROXYTYPE:
390                                 {
391                                         btConeShapeData* conData = (btConeShapeData*)shapeData;
392                                         btVector3 halfExtents = implicitShapeDimensions;  //+margin;
393                                         switch (conData->m_upIndex)
394                                         {
395                                                 case 0:
396                                                 {
397                                                         shape = createConeShapeX(halfExtents.getY(), halfExtents.getX());
398                                                         break;
399                                                 }
400                                                 case 1:
401                                                 {
402                                                         shape = createConeShapeY(halfExtents.getX(), halfExtents.getY());
403                                                         break;
404                                                 }
405                                                 case 2:
406                                                 {
407                                                         shape = createConeShapeZ(halfExtents.getX(), halfExtents.getZ());
408                                                         break;
409                                                 }
410                                                 default:
411                                                 {
412                                                         printf("unknown Cone up axis\n");
413                                                 }
414                                         };
415
416                                         break;
417                                 }
418                                 case MULTI_SPHERE_SHAPE_PROXYTYPE:
419                                 {
420                                         btMultiSphereShapeData* mss = (btMultiSphereShapeData*)bsd;
421                                         int numSpheres = mss->m_localPositionArraySize;
422
423                                         btAlignedObjectArray<btVector3> tmpPos;
424                                         btAlignedObjectArray<btScalar> radii;
425                                         radii.resize(numSpheres);
426                                         tmpPos.resize(numSpheres);
427                                         int i;
428                                         for (i = 0; i < numSpheres; i++)
429                                         {
430                                                 tmpPos[i].deSerializeFloat(mss->m_localPositionArrayPtr[i].m_pos);
431                                                 radii[i] = mss->m_localPositionArrayPtr[i].m_radius;
432                                         }
433                                         shape = createMultiSphereShape(&tmpPos[0], &radii[0], numSpheres);
434                                         break;
435                                 }
436                                 case CONVEX_HULL_SHAPE_PROXYTYPE:
437                                 {
438                                         //      int sz = sizeof(btConvexHullShapeData);
439                                         //      int sz2 = sizeof(btConvexInternalShapeData);
440                                         //      int sz3 = sizeof(btCollisionShapeData);
441                                         btConvexHullShapeData* convexData = (btConvexHullShapeData*)bsd;
442                                         int numPoints = convexData->m_numUnscaledPoints;
443
444                                         btAlignedObjectArray<btVector3> tmpPoints;
445                                         tmpPoints.resize(numPoints);
446                                         int i;
447                                         for (i = 0; i < numPoints; i++)
448                                         {
449 #ifdef BT_USE_DOUBLE_PRECISION
450                                                 if (convexData->m_unscaledPointsDoublePtr)
451                                                         tmpPoints[i].deSerialize(convexData->m_unscaledPointsDoublePtr[i]);
452                                                 if (convexData->m_unscaledPointsFloatPtr)
453                                                         tmpPoints[i].deSerializeFloat(convexData->m_unscaledPointsFloatPtr[i]);
454 #else
455                                                 if (convexData->m_unscaledPointsFloatPtr)
456                                                         tmpPoints[i].deSerialize(convexData->m_unscaledPointsFloatPtr[i]);
457                                                 if (convexData->m_unscaledPointsDoublePtr)
458                                                         tmpPoints[i].deSerializeDouble(convexData->m_unscaledPointsDoublePtr[i]);
459 #endif  //BT_USE_DOUBLE_PRECISION
460                                         }
461                                         btConvexHullShape* hullShape = createConvexHullShape();
462                                         for (i = 0; i < numPoints; i++)
463                                         {
464                                                 hullShape->addPoint(tmpPoints[i]);
465                                         }
466                                         hullShape->setMargin(bsd->m_collisionMargin);
467                                         //hullShape->initializePolyhedralFeatures();
468                                         shape = hullShape;
469                                         break;
470                                 }
471                                 default:
472                                 {
473                                         printf("error: cannot create shape type (%d)\n", shapeData->m_shapeType);
474                                 }
475                         }
476
477                         if (shape)
478                         {
479                                 shape->setMargin(bsd->m_collisionMargin);
480
481                                 btVector3 localScaling;
482                                 localScaling.deSerializeFloat(bsd->m_localScaling);
483                                 shape->setLocalScaling(localScaling);
484                         }
485                         break;
486                 }
487                 case TRIANGLE_MESH_SHAPE_PROXYTYPE:
488                 {
489                         btTriangleMeshShapeData* trimesh = (btTriangleMeshShapeData*)shapeData;
490                         btStridingMeshInterfaceData* interfaceData = createStridingMeshInterfaceData(&trimesh->m_meshInterface);
491                         btTriangleIndexVertexArray* meshInterface = createMeshInterface(*interfaceData);
492                         if (!meshInterface->getNumSubParts())
493                         {
494                                 return 0;
495                         }
496
497                         btVector3 scaling;
498                         scaling.deSerializeFloat(trimesh->m_meshInterface.m_scaling);
499                         meshInterface->setScaling(scaling);
500
501                         btOptimizedBvh* bvh = 0;
502 #if 1
503                         if (trimesh->m_quantizedFloatBvh)
504                         {
505                                 btOptimizedBvh** bvhPtr = m_bvhMap.find(trimesh->m_quantizedFloatBvh);
506                                 if (bvhPtr && *bvhPtr)
507                                 {
508                                         bvh = *bvhPtr;
509                                 }
510                                 else
511                                 {
512                                         bvh = createOptimizedBvh();
513                                         bvh->deSerializeFloat(*trimesh->m_quantizedFloatBvh);
514                                 }
515                         }
516                         if (trimesh->m_quantizedDoubleBvh)
517                         {
518                                 btOptimizedBvh** bvhPtr = m_bvhMap.find(trimesh->m_quantizedDoubleBvh);
519                                 if (bvhPtr && *bvhPtr)
520                                 {
521                                         bvh = *bvhPtr;
522                                 }
523                                 else
524                                 {
525                                         bvh = createOptimizedBvh();
526                                         bvh->deSerializeDouble(*trimesh->m_quantizedDoubleBvh);
527                                 }
528                         }
529 #endif
530
531                         btBvhTriangleMeshShape* trimeshShape = createBvhTriangleMeshShape(meshInterface, bvh);
532                         trimeshShape->setMargin(trimesh->m_collisionMargin);
533                         shape = trimeshShape;
534
535                         if (trimesh->m_triangleInfoMap)
536                         {
537                                 btTriangleInfoMap* map = createTriangleInfoMap();
538                                 map->deSerialize(*trimesh->m_triangleInfoMap);
539                                 trimeshShape->setTriangleInfoMap(map);
540
541 #ifdef USE_INTERNAL_EDGE_UTILITY
542                                 gContactAddedCallback = btAdjustInternalEdgeContactsCallback;
543 #endif  //USE_INTERNAL_EDGE_UTILITY
544                         }
545
546                         //printf("trimesh->m_collisionMargin=%f\n",trimesh->m_collisionMargin);
547                         break;
548                 }
549                 case COMPOUND_SHAPE_PROXYTYPE:
550                 {
551                         btCompoundShapeData* compoundData = (btCompoundShapeData*)shapeData;
552                         btCompoundShape* compoundShape = createCompoundShape();
553
554                         //btCompoundShapeChildData* childShapeDataArray = &compoundData->m_childShapePtr[0];
555
556                         btAlignedObjectArray<btCollisionShape*> childShapes;
557                         for (int i = 0; i < compoundData->m_numChildShapes; i++)
558                         {
559                                 //btCompoundShapeChildData* ptr = &compoundData->m_childShapePtr[i];
560
561                                 btCollisionShapeData* cd = compoundData->m_childShapePtr[i].m_childShape;
562
563                                 btCollisionShape* childShape = convertCollisionShape(cd);
564                                 if (childShape)
565                                 {
566                                         btTransform localTransform;
567                                         localTransform.deSerializeFloat(compoundData->m_childShapePtr[i].m_transform);
568                                         compoundShape->addChildShape(localTransform, childShape);
569                                 }
570                                 else
571                                 {
572 #ifdef _DEBUG
573                                         printf("error: couldn't create childShape for compoundShape\n");
574 #endif
575                                 }
576                         }
577                         shape = compoundShape;
578
579                         break;
580                 }
581                 case SOFTBODY_SHAPE_PROXYTYPE:
582                 {
583                         return 0;
584                 }
585                 default:
586                 {
587 #ifdef _DEBUG
588                         printf("unsupported shape type (%d)\n", shapeData->m_shapeType);
589 #endif
590                 }
591         }
592
593         return shape;
594 }
595
596 char* btCollisionWorldImporter::duplicateName(const char* name)
597 {
598         if (name)
599         {
600                 int l = (int)strlen(name);
601                 char* newName = new char[l + 1];
602                 memcpy(newName, name, l);
603                 newName[l] = 0;
604                 m_allocatedNames.push_back(newName);
605                 return newName;
606         }
607         return 0;
608 }
609
610 btTriangleIndexVertexArray* btCollisionWorldImporter::createMeshInterface(btStridingMeshInterfaceData& meshData)
611 {
612         btTriangleIndexVertexArray* meshInterface = createTriangleMeshContainer();
613
614         for (int i = 0; i < meshData.m_numMeshParts; i++)
615         {
616                 btIndexedMesh meshPart;
617                 meshPart.m_numTriangles = meshData.m_meshPartsPtr[i].m_numTriangles;
618                 meshPart.m_numVertices = meshData.m_meshPartsPtr[i].m_numVertices;
619
620                 if (meshData.m_meshPartsPtr[i].m_indices32)
621                 {
622                         meshPart.m_indexType = PHY_INTEGER;
623                         meshPart.m_triangleIndexStride = 3 * sizeof(int);
624                         int* indexArray = (int*)btAlignedAlloc(sizeof(int) * 3 * meshPart.m_numTriangles, 16);
625                         m_indexArrays.push_back(indexArray);
626                         for (int j = 0; j < 3 * meshPart.m_numTriangles; j++)
627                         {
628                                 indexArray[j] = meshData.m_meshPartsPtr[i].m_indices32[j].m_value;
629                         }
630                         meshPart.m_triangleIndexBase = (const unsigned char*)indexArray;
631                 }
632                 else
633                 {
634                         if (meshData.m_meshPartsPtr[i].m_3indices16)
635                         {
636                                 meshPart.m_indexType = PHY_SHORT;
637                                 meshPart.m_triangleIndexStride = sizeof(short int) * 3;  //sizeof(btShortIntIndexTripletData);
638
639                                 short int* indexArray = (short int*)btAlignedAlloc(sizeof(short int) * 3 * meshPart.m_numTriangles, 16);
640                                 m_shortIndexArrays.push_back(indexArray);
641
642                                 for (int j = 0; j < meshPart.m_numTriangles; j++)
643                                 {
644                                         indexArray[3 * j] = meshData.m_meshPartsPtr[i].m_3indices16[j].m_values[0];
645                                         indexArray[3 * j + 1] = meshData.m_meshPartsPtr[i].m_3indices16[j].m_values[1];
646                                         indexArray[3 * j + 2] = meshData.m_meshPartsPtr[i].m_3indices16[j].m_values[2];
647                                 }
648
649                                 meshPart.m_triangleIndexBase = (const unsigned char*)indexArray;
650                         }
651                         if (meshData.m_meshPartsPtr[i].m_indices16)
652                         {
653                                 meshPart.m_indexType = PHY_SHORT;
654                                 meshPart.m_triangleIndexStride = 3 * sizeof(short int);
655                                 short int* indexArray = (short int*)btAlignedAlloc(sizeof(short int) * 3 * meshPart.m_numTriangles, 16);
656                                 m_shortIndexArrays.push_back(indexArray);
657                                 for (int j = 0; j < 3 * meshPart.m_numTriangles; j++)
658                                 {
659                                         indexArray[j] = meshData.m_meshPartsPtr[i].m_indices16[j].m_value;
660                                 }
661
662                                 meshPart.m_triangleIndexBase = (const unsigned char*)indexArray;
663                         }
664
665                         if (meshData.m_meshPartsPtr[i].m_3indices8)
666                         {
667                                 meshPart.m_indexType = PHY_UCHAR;
668                                 meshPart.m_triangleIndexStride = sizeof(unsigned char) * 3;
669
670                                 unsigned char* indexArray = (unsigned char*)btAlignedAlloc(sizeof(unsigned char) * 3 * meshPart.m_numTriangles, 16);
671                                 m_charIndexArrays.push_back(indexArray);
672
673                                 for (int j = 0; j < meshPart.m_numTriangles; j++)
674                                 {
675                                         indexArray[3 * j] = meshData.m_meshPartsPtr[i].m_3indices8[j].m_values[0];
676                                         indexArray[3 * j + 1] = meshData.m_meshPartsPtr[i].m_3indices8[j].m_values[1];
677                                         indexArray[3 * j + 2] = meshData.m_meshPartsPtr[i].m_3indices8[j].m_values[2];
678                                 }
679
680                                 meshPart.m_triangleIndexBase = (const unsigned char*)indexArray;
681                         }
682                 }
683
684                 if (meshData.m_meshPartsPtr[i].m_vertices3f)
685                 {
686                         meshPart.m_vertexType = PHY_FLOAT;
687                         meshPart.m_vertexStride = sizeof(btVector3FloatData);
688                         btVector3FloatData* vertices = (btVector3FloatData*)btAlignedAlloc(sizeof(btVector3FloatData) * meshPart.m_numVertices, 16);
689                         m_floatVertexArrays.push_back(vertices);
690
691                         for (int j = 0; j < meshPart.m_numVertices; j++)
692                         {
693                                 vertices[j].m_floats[0] = meshData.m_meshPartsPtr[i].m_vertices3f[j].m_floats[0];
694                                 vertices[j].m_floats[1] = meshData.m_meshPartsPtr[i].m_vertices3f[j].m_floats[1];
695                                 vertices[j].m_floats[2] = meshData.m_meshPartsPtr[i].m_vertices3f[j].m_floats[2];
696                                 vertices[j].m_floats[3] = meshData.m_meshPartsPtr[i].m_vertices3f[j].m_floats[3];
697                         }
698                         meshPart.m_vertexBase = (const unsigned char*)vertices;
699                 }
700                 else
701                 {
702                         meshPart.m_vertexType = PHY_DOUBLE;
703                         meshPart.m_vertexStride = sizeof(btVector3DoubleData);
704
705                         btVector3DoubleData* vertices = (btVector3DoubleData*)btAlignedAlloc(sizeof(btVector3DoubleData) * meshPart.m_numVertices, 16);
706                         m_doubleVertexArrays.push_back(vertices);
707
708                         for (int j = 0; j < meshPart.m_numVertices; j++)
709                         {
710                                 vertices[j].m_floats[0] = meshData.m_meshPartsPtr[i].m_vertices3d[j].m_floats[0];
711                                 vertices[j].m_floats[1] = meshData.m_meshPartsPtr[i].m_vertices3d[j].m_floats[1];
712                                 vertices[j].m_floats[2] = meshData.m_meshPartsPtr[i].m_vertices3d[j].m_floats[2];
713                                 vertices[j].m_floats[3] = meshData.m_meshPartsPtr[i].m_vertices3d[j].m_floats[3];
714                         }
715                         meshPart.m_vertexBase = (const unsigned char*)vertices;
716                 }
717
718                 if (meshPart.m_triangleIndexBase && meshPart.m_vertexBase)
719                 {
720                         meshInterface->addIndexedMesh(meshPart, meshPart.m_indexType);
721                 }
722         }
723
724         return meshInterface;
725 }
726
727 btStridingMeshInterfaceData* btCollisionWorldImporter::createStridingMeshInterfaceData(btStridingMeshInterfaceData* interfaceData)
728 {
729         //create a new btStridingMeshInterfaceData that is an exact copy of shapedata and store it in the WorldImporter
730         btStridingMeshInterfaceData* newData = new btStridingMeshInterfaceData;
731
732         newData->m_scaling = interfaceData->m_scaling;
733         newData->m_numMeshParts = interfaceData->m_numMeshParts;
734         newData->m_meshPartsPtr = new btMeshPartData[newData->m_numMeshParts];
735
736         for (int i = 0; i < newData->m_numMeshParts; i++)
737         {
738                 btMeshPartData* curPart = &interfaceData->m_meshPartsPtr[i];
739                 btMeshPartData* curNewPart = &newData->m_meshPartsPtr[i];
740
741                 curNewPart->m_numTriangles = curPart->m_numTriangles;
742                 curNewPart->m_numVertices = curPart->m_numVertices;
743
744                 if (curPart->m_vertices3f)
745                 {
746                         curNewPart->m_vertices3f = new btVector3FloatData[curNewPart->m_numVertices];
747                         memcpy(curNewPart->m_vertices3f, curPart->m_vertices3f, sizeof(btVector3FloatData) * curNewPart->m_numVertices);
748                 }
749                 else
750                         curNewPart->m_vertices3f = NULL;
751
752                 if (curPart->m_vertices3d)
753                 {
754                         curNewPart->m_vertices3d = new btVector3DoubleData[curNewPart->m_numVertices];
755                         memcpy(curNewPart->m_vertices3d, curPart->m_vertices3d, sizeof(btVector3DoubleData) * curNewPart->m_numVertices);
756                 }
757                 else
758                         curNewPart->m_vertices3d = NULL;
759
760                 int numIndices = curNewPart->m_numTriangles * 3;
761                 ///the m_3indices8 was not initialized in some Bullet versions, this can cause crashes at loading time
762                 ///we catch it by only dealing with m_3indices8 if none of the other indices are initialized
763                 bool uninitialized3indices8Workaround = false;
764
765                 if (curPart->m_indices32)
766                 {
767                         uninitialized3indices8Workaround = true;
768                         curNewPart->m_indices32 = new btIntIndexData[numIndices];
769                         memcpy(curNewPart->m_indices32, curPart->m_indices32, sizeof(btIntIndexData) * numIndices);
770                 }
771                 else
772                         curNewPart->m_indices32 = NULL;
773
774                 if (curPart->m_3indices16)
775                 {
776                         uninitialized3indices8Workaround = true;
777                         curNewPart->m_3indices16 = new btShortIntIndexTripletData[curNewPart->m_numTriangles];
778                         memcpy(curNewPart->m_3indices16, curPart->m_3indices16, sizeof(btShortIntIndexTripletData) * curNewPart->m_numTriangles);
779                 }
780                 else
781                         curNewPart->m_3indices16 = NULL;
782
783                 if (curPart->m_indices16)
784                 {
785                         uninitialized3indices8Workaround = true;
786                         curNewPart->m_indices16 = new btShortIntIndexData[numIndices];
787                         memcpy(curNewPart->m_indices16, curPart->m_indices16, sizeof(btShortIntIndexData) * numIndices);
788                 }
789                 else
790                         curNewPart->m_indices16 = NULL;
791
792                 if (!uninitialized3indices8Workaround && curPart->m_3indices8)
793                 {
794                         curNewPart->m_3indices8 = new btCharIndexTripletData[curNewPart->m_numTriangles];
795                         memcpy(curNewPart->m_3indices8, curPart->m_3indices8, sizeof(btCharIndexTripletData) * curNewPart->m_numTriangles);
796                 }
797                 else
798                         curNewPart->m_3indices8 = NULL;
799         }
800
801         m_allocatedbtStridingMeshInterfaceDatas.push_back(newData);
802
803         return (newData);
804 }
805
806 #ifdef USE_INTERNAL_EDGE_UTILITY
807 extern ContactAddedCallback gContactAddedCallback;
808
809 static bool btAdjustInternalEdgeContactsCallback(btManifoldPoint& cp, const btCollisionObject* colObj0, int partId0, int index0, const btCollisionObject* colObj1, int partId1, int index1)
810 {
811         btAdjustInternalEdgeContacts(cp, colObj1, colObj0, partId1, index1);
812         //btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_BACKFACE_MODE);
813         //btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_DOUBLE_SIDED+BT_TRIANGLE_CONCAVE_DOUBLE_SIDED);
814         return true;
815 }
816 #endif  //USE_INTERNAL_EDGE_UTILITY
817
818 /*
819 btRigidBody*  btWorldImporter::createRigidBody(bool isDynamic, btScalar mass, const btTransform& startTransform,btCollisionShape* shape,const char* bodyName)
820 {
821         btVector3 localInertia;
822         localInertia.setZero();
823
824         if (mass)
825                 shape->calculateLocalInertia(mass,localInertia);
826
827         btRigidBody* body = new btRigidBody(mass,0,shape,localInertia);
828         body->setWorldTransform(startTransform);
829
830         if (m_dynamicsWorld)
831                 m_dynamicsWorld->addRigidBody(body);
832
833         if (bodyName)
834         {
835                 char* newname = duplicateName(bodyName);
836                 m_objectNameMap.insert(body,newname);
837                 m_nameBodyMap.insert(newname,body);
838         }
839         m_allocatedRigidBodies.push_back(body);
840         return body;
841
842 }
843 */
844
845 btCollisionObject* btCollisionWorldImporter::getCollisionObjectByName(const char* name)
846 {
847         btCollisionObject** bodyPtr = m_nameColObjMap.find(name);
848         if (bodyPtr && *bodyPtr)
849         {
850                 return *bodyPtr;
851         }
852         return 0;
853 }
854
855 btCollisionObject* btCollisionWorldImporter::createCollisionObject(const btTransform& startTransform, btCollisionShape* shape, const char* bodyName)
856 {
857         btCollisionObject* colObj = new btCollisionObject();
858         colObj->setWorldTransform(startTransform);
859         colObj->setCollisionShape(shape);
860         m_collisionWorld->addCollisionObject(colObj);  //todo: flags etc
861
862         if (bodyName)
863         {
864                 char* newname = duplicateName(bodyName);
865                 m_objectNameMap.insert(colObj, newname);
866                 m_nameColObjMap.insert(newname, colObj);
867         }
868         m_allocatedCollisionObjects.push_back(colObj);
869
870         return colObj;
871 }
872
873 btCollisionShape* btCollisionWorldImporter::createPlaneShape(const btVector3& planeNormal, btScalar planeConstant)
874 {
875         btStaticPlaneShape* shape = new btStaticPlaneShape(planeNormal, planeConstant);
876         m_allocatedCollisionShapes.push_back(shape);
877         return shape;
878 }
879 btCollisionShape* btCollisionWorldImporter::createBoxShape(const btVector3& halfExtents)
880 {
881         btBoxShape* shape = new btBoxShape(halfExtents);
882         m_allocatedCollisionShapes.push_back(shape);
883         return shape;
884 }
885 btCollisionShape* btCollisionWorldImporter::createSphereShape(btScalar radius)
886 {
887         btSphereShape* shape = new btSphereShape(radius);
888         m_allocatedCollisionShapes.push_back(shape);
889         return shape;
890 }
891
892 btCollisionShape* btCollisionWorldImporter::createCapsuleShapeX(btScalar radius, btScalar height)
893 {
894         btCapsuleShapeX* shape = new btCapsuleShapeX(radius, height);
895         m_allocatedCollisionShapes.push_back(shape);
896         return shape;
897 }
898
899 btCollisionShape* btCollisionWorldImporter::createCapsuleShapeY(btScalar radius, btScalar height)
900 {
901         btCapsuleShape* shape = new btCapsuleShape(radius, height);
902         m_allocatedCollisionShapes.push_back(shape);
903         return shape;
904 }
905
906 btCollisionShape* btCollisionWorldImporter::createCapsuleShapeZ(btScalar radius, btScalar height)
907 {
908         btCapsuleShapeZ* shape = new btCapsuleShapeZ(radius, height);
909         m_allocatedCollisionShapes.push_back(shape);
910         return shape;
911 }
912
913 btCollisionShape* btCollisionWorldImporter::createCylinderShapeX(btScalar radius, btScalar height)
914 {
915         btCylinderShapeX* shape = new btCylinderShapeX(btVector3(height, radius, radius));
916         m_allocatedCollisionShapes.push_back(shape);
917         return shape;
918 }
919
920 btCollisionShape* btCollisionWorldImporter::createCylinderShapeY(btScalar radius, btScalar height)
921 {
922         btCylinderShape* shape = new btCylinderShape(btVector3(radius, height, radius));
923         m_allocatedCollisionShapes.push_back(shape);
924         return shape;
925 }
926
927 btCollisionShape* btCollisionWorldImporter::createCylinderShapeZ(btScalar radius, btScalar height)
928 {
929         btCylinderShapeZ* shape = new btCylinderShapeZ(btVector3(radius, radius, height));
930         m_allocatedCollisionShapes.push_back(shape);
931         return shape;
932 }
933
934 btCollisionShape* btCollisionWorldImporter::createConeShapeX(btScalar radius, btScalar height)
935 {
936         btConeShapeX* shape = new btConeShapeX(radius, height);
937         m_allocatedCollisionShapes.push_back(shape);
938         return shape;
939 }
940
941 btCollisionShape* btCollisionWorldImporter::createConeShapeY(btScalar radius, btScalar height)
942 {
943         btConeShape* shape = new btConeShape(radius, height);
944         m_allocatedCollisionShapes.push_back(shape);
945         return shape;
946 }
947
948 btCollisionShape* btCollisionWorldImporter::createConeShapeZ(btScalar radius, btScalar height)
949 {
950         btConeShapeZ* shape = new btConeShapeZ(radius, height);
951         m_allocatedCollisionShapes.push_back(shape);
952         return shape;
953 }
954
955 btTriangleIndexVertexArray* btCollisionWorldImporter::createTriangleMeshContainer()
956 {
957         btTriangleIndexVertexArray* in = new btTriangleIndexVertexArray();
958         m_allocatedTriangleIndexArrays.push_back(in);
959         return in;
960 }
961
962 btOptimizedBvh* btCollisionWorldImporter::createOptimizedBvh()
963 {
964         btOptimizedBvh* bvh = new btOptimizedBvh();
965         m_allocatedBvhs.push_back(bvh);
966         return bvh;
967 }
968
969 btTriangleInfoMap* btCollisionWorldImporter::createTriangleInfoMap()
970 {
971         btTriangleInfoMap* tim = new btTriangleInfoMap();
972         m_allocatedTriangleInfoMaps.push_back(tim);
973         return tim;
974 }
975
976 btBvhTriangleMeshShape* btCollisionWorldImporter::createBvhTriangleMeshShape(btStridingMeshInterface* trimesh, btOptimizedBvh* bvh)
977 {
978         if (bvh)
979         {
980                 btBvhTriangleMeshShape* bvhTriMesh = new btBvhTriangleMeshShape(trimesh, bvh->isQuantized(), false);
981                 bvhTriMesh->setOptimizedBvh(bvh);
982                 m_allocatedCollisionShapes.push_back(bvhTriMesh);
983                 return bvhTriMesh;
984         }
985
986         btBvhTriangleMeshShape* ts = new btBvhTriangleMeshShape(trimesh, true);
987         m_allocatedCollisionShapes.push_back(ts);
988         return ts;
989 }
990 btCollisionShape* btCollisionWorldImporter::createConvexTriangleMeshShape(btStridingMeshInterface* trimesh)
991 {
992         return 0;
993 }
994 #ifdef SUPPORT_GIMPACT_SHAPE_IMPORT
995 btGImpactMeshShape* btCollisionWorldImporter::createGimpactShape(btStridingMeshInterface* trimesh)
996 {
997         btGImpactMeshShape* shape = new btGImpactMeshShape(trimesh);
998         m_allocatedCollisionShapes.push_back(shape);
999         return shape;
1000 }
1001 #endif  //SUPPORT_GIMPACT_SHAPE_IMPORT
1002
1003 btConvexHullShape* btCollisionWorldImporter::createConvexHullShape()
1004 {
1005         btConvexHullShape* shape = new btConvexHullShape();
1006         m_allocatedCollisionShapes.push_back(shape);
1007         return shape;
1008 }
1009
1010 btCompoundShape* btCollisionWorldImporter::createCompoundShape()
1011 {
1012         btCompoundShape* shape = new btCompoundShape();
1013         m_allocatedCollisionShapes.push_back(shape);
1014         return shape;
1015 }
1016
1017 btScaledBvhTriangleMeshShape* btCollisionWorldImporter::createScaledTrangleMeshShape(btBvhTriangleMeshShape* meshShape, const btVector3& localScaling)
1018 {
1019         btScaledBvhTriangleMeshShape* shape = new btScaledBvhTriangleMeshShape(meshShape, localScaling);
1020         m_allocatedCollisionShapes.push_back(shape);
1021         return shape;
1022 }
1023
1024 btMultiSphereShape* btCollisionWorldImporter::createMultiSphereShape(const btVector3* positions, const btScalar* radi, int numSpheres)
1025 {
1026         btMultiSphereShape* shape = new btMultiSphereShape(positions, radi, numSpheres);
1027         m_allocatedCollisionShapes.push_back(shape);
1028         return shape;
1029 }
1030
1031 // query for data
1032 int btCollisionWorldImporter::getNumCollisionShapes() const
1033 {
1034         return m_allocatedCollisionShapes.size();
1035 }
1036
1037 btCollisionShape* btCollisionWorldImporter::getCollisionShapeByIndex(int index)
1038 {
1039         return m_allocatedCollisionShapes[index];
1040 }
1041
1042 btCollisionShape* btCollisionWorldImporter::getCollisionShapeByName(const char* name)
1043 {
1044         btCollisionShape** shapePtr = m_nameShapeMap.find(name);
1045         if (shapePtr && *shapePtr)
1046         {
1047                 return *shapePtr;
1048         }
1049         return 0;
1050 }
1051
1052 const char* btCollisionWorldImporter::getNameForPointer(const void* ptr) const
1053 {
1054         const char* const* namePtr = m_objectNameMap.find(ptr);
1055         if (namePtr && *namePtr)
1056                 return *namePtr;
1057         return 0;
1058 }
1059
1060 int btCollisionWorldImporter::getNumRigidBodies() const
1061 {
1062         return m_allocatedRigidBodies.size();
1063 }
1064
1065 btCollisionObject* btCollisionWorldImporter::getRigidBodyByIndex(int index) const
1066 {
1067         return m_allocatedRigidBodies[index];
1068 }
1069
1070 int btCollisionWorldImporter::getNumBvhs() const
1071 {
1072         return m_allocatedBvhs.size();
1073 }
1074 btOptimizedBvh* btCollisionWorldImporter::getBvhByIndex(int index) const
1075 {
1076         return m_allocatedBvhs[index];
1077 }
1078
1079 int btCollisionWorldImporter::getNumTriangleInfoMaps() const
1080 {
1081         return m_allocatedTriangleInfoMaps.size();
1082 }
1083
1084 btTriangleInfoMap* btCollisionWorldImporter::getTriangleInfoMapByIndex(int index) const
1085 {
1086         return m_allocatedTriangleInfoMaps[index];
1087 }