Imported Upstream version 2.81
[platform/upstream/libbullet.git] / Extras / Serialize / BulletWorldImporter / btWorldImporter.cpp
1 /*\r
2 Bullet Continuous Collision Detection and Physics Library\r
3 Copyright (c) 2003-2012 Erwin Coumans  http://bulletphysics.org\r
4 \r
5 This software is provided 'as-is', without any express or implied warranty.\r
6 In no event will the authors be held liable for any damages arising from the use of this software.\r
7 Permission is granted to anyone to use this software for any purpose, \r
8 including commercial applications, and to alter it and redistribute it freely, \r
9 subject to the following restrictions:\r
10 \r
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.\r
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\r
13 3. This notice may not be removed or altered from any source distribution.\r
14 */\r
15 \r
16 #include "btWorldImporter.h"\r
17 #include "btBulletDynamicsCommon.h"\r
18 #include "BulletCollision/Gimpact/btGImpactShape.h"\r
19 \r
20 btWorldImporter::btWorldImporter(btDynamicsWorld* world)\r
21 :m_dynamicsWorld(world),\r
22 m_verboseMode(0)\r
23 {\r
24 \r
25 }\r
26 \r
27 btWorldImporter::~btWorldImporter()\r
28 {\r
29 }\r
30 \r
31 void btWorldImporter::deleteAllData()\r
32 {\r
33         int i;\r
34         for (i=0;i<m_allocatedConstraints.size();i++)\r
35         {\r
36                 if(m_dynamicsWorld)\r
37                         m_dynamicsWorld->removeConstraint(m_allocatedConstraints[i]);\r
38                 delete m_allocatedConstraints[i];\r
39         }\r
40         m_allocatedConstraints.clear();\r
41 \r
42         \r
43         for (i=0;i<m_allocatedRigidBodies.size();i++)\r
44         {\r
45                 if(m_dynamicsWorld)\r
46                         m_dynamicsWorld->removeRigidBody(btRigidBody::upcast(m_allocatedRigidBodies[i]));\r
47                 delete m_allocatedRigidBodies[i];\r
48         }\r
49         \r
50         m_allocatedRigidBodies.clear();\r
51 \r
52 \r
53         for (i=0;i<m_allocatedCollisionShapes.size();i++)\r
54         {\r
55                 delete m_allocatedCollisionShapes[i];\r
56         }\r
57         m_allocatedCollisionShapes.clear();\r
58 \r
59         \r
60         for (i=0;i<m_allocatedBvhs.size();i++)\r
61         {\r
62                 delete m_allocatedBvhs[i];\r
63         }\r
64         m_allocatedBvhs.clear();\r
65         \r
66         for (i=0;i<m_allocatedTriangleInfoMaps.size();i++)\r
67         {\r
68                 delete m_allocatedTriangleInfoMaps[i];\r
69         }\r
70         m_allocatedTriangleInfoMaps.clear();\r
71         for (i=0;i<m_allocatedTriangleIndexArrays.size();i++)\r
72         {\r
73                 delete m_allocatedTriangleIndexArrays[i];\r
74         }\r
75         m_allocatedTriangleIndexArrays.clear();\r
76         for (i=0;i<m_allocatedNames.size();i++)\r
77         {\r
78                 delete[] m_allocatedNames[i];\r
79         }\r
80         m_allocatedNames.clear();\r
81 \r
82         for (i=0;i<m_allocatedbtStridingMeshInterfaceDatas.size();i++)\r
83         {\r
84                 btStridingMeshInterfaceData* curData = m_allocatedbtStridingMeshInterfaceDatas[i];\r
85 \r
86                 for(int a = 0;a < curData->m_numMeshParts;a++)\r
87                 {\r
88                         btMeshPartData* curPart = &curData->m_meshPartsPtr[a];\r
89                         if(curPart->m_vertices3f)\r
90                                 delete [] curPart->m_vertices3f;\r
91 \r
92                         if(curPart->m_vertices3d)\r
93                                 delete [] curPart->m_vertices3d;\r
94 \r
95                         if(curPart->m_indices32)\r
96                                 delete [] curPart->m_indices32;\r
97 \r
98                         if(curPart->m_3indices16)\r
99                                 delete [] curPart->m_3indices16;\r
100 \r
101                         if(curPart->m_indices16)\r
102                                 delete [] curPart->m_indices16;\r
103                         \r
104                         if (curPart->m_3indices8)\r
105                                 delete [] curPart->m_3indices8;\r
106 \r
107                 }\r
108                 delete [] curData->m_meshPartsPtr;\r
109                 delete curData;\r
110         }\r
111         m_allocatedbtStridingMeshInterfaceDatas.clear();\r
112 \r
113         for (i=0;i<m_indexArrays.size();i++)\r
114         {\r
115                 btAlignedFree(m_indexArrays[i]);\r
116         }\r
117   m_indexArrays.clear();\r
118 \r
119         for (i=0;i<m_shortIndexArrays.size();i++)\r
120         {\r
121                 btAlignedFree(m_shortIndexArrays[i]);\r
122         }\r
123   m_shortIndexArrays.clear();\r
124 \r
125         for (i=0;i<m_charIndexArrays.size();i++)\r
126         {\r
127                 btAlignedFree(m_charIndexArrays[i]);\r
128         }\r
129   m_charIndexArrays.clear();\r
130   \r
131         for (i=0;i<m_floatVertexArrays.size();i++)\r
132         {\r
133                 btAlignedFree(m_floatVertexArrays[i]);\r
134         }\r
135   m_floatVertexArrays.clear();\r
136 \r
137         for (i=0;i<m_doubleVertexArrays.size();i++)\r
138         {\r
139                 btAlignedFree(m_doubleVertexArrays[i]);\r
140         }\r
141    m_doubleVertexArrays.clear();\r
142    \r
143 \r
144 }\r
145 \r
146 \r
147 \r
148 btCollisionShape* btWorldImporter::convertCollisionShape(  btCollisionShapeData* shapeData  )\r
149 {\r
150         btCollisionShape* shape = 0;\r
151 \r
152         switch (shapeData->m_shapeType)\r
153                 {\r
154         case STATIC_PLANE_PROXYTYPE:\r
155                 {\r
156                         btStaticPlaneShapeData* planeData = (btStaticPlaneShapeData*)shapeData;\r
157                         btVector3 planeNormal,localScaling;\r
158                         planeNormal.deSerializeFloat(planeData->m_planeNormal);\r
159                         localScaling.deSerializeFloat(planeData->m_localScaling);\r
160                         shape = createPlaneShape(planeNormal,planeData->m_planeConstant);\r
161                         shape->setLocalScaling(localScaling);\r
162 \r
163                         break;\r
164                 }\r
165         case SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE:\r
166                 {\r
167                         btScaledTriangleMeshShapeData* scaledMesh = (btScaledTriangleMeshShapeData*) shapeData;\r
168                         btCollisionShapeData* colShapeData = (btCollisionShapeData*) &scaledMesh->m_trimeshShapeData;\r
169                         colShapeData->m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE;\r
170                         btCollisionShape* childShape = convertCollisionShape(colShapeData);\r
171                         btBvhTriangleMeshShape* meshShape = (btBvhTriangleMeshShape*)childShape;\r
172                         btVector3 localScaling;\r
173                         localScaling.deSerializeFloat(scaledMesh->m_localScaling);\r
174 \r
175                         shape = createScaledTrangleMeshShape(meshShape, localScaling);\r
176                         break;\r
177                 }\r
178         case GIMPACT_SHAPE_PROXYTYPE:\r
179                 {\r
180                         btGImpactMeshShapeData* gimpactData = (btGImpactMeshShapeData*) shapeData;\r
181                         if (gimpactData->m_gimpactSubType == CONST_GIMPACT_TRIMESH_SHAPE)\r
182                         {\r
183                                 btStridingMeshInterfaceData* interfaceData = createStridingMeshInterfaceData(&gimpactData->m_meshInterface);\r
184                                 btTriangleIndexVertexArray* meshInterface = createMeshInterface(*interfaceData);\r
185                                 \r
186 \r
187                                 btGImpactMeshShape* gimpactShape = createGimpactShape(meshInterface);\r
188                                 btVector3 localScaling;\r
189                                 localScaling.deSerializeFloat(gimpactData->m_localScaling);\r
190                                 gimpactShape->setLocalScaling(localScaling);\r
191                                 gimpactShape->setMargin(btScalar(gimpactData->m_collisionMargin));\r
192                                 gimpactShape->updateBound();\r
193                                 shape = gimpactShape;\r
194                         } else\r
195                         {\r
196                                 printf("unsupported gimpact sub type\n");\r
197                         }\r
198                         break;\r
199                 }\r
200 \r
201                 case CYLINDER_SHAPE_PROXYTYPE:\r
202                 case CAPSULE_SHAPE_PROXYTYPE:\r
203                 case BOX_SHAPE_PROXYTYPE:\r
204                 case SPHERE_SHAPE_PROXYTYPE:\r
205                 case MULTI_SPHERE_SHAPE_PROXYTYPE:\r
206                 case CONVEX_HULL_SHAPE_PROXYTYPE:\r
207                         {\r
208                                 btConvexInternalShapeData* bsd = (btConvexInternalShapeData*)shapeData;\r
209                                 btVector3 implicitShapeDimensions;\r
210                                 implicitShapeDimensions.deSerializeFloat(bsd->m_implicitShapeDimensions);\r
211                                 btVector3 localScaling;\r
212                                 localScaling.deSerializeFloat(bsd->m_localScaling);\r
213                                 btVector3 margin(bsd->m_collisionMargin,bsd->m_collisionMargin,bsd->m_collisionMargin);\r
214                                 switch (shapeData->m_shapeType)\r
215                                 {\r
216                                         case BOX_SHAPE_PROXYTYPE:\r
217                                                 {\r
218                                                         btBoxShape* box= (btBoxShape*)createBoxShape(implicitShapeDimensions/localScaling+margin);\r
219                                                         //box->initializePolyhedralFeatures();\r
220                                                         shape = box;\r
221                                                         \r
222                                                         break;\r
223                                                 }\r
224                                         case SPHERE_SHAPE_PROXYTYPE:\r
225                                                 {\r
226                                                         shape = createSphereShape(implicitShapeDimensions.getX());\r
227                                                         break;\r
228                                                 }\r
229                                         case CAPSULE_SHAPE_PROXYTYPE:\r
230                                                 {\r
231                                                         btCapsuleShapeData* capData = (btCapsuleShapeData*)shapeData;\r
232                                                         switch (capData->m_upAxis)\r
233                                                         {\r
234                                                         case 0:\r
235                                                                 {\r
236                                                                         shape = createCapsuleShapeX(implicitShapeDimensions.getY()+bsd->m_collisionMargin*2,2*implicitShapeDimensions.getX());\r
237                                                                         break;\r
238                                                                 }\r
239                                                         case 1:\r
240                                                                 {\r
241                                                                         shape = createCapsuleShapeY(implicitShapeDimensions.getX()+bsd->m_collisionMargin*2,2*implicitShapeDimensions.getY());\r
242                                                                         break;\r
243                                                                 }\r
244                                                         case 2:\r
245                                                                 {\r
246                                                                         shape = createCapsuleShapeZ(implicitShapeDimensions.getX()+bsd->m_collisionMargin*2,2*implicitShapeDimensions.getZ());\r
247                                                                         break;\r
248                                                                 }\r
249                                                         default:\r
250                                                                 {\r
251                                                                         printf("error: wrong up axis for btCapsuleShape\n");\r
252                                                                 }\r
253                                                                 bsd->m_collisionMargin = 0.f;\r
254 \r
255                                                         };\r
256                                                         \r
257                                                         break;\r
258                                                 }\r
259                                         case CYLINDER_SHAPE_PROXYTYPE:\r
260                                                 {\r
261                                                         btCylinderShapeData* cylData = (btCylinderShapeData*) shapeData;\r
262                                                         btVector3 halfExtents = implicitShapeDimensions+margin;\r
263                                                         switch (cylData->m_upAxis)\r
264                                                         {\r
265                                                         case 0:\r
266                                                                 {\r
267                                                                         shape = createCylinderShapeX(halfExtents.getY(),halfExtents.getX());\r
268                                                                         break;\r
269                                                                 }\r
270                                                         case 1:\r
271                                                                 {\r
272                                                                         shape = createCylinderShapeY(halfExtents.getX(),halfExtents.getY());\r
273                                                                         break;\r
274                                                                 }\r
275                                                         case 2:\r
276                                                                 {\r
277                                                                         shape = createCylinderShapeZ(halfExtents.getX(),halfExtents.getZ());\r
278                                                                         break;\r
279                                                                 }\r
280                                                         default:\r
281                                                                 {\r
282                                                                         printf("unknown Cylinder up axis\n");\r
283                                                                 }\r
284 \r
285                                                         };\r
286                                                         \r
287 \r
288                                                         \r
289                                                         break;\r
290                                                 }\r
291                                         case MULTI_SPHERE_SHAPE_PROXYTYPE:\r
292                                                 {\r
293                                                         btMultiSphereShapeData* mss = (btMultiSphereShapeData*)bsd;\r
294                                                         int numSpheres = mss->m_localPositionArraySize;\r
295 \r
296                                                         btAlignedObjectArray<btVector3> tmpPos;\r
297                                                         btAlignedObjectArray<btScalar> radii;\r
298                                                         radii.resize(numSpheres);\r
299                                                         tmpPos.resize(numSpheres);\r
300                                                         int i;\r
301                                                         for ( i=0;i<numSpheres;i++)\r
302                                                         {\r
303                                                                 tmpPos[i].deSerializeFloat(mss->m_localPositionArrayPtr[i].m_pos);\r
304                                                                 radii[i] = mss->m_localPositionArrayPtr[i].m_radius;\r
305                                                         }\r
306                                                         shape = createMultiSphereShape(&tmpPos[0],&radii[0],numSpheres);\r
307                                                         break;\r
308                                                 }\r
309                                         case CONVEX_HULL_SHAPE_PROXYTYPE:\r
310                                                 {\r
311                                                 //      int sz = sizeof(btConvexHullShapeData);\r
312                                                 //      int sz2 = sizeof(btConvexInternalShapeData);\r
313                                                 //      int sz3 = sizeof(btCollisionShapeData);\r
314                                                         btConvexHullShapeData* convexData = (btConvexHullShapeData*)bsd;\r
315                                                         int numPoints = convexData->m_numUnscaledPoints;\r
316 \r
317                                                         btAlignedObjectArray<btVector3> tmpPoints;\r
318                                                         tmpPoints.resize(numPoints);\r
319                                                         int i;\r
320                                                         for ( i=0;i<numPoints;i++)\r
321                                                         {\r
322 #ifdef BT_USE_DOUBLE_PRECISION\r
323                                                         if (convexData->m_unscaledPointsDoublePtr)\r
324                                                                 tmpPoints[i].deSerialize(convexData->m_unscaledPointsDoublePtr[i]);\r
325                                                         if (convexData->m_unscaledPointsFloatPtr)\r
326                                                                 tmpPoints[i].deSerializeFloat(convexData->m_unscaledPointsFloatPtr[i]);\r
327 #else\r
328                                                         if (convexData->m_unscaledPointsFloatPtr)\r
329                                                                 tmpPoints[i].deSerialize(convexData->m_unscaledPointsFloatPtr[i]);\r
330                                                         if (convexData->m_unscaledPointsDoublePtr)\r
331                                                                 tmpPoints[i].deSerializeDouble(convexData->m_unscaledPointsDoublePtr[i]);\r
332 #endif //BT_USE_DOUBLE_PRECISION\r
333                                                         }\r
334                                                         btConvexHullShape* hullShape = createConvexHullShape();\r
335                                                         for (i=0;i<numPoints;i++)\r
336                                                         {\r
337                                                                 hullShape->addPoint(tmpPoints[i]);\r
338                                                         }\r
339                                                         hullShape->setMargin(bsd->m_collisionMargin);\r
340                                                         //hullShape->initializePolyhedralFeatures();\r
341                                                         shape = hullShape;\r
342                                                         break;\r
343                                                 }\r
344                                         default:\r
345                                                 {\r
346                                                         printf("error: cannot create shape type (%d)\n",shapeData->m_shapeType);\r
347                                                 }\r
348                                 }\r
349 \r
350                                 if (shape)\r
351                                 {\r
352                                         shape->setMargin(bsd->m_collisionMargin);\r
353                                         \r
354                                         btVector3 localScaling;\r
355                                         localScaling.deSerializeFloat(bsd->m_localScaling);\r
356                                         shape->setLocalScaling(localScaling);\r
357                                         \r
358                                 }\r
359                                 break;\r
360                         }\r
361                 case TRIANGLE_MESH_SHAPE_PROXYTYPE:\r
362                 {\r
363                         btTriangleMeshShapeData* trimesh = (btTriangleMeshShapeData*)shapeData;\r
364                         btStridingMeshInterfaceData* interfaceData = createStridingMeshInterfaceData(&trimesh->m_meshInterface);\r
365                         btTriangleIndexVertexArray* meshInterface = createMeshInterface(*interfaceData);\r
366                         if (!meshInterface->getNumSubParts())\r
367                         {\r
368                                 return 0;\r
369                         }\r
370 \r
371                         btVector3 scaling; scaling.deSerializeFloat(trimesh->m_meshInterface.m_scaling);\r
372                         meshInterface->setScaling(scaling);\r
373 \r
374 \r
375                         btOptimizedBvh* bvh = 0;\r
376 #if 1\r
377                         if (trimesh->m_quantizedFloatBvh)\r
378                         {\r
379                                 btOptimizedBvh** bvhPtr = m_bvhMap.find(trimesh->m_quantizedFloatBvh);\r
380                                 if (bvhPtr && *bvhPtr)\r
381                                 {\r
382                                         bvh = *bvhPtr;\r
383                                 } else\r
384                                 {\r
385                                         bvh = createOptimizedBvh();\r
386                                         bvh->deSerializeFloat(*trimesh->m_quantizedFloatBvh);\r
387                                 }\r
388                         }\r
389                         if (trimesh->m_quantizedDoubleBvh)\r
390                         {\r
391                                 btOptimizedBvh** bvhPtr = m_bvhMap.find(trimesh->m_quantizedDoubleBvh);\r
392                                 if (bvhPtr && *bvhPtr)\r
393                                 {\r
394                                         bvh = *bvhPtr;\r
395                                 } else\r
396                                 {\r
397                                         bvh = createOptimizedBvh();\r
398                                         bvh->deSerializeDouble(*trimesh->m_quantizedDoubleBvh);\r
399                                 }\r
400                         }\r
401 #endif\r
402 \r
403 \r
404                         btBvhTriangleMeshShape* trimeshShape = createBvhTriangleMeshShape(meshInterface,bvh);\r
405                         trimeshShape->setMargin(trimesh->m_collisionMargin);\r
406                         shape = trimeshShape;\r
407 \r
408                         if (trimesh->m_triangleInfoMap)\r
409                         {\r
410                                 btTriangleInfoMap* map = createTriangleInfoMap();\r
411                                 map->deSerialize(*trimesh->m_triangleInfoMap);\r
412                                 trimeshShape->setTriangleInfoMap(map);\r
413 \r
414 #ifdef USE_INTERNAL_EDGE_UTILITY\r
415                                 gContactAddedCallback = btAdjustInternalEdgeContactsCallback;\r
416 #endif //USE_INTERNAL_EDGE_UTILITY\r
417 \r
418                         }\r
419 \r
420                         //printf("trimesh->m_collisionMargin=%f\n",trimesh->m_collisionMargin);\r
421                         break;\r
422                 }\r
423                 case COMPOUND_SHAPE_PROXYTYPE:\r
424                         {\r
425                                 btCompoundShapeData* compoundData = (btCompoundShapeData*)shapeData;\r
426                                 btCompoundShape* compoundShape = createCompoundShape();\r
427 \r
428                                 btCompoundShapeChildData* childShapeDataArray = &compoundData->m_childShapePtr[0];\r
429                                 \r
430 \r
431                                 btAlignedObjectArray<btCollisionShape*> childShapes;\r
432                                 for (int i=0;i<compoundData->m_numChildShapes;i++)\r
433                                 {\r
434                                         btCompoundShapeChildData* ptr = &compoundData->m_childShapePtr[i];\r
435 \r
436                                         btCollisionShapeData* cd = compoundData->m_childShapePtr[i].m_childShape;\r
437 \r
438                                         btCollisionShape* childShape = convertCollisionShape(cd);\r
439                                         if (childShape)\r
440                                         {\r
441                                                 btTransform localTransform;\r
442                                                 localTransform.deSerializeFloat(compoundData->m_childShapePtr[i].m_transform);\r
443                                                 compoundShape->addChildShape(localTransform,childShape);\r
444                                         } else\r
445                                         {\r
446 #ifdef _DEBUG\r
447                                                 printf("error: couldn't create childShape for compoundShape\n");\r
448 #endif\r
449                                         }\r
450                                         \r
451                                 }\r
452                                 shape = compoundShape;\r
453 \r
454                                 break;\r
455                         }\r
456                 case SOFTBODY_SHAPE_PROXYTYPE:\r
457                         {\r
458                                 return 0;\r
459                         }\r
460                 default:\r
461                         {\r
462 #ifdef _DEBUG\r
463                                 printf("unsupported shape type (%d)\n",shapeData->m_shapeType);\r
464 #endif\r
465                         }\r
466                 }\r
467 \r
468                 return shape;\r
469         \r
470 }\r
471 \r
472 \r
473 \r
474 char* btWorldImporter::duplicateName(const char* name)\r
475 {\r
476         if (name)\r
477         {\r
478                 int l = (int)strlen(name);\r
479                 char* newName = new char[l+1];\r
480                 memcpy(newName,name,l);\r
481                 newName[l] = 0;\r
482                 m_allocatedNames.push_back(newName);\r
483                 return newName;\r
484         }\r
485         return 0;\r
486 }\r
487 \r
488 \r
489 \r
490 void btWorldImporter::convertConstraint(btTypedConstraintData* constraintData,btRigidBody* rbA, btRigidBody* rbB ,bool isDoublePrecisionData, int fileVersion)\r
491 {\r
492         btTypedConstraint* constraint = 0;\r
493 \r
494                 switch (constraintData->m_objectType)\r
495                 {\r
496                 case POINT2POINT_CONSTRAINT_TYPE:\r
497                         {\r
498                                 if (isDoublePrecisionData)\r
499                                 {\r
500                                         btPoint2PointConstraintDoubleData* p2pData = (btPoint2PointConstraintDoubleData*)constraintData;\r
501                                         if (rbA && rbB)\r
502                                         {                                       \r
503                                                 btVector3 pivotInA,pivotInB;\r
504                                                 pivotInA.deSerializeDouble(p2pData->m_pivotInA);\r
505                                                 pivotInB.deSerializeDouble(p2pData->m_pivotInB);\r
506                                                 constraint = createPoint2PointConstraint(*rbA,*rbB,pivotInA,pivotInB);\r
507                                         } else\r
508                                         {\r
509                                                 btVector3 pivotInA;\r
510                                                 pivotInA.deSerializeDouble(p2pData->m_pivotInA);\r
511                                                 constraint = createPoint2PointConstraint(*rbA,pivotInA);\r
512                                         }\r
513                                 } else\r
514                                 {\r
515                                         btPoint2PointConstraintFloatData* p2pData = (btPoint2PointConstraintFloatData*)constraintData;\r
516                                         if (rbA&& rbB)\r
517                                         {                                       \r
518                                                 btVector3 pivotInA,pivotInB;\r
519                                                 pivotInA.deSerializeFloat(p2pData->m_pivotInA);\r
520                                                 pivotInB.deSerializeFloat(p2pData->m_pivotInB);\r
521                                                 constraint = createPoint2PointConstraint(*rbA,*rbB,pivotInA,pivotInB);\r
522                                         \r
523                                         } else\r
524                                         {\r
525                                                 btVector3 pivotInA;\r
526                                                 pivotInA.deSerializeFloat(p2pData->m_pivotInA);\r
527                                                 constraint = createPoint2PointConstraint(*rbA,pivotInA);\r
528                                         }\r
529 \r
530                                 }\r
531 \r
532                                 break;\r
533                         }\r
534                 case HINGE_CONSTRAINT_TYPE:\r
535                         {\r
536                                 btHingeConstraint* hinge = 0;\r
537 \r
538                                 if (isDoublePrecisionData)\r
539                                 {\r
540                                         btHingeConstraintDoubleData* hingeData = (btHingeConstraintDoubleData*)constraintData;\r
541                                         if (rbA&& rbB)\r
542                                         {\r
543                                                 btTransform rbAFrame,rbBFrame;\r
544                                                 rbAFrame.deSerializeDouble(hingeData->m_rbAFrame);\r
545                                                 rbBFrame.deSerializeDouble(hingeData->m_rbBFrame);\r
546                                                 hinge = createHingeConstraint(*rbA,*rbB,rbAFrame,rbBFrame,hingeData->m_useReferenceFrameA!=0);\r
547                                         } else\r
548                                         {\r
549                                                 btTransform rbAFrame;\r
550                                                 rbAFrame.deSerializeDouble(hingeData->m_rbAFrame);\r
551                                                 hinge = createHingeConstraint(*rbA,rbAFrame,hingeData->m_useReferenceFrameA!=0);\r
552                                         }\r
553                                         if (hingeData->m_enableAngularMotor)\r
554                                         {\r
555                                                 hinge->enableAngularMotor(true,hingeData->m_motorTargetVelocity,hingeData->m_maxMotorImpulse);\r
556                                         }\r
557                                         hinge->setAngularOnly(hingeData->m_angularOnly!=0);\r
558                                         hinge->setLimit(btScalar(hingeData->m_lowerLimit),btScalar(hingeData->m_upperLimit),btScalar(hingeData->m_limitSoftness),btScalar(hingeData->m_biasFactor),btScalar(hingeData->m_relaxationFactor));\r
559                                 } else\r
560                                 {\r
561                                         btHingeConstraintFloatData* hingeData = (btHingeConstraintFloatData*)constraintData;\r
562                                         if (rbA&& rbB)\r
563                                         {\r
564                                                 btTransform rbAFrame,rbBFrame;\r
565                                                 rbAFrame.deSerializeFloat(hingeData->m_rbAFrame);\r
566                                                 rbBFrame.deSerializeFloat(hingeData->m_rbBFrame);\r
567                                                 hinge = createHingeConstraint(*rbA,*rbB,rbAFrame,rbBFrame,hingeData->m_useReferenceFrameA!=0);\r
568                                         } else\r
569                                         {\r
570                                                 btTransform rbAFrame;\r
571                                                 rbAFrame.deSerializeFloat(hingeData->m_rbAFrame);\r
572                                                 hinge = createHingeConstraint(*rbA,rbAFrame,hingeData->m_useReferenceFrameA!=0);\r
573                                         }\r
574                                         if (hingeData->m_enableAngularMotor)\r
575                                         {\r
576                                                 hinge->enableAngularMotor(true,hingeData->m_motorTargetVelocity,hingeData->m_maxMotorImpulse);\r
577                                         }\r
578                                         hinge->setAngularOnly(hingeData->m_angularOnly!=0);\r
579                                         hinge->setLimit(btScalar(hingeData->m_lowerLimit),btScalar(hingeData->m_upperLimit),btScalar(hingeData->m_limitSoftness),btScalar(hingeData->m_biasFactor),btScalar(hingeData->m_relaxationFactor));\r
580                                 }\r
581 \r
582                                 constraint = hinge;\r
583                                 break;\r
584 \r
585                         }\r
586                 case CONETWIST_CONSTRAINT_TYPE:\r
587                         {\r
588                                 btConeTwistConstraintData* coneData = (btConeTwistConstraintData*)constraintData;\r
589                                 btConeTwistConstraint* coneTwist = 0;\r
590                                 \r
591                                 if (rbA&& rbB)\r
592                                 {\r
593                                         btTransform rbAFrame,rbBFrame;\r
594                                         rbAFrame.deSerializeFloat(coneData->m_rbAFrame);\r
595                                         rbBFrame.deSerializeFloat(coneData->m_rbBFrame);\r
596                                         coneTwist = createConeTwistConstraint(*rbA,*rbB,rbAFrame,rbBFrame);\r
597                                 } else\r
598                                 {\r
599                                         btTransform rbAFrame;\r
600                                         rbAFrame.deSerializeFloat(coneData->m_rbAFrame);\r
601                                         coneTwist = createConeTwistConstraint(*rbA,rbAFrame);\r
602                                 }\r
603                                 coneTwist->setLimit(coneData->m_swingSpan1,coneData->m_swingSpan2,coneData->m_twistSpan,coneData->m_limitSoftness,coneData->m_biasFactor,coneData->m_relaxationFactor);\r
604                                 coneTwist->setDamping(coneData->m_damping);\r
605                                 \r
606                                 constraint = coneTwist;\r
607                                 break;\r
608                         }\r
609 \r
610                 case D6_SPRING_CONSTRAINT_TYPE:\r
611                         {\r
612                                 \r
613                                 btGeneric6DofSpringConstraintData* dofData = (btGeneric6DofSpringConstraintData*)constraintData;\r
614                         //      int sz = sizeof(btGeneric6DofSpringConstraintData);\r
615                                 btGeneric6DofSpringConstraint* dof = 0;\r
616 \r
617                                 if (rbA && rbB)\r
618                                 {\r
619                                         btTransform rbAFrame,rbBFrame;\r
620                                         rbAFrame.deSerializeFloat(dofData->m_6dofData.m_rbAFrame);\r
621                                         rbBFrame.deSerializeFloat(dofData->m_6dofData.m_rbBFrame);\r
622                                         dof = createGeneric6DofSpringConstraint(*rbA,*rbB,rbAFrame,rbBFrame,dofData->m_6dofData.m_useLinearReferenceFrameA!=0);\r
623                                 } else\r
624                                 {\r
625                                         printf("Error in btWorldImporter::createGeneric6DofSpringConstraint: requires rbA && rbB\n");\r
626                                 }\r
627 \r
628                                 if (dof)\r
629                                 {\r
630                                         btVector3 angLowerLimit,angUpperLimit, linLowerLimit,linUpperlimit;\r
631                                         angLowerLimit.deSerializeFloat(dofData->m_6dofData.m_angularLowerLimit);\r
632                                         angUpperLimit.deSerializeFloat(dofData->m_6dofData.m_angularUpperLimit);\r
633                                         linLowerLimit.deSerializeFloat(dofData->m_6dofData.m_linearLowerLimit);\r
634                                         linUpperlimit.deSerializeFloat(dofData->m_6dofData.m_linearUpperLimit);\r
635                                         \r
636                                         angLowerLimit.setW(0.f);\r
637                                         dof->setAngularLowerLimit(angLowerLimit);\r
638                                         dof->setAngularUpperLimit(angUpperLimit);\r
639                                         dof->setLinearLowerLimit(linLowerLimit);\r
640                                         dof->setLinearUpperLimit(linUpperlimit);\r
641 \r
642                                         int i;\r
643                                         if (fileVersion>280)\r
644                                         {\r
645                                                 for (i=0;i<6;i++)\r
646                                                 {\r
647                                                         dof->setStiffness(i,dofData->m_springStiffness[i]);\r
648                                                         dof->setEquilibriumPoint(i,dofData->m_equilibriumPoint[i]);\r
649                                                         dof->enableSpring(i,dofData->m_springEnabled[i]!=0);\r
650                                                         dof->setDamping(i,dofData->m_springDamping[i]);\r
651                                                 }\r
652                                         }\r
653                                 }\r
654 \r
655                                 constraint = dof;\r
656                                 break;\r
657                         }\r
658                 case D6_CONSTRAINT_TYPE:\r
659                         {\r
660                                 btGeneric6DofConstraintData* dofData = (btGeneric6DofConstraintData*)constraintData;\r
661                                 btGeneric6DofConstraint* dof = 0;\r
662 \r
663                                 if (rbA&& rbB)\r
664                                 {\r
665                                         btTransform rbAFrame,rbBFrame;\r
666                                         rbAFrame.deSerializeFloat(dofData->m_rbAFrame);\r
667                                         rbBFrame.deSerializeFloat(dofData->m_rbBFrame);\r
668                                         dof = createGeneric6DofConstraint(*rbA,*rbB,rbAFrame,rbBFrame,dofData->m_useLinearReferenceFrameA!=0);\r
669                                 } else\r
670                                 {\r
671                                         if (rbB)\r
672                                         {\r
673                                                 btTransform rbBFrame;\r
674                                                 rbBFrame.deSerializeFloat(dofData->m_rbBFrame);\r
675                                                 dof = createGeneric6DofConstraint(*rbB,rbBFrame,dofData->m_useLinearReferenceFrameA!=0);\r
676                                         } else\r
677                                         {\r
678                                                 printf("Error in btWorldImporter::createGeneric6DofConstraint: missing rbB\n");\r
679                                         }\r
680                                 }\r
681 \r
682                                 if (dof)\r
683                                 {\r
684                                         btVector3 angLowerLimit,angUpperLimit, linLowerLimit,linUpperlimit;\r
685                                         angLowerLimit.deSerializeFloat(dofData->m_angularLowerLimit);\r
686                                         angUpperLimit.deSerializeFloat(dofData->m_angularUpperLimit);\r
687                                         linLowerLimit.deSerializeFloat(dofData->m_linearLowerLimit);\r
688                                         linUpperlimit.deSerializeFloat(dofData->m_linearUpperLimit);\r
689                                         \r
690                                         dof->setAngularLowerLimit(angLowerLimit);\r
691                                         dof->setAngularUpperLimit(angUpperLimit);\r
692                                         dof->setLinearLowerLimit(linLowerLimit);\r
693                                         dof->setLinearUpperLimit(linUpperlimit);\r
694                                 }\r
695 \r
696                                 constraint = dof;\r
697                                 break;\r
698                         }\r
699                 case SLIDER_CONSTRAINT_TYPE:\r
700                         {\r
701                                 btSliderConstraintData* sliderData = (btSliderConstraintData*)constraintData;\r
702                                 btSliderConstraint* slider = 0;\r
703                                 if (rbA&& rbB)\r
704                                 {\r
705                                         btTransform rbAFrame,rbBFrame;\r
706                                         rbAFrame.deSerializeFloat(sliderData->m_rbAFrame);\r
707                                         rbBFrame.deSerializeFloat(sliderData->m_rbBFrame);\r
708                                         slider = createSliderConstraint(*rbA,*rbB,rbAFrame,rbBFrame,sliderData->m_useLinearReferenceFrameA!=0);\r
709                                 } else\r
710                                 {\r
711                                         btTransform rbBFrame;\r
712                                         rbBFrame.deSerializeFloat(sliderData->m_rbBFrame);\r
713                                         slider = createSliderConstraint(*rbB,rbBFrame,sliderData->m_useLinearReferenceFrameA!=0);\r
714                                 }\r
715                                 slider->setLowerLinLimit(sliderData->m_linearLowerLimit);\r
716                                 slider->setUpperLinLimit(sliderData->m_linearUpperLimit);\r
717                                 slider->setLowerAngLimit(sliderData->m_angularLowerLimit);\r
718                                 slider->setUpperAngLimit(sliderData->m_angularUpperLimit);\r
719                                 slider->setUseFrameOffset(sliderData->m_useOffsetForConstraintFrame!=0);\r
720                                 constraint = slider;\r
721                                 break;\r
722                         }\r
723                 \r
724                 default:\r
725                         {\r
726                                 printf("unknown constraint type\n");\r
727                         }\r
728                 };\r
729 \r
730                 if (constraint)\r
731                 {\r
732                         constraint->setDbgDrawSize(constraintData->m_dbgDrawSize);\r
733                         ///those fields didn't exist and set to zero for pre-280 versions, so do a check here\r
734                         if (fileVersion>=280)\r
735                         {\r
736                                 constraint->setBreakingImpulseThreshold(constraintData->m_breakingImpulseThreshold);\r
737                                 constraint->setEnabled(constraintData->m_isEnabled!=0);\r
738                                 constraint->setOverrideNumSolverIterations(constraintData->m_overrideNumSolverIterations);\r
739                         }\r
740 \r
741                         if (constraintData->m_name)\r
742                         {\r
743                                 char* newname = duplicateName(constraintData->m_name);\r
744                                 m_nameConstraintMap.insert(newname,constraint);\r
745                                 m_objectNameMap.insert(constraint,newname);\r
746                         }\r
747                         if(m_dynamicsWorld)\r
748                                 m_dynamicsWorld->addConstraint(constraint,constraintData->m_disableCollisionsBetweenLinkedBodies!=0);\r
749                 }\r
750                 \r
751 \r
752 }\r
753 \r
754 \r
755 \r
756 \r
757 \r
758 \r
759 \r
760 \r
761 \r
762 \r
763 \r
764 btTriangleIndexVertexArray* btWorldImporter::createMeshInterface(btStridingMeshInterfaceData&  meshData)\r
765 {\r
766         btTriangleIndexVertexArray* meshInterface = createTriangleMeshContainer();\r
767 \r
768         for (int i=0;i<meshData.m_numMeshParts;i++)\r
769         {\r
770                 btIndexedMesh meshPart;\r
771                 meshPart.m_numTriangles = meshData.m_meshPartsPtr[i].m_numTriangles;\r
772                 meshPart.m_numVertices = meshData.m_meshPartsPtr[i].m_numVertices;\r
773                 \r
774 \r
775                 if (meshData.m_meshPartsPtr[i].m_indices32)\r
776                 {\r
777                         meshPart.m_indexType = PHY_INTEGER;\r
778                         meshPart.m_triangleIndexStride = 3*sizeof(int);\r
779                         int* indexArray = (int*)btAlignedAlloc(sizeof(int)*3*meshPart.m_numTriangles,16);\r
780                         m_indexArrays.push_back(indexArray);\r
781                         for (int j=0;j<3*meshPart.m_numTriangles;j++)\r
782                         {\r
783                                 indexArray[j] = meshData.m_meshPartsPtr[i].m_indices32[j].m_value;\r
784                         }\r
785                         meshPart.m_triangleIndexBase = (const unsigned char*)indexArray;\r
786                 } else\r
787                 {\r
788                         if (meshData.m_meshPartsPtr[i].m_3indices16)\r
789                         {\r
790                                 meshPart.m_indexType = PHY_SHORT;\r
791                                 meshPart.m_triangleIndexStride = sizeof(short int)*3;//sizeof(btShortIntIndexTripletData);\r
792 \r
793                                 short int* indexArray = (short int*)btAlignedAlloc(sizeof(short int)*3*meshPart.m_numTriangles,16);\r
794                                 m_shortIndexArrays.push_back(indexArray);\r
795 \r
796                                 for (int j=0;j<meshPart.m_numTriangles;j++)\r
797                                 {\r
798                                         indexArray[3*j] = meshData.m_meshPartsPtr[i].m_3indices16[j].m_values[0];\r
799                                         indexArray[3*j+1] = meshData.m_meshPartsPtr[i].m_3indices16[j].m_values[1];\r
800                                         indexArray[3*j+2] = meshData.m_meshPartsPtr[i].m_3indices16[j].m_values[2];\r
801                                 }\r
802 \r
803                                 meshPart.m_triangleIndexBase = (const unsigned char*)indexArray;\r
804                         }\r
805                         if (meshData.m_meshPartsPtr[i].m_indices16)\r
806                         {\r
807                                 meshPart.m_indexType = PHY_SHORT;\r
808                                 meshPart.m_triangleIndexStride = 3*sizeof(short int);\r
809                                 short int* indexArray = (short int*)btAlignedAlloc(sizeof(short int)*3*meshPart.m_numTriangles,16);\r
810                                 m_shortIndexArrays.push_back(indexArray);\r
811                                 for (int j=0;j<3*meshPart.m_numTriangles;j++)\r
812                                 {\r
813                                         indexArray[j] = meshData.m_meshPartsPtr[i].m_indices16[j].m_value;\r
814                                 }\r
815 \r
816                                 meshPart.m_triangleIndexBase = (const unsigned char*)indexArray;\r
817                         }\r
818 \r
819                         if (meshData.m_meshPartsPtr[i].m_3indices8)\r
820                         {\r
821                                 meshPart.m_indexType = PHY_UCHAR;\r
822                                 meshPart.m_triangleIndexStride = sizeof(unsigned char)*3;\r
823 \r
824                                 unsigned char* indexArray = (unsigned char*)btAlignedAlloc(sizeof(unsigned char)*3*meshPart.m_numTriangles,16);\r
825                                 m_charIndexArrays.push_back(indexArray);\r
826 \r
827                                 for (int j=0;j<meshPart.m_numTriangles;j++)\r
828                                 {\r
829                                         indexArray[3*j] = meshData.m_meshPartsPtr[i].m_3indices8[j].m_values[0];\r
830                                         indexArray[3*j+1] = meshData.m_meshPartsPtr[i].m_3indices8[j].m_values[1];\r
831                                         indexArray[3*j+2] = meshData.m_meshPartsPtr[i].m_3indices8[j].m_values[2];\r
832                                 }\r
833 \r
834                                 meshPart.m_triangleIndexBase = (const unsigned char*)indexArray;\r
835                         }\r
836                 }\r
837 \r
838                 if (meshData.m_meshPartsPtr[i].m_vertices3f)\r
839                 {\r
840                         meshPart.m_vertexType = PHY_FLOAT;\r
841                         meshPart.m_vertexStride = sizeof(btVector3FloatData);\r
842                         btVector3FloatData* vertices = (btVector3FloatData*) btAlignedAlloc(sizeof(btVector3FloatData)*meshPart.m_numVertices,16);\r
843                         m_floatVertexArrays.push_back(vertices);\r
844 \r
845                         for (int j=0;j<meshPart.m_numVertices;j++)\r
846                         {\r
847                                 vertices[j].m_floats[0] = meshData.m_meshPartsPtr[i].m_vertices3f[j].m_floats[0];\r
848                                 vertices[j].m_floats[1] = meshData.m_meshPartsPtr[i].m_vertices3f[j].m_floats[1];\r
849                                 vertices[j].m_floats[2] = meshData.m_meshPartsPtr[i].m_vertices3f[j].m_floats[2];\r
850                                 vertices[j].m_floats[3] = meshData.m_meshPartsPtr[i].m_vertices3f[j].m_floats[3];\r
851                         }\r
852                         meshPart.m_vertexBase = (const unsigned char*)vertices;\r
853                 } else\r
854                 {\r
855                         meshPart.m_vertexType = PHY_DOUBLE;\r
856                         meshPart.m_vertexStride = sizeof(btVector3DoubleData);\r
857 \r
858 \r
859                         btVector3DoubleData* vertices = (btVector3DoubleData*) btAlignedAlloc(sizeof(btVector3DoubleData)*meshPart.m_numVertices,16);\r
860                         m_doubleVertexArrays.push_back(vertices);\r
861 \r
862                         for (int j=0;j<meshPart.m_numVertices;j++)\r
863                         {\r
864                                 vertices[j].m_floats[0] = meshData.m_meshPartsPtr[i].m_vertices3d[j].m_floats[0];\r
865                                 vertices[j].m_floats[1] = meshData.m_meshPartsPtr[i].m_vertices3d[j].m_floats[1];\r
866                                 vertices[j].m_floats[2] = meshData.m_meshPartsPtr[i].m_vertices3d[j].m_floats[2];\r
867                                 vertices[j].m_floats[3] = meshData.m_meshPartsPtr[i].m_vertices3d[j].m_floats[3];\r
868                         }\r
869                         meshPart.m_vertexBase = (const unsigned char*)vertices;\r
870                 }\r
871                 \r
872                 if (meshPart.m_triangleIndexBase && meshPart.m_vertexBase)\r
873                 {\r
874                         meshInterface->addIndexedMesh(meshPart,meshPart.m_indexType);\r
875                 }\r
876         }\r
877 \r
878         return meshInterface;\r
879 }\r
880 \r
881 \r
882 btStridingMeshInterfaceData* btWorldImporter::createStridingMeshInterfaceData(btStridingMeshInterfaceData* interfaceData)\r
883 {\r
884         //create a new btStridingMeshInterfaceData that is an exact copy of shapedata and store it in the WorldImporter\r
885         btStridingMeshInterfaceData* newData = new btStridingMeshInterfaceData;\r
886 \r
887         newData->m_scaling = interfaceData->m_scaling;\r
888         newData->m_numMeshParts = interfaceData->m_numMeshParts;\r
889         newData->m_meshPartsPtr = new btMeshPartData[newData->m_numMeshParts];\r
890 \r
891         for(int i = 0;i < newData->m_numMeshParts;i++)\r
892         {\r
893                 btMeshPartData* curPart = &interfaceData->m_meshPartsPtr[i];\r
894                 btMeshPartData* curNewPart = &newData->m_meshPartsPtr[i];\r
895 \r
896                 curNewPart->m_numTriangles = curPart->m_numTriangles;\r
897                 curNewPart->m_numVertices = curPart->m_numVertices;\r
898                 \r
899                 if(curPart->m_vertices3f)\r
900                 {\r
901                         curNewPart->m_vertices3f = new btVector3FloatData[curNewPart->m_numVertices];\r
902                         memcpy(curNewPart->m_vertices3f,curPart->m_vertices3f,sizeof(btVector3FloatData) * curNewPart->m_numVertices);\r
903                 }\r
904                 else\r
905                         curNewPart->m_vertices3f = NULL;\r
906 \r
907                 if(curPart->m_vertices3d)\r
908                 {\r
909                         curNewPart->m_vertices3d = new btVector3DoubleData[curNewPart->m_numVertices];\r
910                         memcpy(curNewPart->m_vertices3d,curPart->m_vertices3d,sizeof(btVector3DoubleData) * curNewPart->m_numVertices);\r
911                 }\r
912                 else\r
913                         curNewPart->m_vertices3d = NULL;\r
914 \r
915                 int numIndices = curNewPart->m_numTriangles * 3;\r
916                 ///the m_3indices8 was not initialized in some Bullet versions, this can cause crashes at loading time\r
917                 ///we catch it by only dealing with m_3indices8 if none of the other indices are initialized\r
918                 bool uninitialized3indices8Workaround =false;\r
919 \r
920                 if(curPart->m_indices32)\r
921                 {\r
922                         uninitialized3indices8Workaround=true;\r
923                         curNewPart->m_indices32 = new btIntIndexData[numIndices];\r
924                         memcpy(curNewPart->m_indices32,curPart->m_indices32,sizeof(btIntIndexData) * numIndices);\r
925                 }\r
926                 else\r
927                         curNewPart->m_indices32 = NULL;\r
928 \r
929                 if(curPart->m_3indices16)\r
930                 {\r
931                         uninitialized3indices8Workaround=true;\r
932                         curNewPart->m_3indices16 = new btShortIntIndexTripletData[curNewPart->m_numTriangles];\r
933                         memcpy(curNewPart->m_3indices16,curPart->m_3indices16,sizeof(btShortIntIndexTripletData) * curNewPart->m_numTriangles);\r
934                 }\r
935                 else\r
936                         curNewPart->m_3indices16 = NULL;\r
937 \r
938                 if(curPart->m_indices16)\r
939                 {\r
940                         uninitialized3indices8Workaround=true;\r
941                         curNewPart->m_indices16 = new btShortIntIndexData[numIndices];\r
942                         memcpy(curNewPart->m_indices16,curPart->m_indices16,sizeof(btShortIntIndexData) * numIndices);\r
943                 }\r
944                 else\r
945                         curNewPart->m_indices16 = NULL;\r
946 \r
947                 if(!uninitialized3indices8Workaround && curPart->m_3indices8)\r
948                 {\r
949                         curNewPart->m_3indices8 = new btCharIndexTripletData[curNewPart->m_numTriangles];\r
950                         memcpy(curNewPart->m_3indices8,curPart->m_3indices8,sizeof(btCharIndexTripletData) * curNewPart->m_numTriangles);\r
951                 }\r
952                 else\r
953                         curNewPart->m_3indices8 = NULL;\r
954 \r
955         }\r
956 \r
957         m_allocatedbtStridingMeshInterfaceDatas.push_back(newData);\r
958 \r
959         return(newData);\r
960 }\r
961 \r
962 #ifdef USE_INTERNAL_EDGE_UTILITY\r
963 extern ContactAddedCallback             gContactAddedCallback;\r
964 \r
965 static bool btAdjustInternalEdgeContactsCallback(btManifoldPoint& cp,   const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1)\r
966 {\r
967 \r
968         btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1);\r
969                 //btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_BACKFACE_MODE);\r
970                 //btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_DOUBLE_SIDED+BT_TRIANGLE_CONCAVE_DOUBLE_SIDED);\r
971         return true;\r
972 }\r
973 #endif //USE_INTERNAL_EDGE_UTILITY\r
974 \r
975 \r
976 \r
977 \r
978 btCollisionObject* btWorldImporter::createCollisionObject(const btTransform& startTransform,btCollisionShape* shape, const char* bodyName)\r
979 {\r
980         return createRigidBody(false,0,startTransform,shape,bodyName);\r
981 }\r
982 \r
983 void    btWorldImporter::setDynamicsWorldInfo(const btVector3& gravity, const btContactSolverInfo& solverInfo)\r
984 {\r
985         if (m_dynamicsWorld)\r
986         {\r
987                 m_dynamicsWorld->setGravity(gravity);\r
988                 m_dynamicsWorld->getSolverInfo() = solverInfo;\r
989         }\r
990 \r
991 }\r
992 \r
993 btRigidBody*  btWorldImporter::createRigidBody(bool isDynamic, btScalar mass, const btTransform& startTransform,btCollisionShape* shape,const char* bodyName)\r
994 {\r
995         btVector3 localInertia;\r
996         localInertia.setZero();\r
997 \r
998         if (mass)\r
999                 shape->calculateLocalInertia(mass,localInertia);\r
1000         \r
1001         btRigidBody* body = new btRigidBody(mass,0,shape,localInertia); \r
1002         body->setWorldTransform(startTransform);\r
1003 \r
1004         if (m_dynamicsWorld)\r
1005                 m_dynamicsWorld->addRigidBody(body);\r
1006         \r
1007         if (bodyName)\r
1008         {\r
1009                 char* newname = duplicateName(bodyName);\r
1010                 m_objectNameMap.insert(body,newname);\r
1011                 m_nameBodyMap.insert(newname,body);\r
1012         }\r
1013         m_allocatedRigidBodies.push_back(body);\r
1014         return body;\r
1015 \r
1016 }\r
1017 \r
1018 btCollisionShape* btWorldImporter::createPlaneShape(const btVector3& planeNormal,btScalar planeConstant)\r
1019 {\r
1020         btStaticPlaneShape* shape = new btStaticPlaneShape(planeNormal,planeConstant);\r
1021         m_allocatedCollisionShapes.push_back(shape);\r
1022         return shape;\r
1023 }\r
1024 btCollisionShape* btWorldImporter::createBoxShape(const btVector3& halfExtents)\r
1025 {\r
1026         btBoxShape* shape = new btBoxShape(halfExtents);\r
1027         m_allocatedCollisionShapes.push_back(shape);\r
1028         return shape;\r
1029 }\r
1030 btCollisionShape* btWorldImporter::createSphereShape(btScalar radius)\r
1031 {\r
1032         btSphereShape* shape = new btSphereShape(radius);\r
1033         m_allocatedCollisionShapes.push_back(shape);\r
1034         return shape;\r
1035 }\r
1036 \r
1037 \r
1038 btCollisionShape* btWorldImporter::createCapsuleShapeX(btScalar radius, btScalar height)\r
1039 {\r
1040         btCapsuleShapeX* shape = new btCapsuleShapeX(radius,height);\r
1041         m_allocatedCollisionShapes.push_back(shape);\r
1042         return shape;\r
1043 }\r
1044 \r
1045 btCollisionShape* btWorldImporter::createCapsuleShapeY(btScalar radius, btScalar height)\r
1046 {\r
1047         btCapsuleShape* shape = new btCapsuleShape(radius,height);\r
1048         m_allocatedCollisionShapes.push_back(shape);\r
1049         return shape;\r
1050 }\r
1051 \r
1052 btCollisionShape* btWorldImporter::createCapsuleShapeZ(btScalar radius, btScalar height)\r
1053 {\r
1054         btCapsuleShapeZ* shape = new btCapsuleShapeZ(radius,height);\r
1055         m_allocatedCollisionShapes.push_back(shape);\r
1056         return shape;\r
1057 }\r
1058 \r
1059 btCollisionShape* btWorldImporter::createCylinderShapeX(btScalar radius,btScalar height)\r
1060 {\r
1061         btCylinderShapeX* shape = new btCylinderShapeX(btVector3(height,radius,radius));\r
1062         m_allocatedCollisionShapes.push_back(shape);\r
1063         return shape;\r
1064 }\r
1065 \r
1066 btCollisionShape* btWorldImporter::createCylinderShapeY(btScalar radius,btScalar height)\r
1067 {\r
1068         btCylinderShape* shape = new btCylinderShape(btVector3(radius,height,radius));\r
1069         m_allocatedCollisionShapes.push_back(shape);\r
1070         return shape;\r
1071 }\r
1072 \r
1073 btCollisionShape* btWorldImporter::createCylinderShapeZ(btScalar radius,btScalar height)\r
1074 {\r
1075         btCylinderShapeZ* shape = new btCylinderShapeZ(btVector3(radius,radius,height));\r
1076         m_allocatedCollisionShapes.push_back(shape);\r
1077         return shape;\r
1078 }\r
1079 \r
1080 btTriangleIndexVertexArray*     btWorldImporter::createTriangleMeshContainer()\r
1081 {\r
1082         btTriangleIndexVertexArray* in = new btTriangleIndexVertexArray();\r
1083         m_allocatedTriangleIndexArrays.push_back(in);\r
1084         return in;\r
1085 }\r
1086 \r
1087 btOptimizedBvh* btWorldImporter::createOptimizedBvh()\r
1088 {\r
1089         btOptimizedBvh* bvh = new btOptimizedBvh();\r
1090         m_allocatedBvhs.push_back(bvh);\r
1091         return bvh;\r
1092 }\r
1093 \r
1094 \r
1095 btTriangleInfoMap* btWorldImporter::createTriangleInfoMap()\r
1096 {\r
1097         btTriangleInfoMap* tim = new btTriangleInfoMap();\r
1098         m_allocatedTriangleInfoMaps.push_back(tim);\r
1099         return tim;\r
1100 }\r
1101 \r
1102 btBvhTriangleMeshShape* btWorldImporter::createBvhTriangleMeshShape(btStridingMeshInterface* trimesh, btOptimizedBvh* bvh)\r
1103 {\r
1104         if (bvh)\r
1105         {\r
1106                 btBvhTriangleMeshShape* bvhTriMesh = new btBvhTriangleMeshShape(trimesh,bvh->isQuantized(), false);\r
1107                 bvhTriMesh->setOptimizedBvh(bvh);\r
1108                 m_allocatedCollisionShapes.push_back(bvhTriMesh);\r
1109                 return bvhTriMesh;\r
1110         }\r
1111 \r
1112         btBvhTriangleMeshShape* ts = new btBvhTriangleMeshShape(trimesh,true);\r
1113         m_allocatedCollisionShapes.push_back(ts);\r
1114         return ts;\r
1115 \r
1116 }\r
1117 btCollisionShape* btWorldImporter::createConvexTriangleMeshShape(btStridingMeshInterface* trimesh)\r
1118 {\r
1119         return 0;\r
1120 }\r
1121 btGImpactMeshShape* btWorldImporter::createGimpactShape(btStridingMeshInterface* trimesh)\r
1122 {\r
1123         btGImpactMeshShape* shape = new btGImpactMeshShape(trimesh);\r
1124         m_allocatedCollisionShapes.push_back(shape);\r
1125         return shape;\r
1126         \r
1127 }\r
1128 btConvexHullShape* btWorldImporter::createConvexHullShape()\r
1129 {\r
1130         btConvexHullShape* shape = new btConvexHullShape();\r
1131         m_allocatedCollisionShapes.push_back(shape);\r
1132         return shape;\r
1133 }\r
1134 \r
1135 btCompoundShape* btWorldImporter::createCompoundShape()\r
1136 {\r
1137         btCompoundShape* shape = new btCompoundShape();\r
1138         m_allocatedCollisionShapes.push_back(shape);\r
1139         return shape;\r
1140 }\r
1141 \r
1142         \r
1143 btScaledBvhTriangleMeshShape* btWorldImporter::createScaledTrangleMeshShape(btBvhTriangleMeshShape* meshShape,const btVector3& localScaling)\r
1144 {\r
1145         btScaledBvhTriangleMeshShape* shape = new btScaledBvhTriangleMeshShape(meshShape,localScaling);\r
1146         m_allocatedCollisionShapes.push_back(shape);\r
1147         return shape;\r
1148 }\r
1149 \r
1150 btMultiSphereShape* btWorldImporter::createMultiSphereShape(const btVector3* positions,const btScalar* radi,int numSpheres)\r
1151 {\r
1152         btMultiSphereShape* shape = new btMultiSphereShape(positions, radi, numSpheres);\r
1153         m_allocatedCollisionShapes.push_back(shape);\r
1154         return shape;\r
1155 }\r
1156 \r
1157 btRigidBody& btWorldImporter::getFixedBody()\r
1158 {\r
1159         static btRigidBody s_fixed(0, 0,0);\r
1160         s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.)));\r
1161         return s_fixed;\r
1162 }\r
1163 \r
1164 btPoint2PointConstraint* btWorldImporter::createPoint2PointConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB)\r
1165 {\r
1166         btPoint2PointConstraint* p2p = new btPoint2PointConstraint(rbA,rbB,pivotInA,pivotInB);\r
1167         m_allocatedConstraints.push_back(p2p);\r
1168         return p2p;\r
1169 }\r
1170 \r
1171 btPoint2PointConstraint* btWorldImporter::createPoint2PointConstraint(btRigidBody& rbA,const btVector3& pivotInA)\r
1172 {\r
1173         btPoint2PointConstraint* p2p = new btPoint2PointConstraint(rbA,pivotInA);\r
1174         m_allocatedConstraints.push_back(p2p);\r
1175         return p2p;\r
1176 }\r
1177 \r
1178 \r
1179 btHingeConstraint* btWorldImporter::createHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA)\r
1180 {\r
1181         btHingeConstraint* hinge = new btHingeConstraint(rbA,rbB,rbAFrame,rbBFrame,useReferenceFrameA);\r
1182         m_allocatedConstraints.push_back(hinge);\r
1183         return hinge;\r
1184 }\r
1185 \r
1186 btHingeConstraint* btWorldImporter::createHingeConstraint(btRigidBody& rbA,const btTransform& rbAFrame, bool useReferenceFrameA)\r
1187 {\r
1188         btHingeConstraint* hinge = new btHingeConstraint(rbA,rbAFrame,useReferenceFrameA);\r
1189         m_allocatedConstraints.push_back(hinge);\r
1190         return hinge;\r
1191 }\r
1192 \r
1193 btConeTwistConstraint* btWorldImporter::createConeTwistConstraint(btRigidBody& rbA,btRigidBody& rbB,const btTransform& rbAFrame, const btTransform& rbBFrame)\r
1194 {\r
1195         btConeTwistConstraint* cone = new btConeTwistConstraint(rbA,rbB,rbAFrame,rbBFrame);\r
1196         m_allocatedConstraints.push_back(cone);\r
1197         return cone;\r
1198 }\r
1199 \r
1200 btConeTwistConstraint* btWorldImporter::createConeTwistConstraint(btRigidBody& rbA,const btTransform& rbAFrame)\r
1201 {\r
1202         btConeTwistConstraint* cone = new btConeTwistConstraint(rbA,rbAFrame);\r
1203         m_allocatedConstraints.push_back(cone);\r
1204         return cone;\r
1205 }\r
1206 \r
1207 \r
1208 btGeneric6DofConstraint* btWorldImporter::createGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA)\r
1209 {\r
1210         btGeneric6DofConstraint* dof = new btGeneric6DofConstraint(rbA,rbB,frameInA,frameInB,useLinearReferenceFrameA);\r
1211         m_allocatedConstraints.push_back(dof);\r
1212         return dof;\r
1213 }\r
1214 \r
1215 btGeneric6DofConstraint* btWorldImporter::createGeneric6DofConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB)\r
1216 {\r
1217         btGeneric6DofConstraint* dof =  new btGeneric6DofConstraint(rbB,frameInB,useLinearReferenceFrameB);\r
1218         m_allocatedConstraints.push_back(dof);\r
1219         return dof;\r
1220 }\r
1221 \r
1222 btGeneric6DofSpringConstraint* btWorldImporter::createGeneric6DofSpringConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA)\r
1223 {\r
1224         btGeneric6DofSpringConstraint* dof = new btGeneric6DofSpringConstraint(rbA,rbB,frameInA,frameInB,useLinearReferenceFrameA);\r
1225         m_allocatedConstraints.push_back(dof);\r
1226         return dof;\r
1227 }\r
1228 \r
1229 \r
1230 btSliderConstraint* btWorldImporter::createSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA)\r
1231 {\r
1232         btSliderConstraint* slider = new btSliderConstraint(rbA,rbB,frameInA,frameInB,useLinearReferenceFrameA);\r
1233         m_allocatedConstraints.push_back(slider);\r
1234         return slider;\r
1235 }\r
1236 \r
1237 btSliderConstraint* btWorldImporter::createSliderConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameA)\r
1238 {\r
1239         btSliderConstraint* slider = new btSliderConstraint(rbB,frameInB,useLinearReferenceFrameA);\r
1240         m_allocatedConstraints.push_back(slider);\r
1241         return slider;\r
1242 }\r
1243 \r
1244 \r
1245         // query for data\r
1246 int     btWorldImporter::getNumCollisionShapes() const\r
1247 {\r
1248         return m_allocatedCollisionShapes.size();\r
1249 }\r
1250 \r
1251 btCollisionShape* btWorldImporter::getCollisionShapeByIndex(int index)\r
1252 {\r
1253         return m_allocatedCollisionShapes[index];\r
1254 }\r
1255 \r
1256 btCollisionShape* btWorldImporter::getCollisionShapeByName(const char* name)\r
1257 {\r
1258         btCollisionShape** shapePtr = m_nameShapeMap.find(name);\r
1259         if (shapePtr&& *shapePtr)\r
1260         {\r
1261                 return *shapePtr;\r
1262         }\r
1263         return 0;\r
1264 }\r
1265 \r
1266 btRigidBody* btWorldImporter::getRigidBodyByName(const char* name)\r
1267 {\r
1268         btRigidBody** bodyPtr = m_nameBodyMap.find(name);\r
1269         if (bodyPtr && *bodyPtr)\r
1270         {\r
1271                 return *bodyPtr;\r
1272         }\r
1273         return 0;\r
1274 }\r
1275 \r
1276 btTypedConstraint* btWorldImporter::getConstraintByName(const char* name)\r
1277 {\r
1278         btTypedConstraint** constraintPtr = m_nameConstraintMap.find(name);\r
1279         if (constraintPtr && *constraintPtr)\r
1280         {\r
1281                 return *constraintPtr;\r
1282         }\r
1283         return 0;\r
1284 }\r
1285 \r
1286 const char*     btWorldImporter::getNameForPointer(const void* ptr) const\r
1287 {\r
1288         const char*const * namePtr = m_objectNameMap.find(ptr);\r
1289         if (namePtr && *namePtr)\r
1290                 return *namePtr;\r
1291         return 0;\r
1292 }\r
1293 \r
1294 \r
1295 int btWorldImporter::getNumRigidBodies() const\r
1296 {\r
1297         return m_allocatedRigidBodies.size();\r
1298 }\r
1299 \r
1300 btCollisionObject* btWorldImporter::getRigidBodyByIndex(int index) const\r
1301 {\r
1302         return m_allocatedRigidBodies[index];\r
1303 }\r
1304 int btWorldImporter::getNumConstraints() const\r
1305 {\r
1306         return m_allocatedConstraints.size();\r
1307 }\r
1308 \r
1309 btTypedConstraint* btWorldImporter::getConstraintByIndex(int index) const\r
1310 {\r
1311         return m_allocatedConstraints[index];\r
1312 }\r
1313 \r
1314 int btWorldImporter::getNumBvhs() const\r
1315 {\r
1316         return m_allocatedBvhs.size();\r
1317 }\r
1318  btOptimizedBvh* btWorldImporter::getBvhByIndex(int index) const\r
1319 {\r
1320         return m_allocatedBvhs[index];\r
1321 }\r
1322 \r
1323 int btWorldImporter::getNumTriangleInfoMaps() const\r
1324 {\r
1325         return m_allocatedTriangleInfoMaps.size();\r
1326 }\r
1327 \r
1328 btTriangleInfoMap* btWorldImporter::getTriangleInfoMapByIndex(int index) const\r
1329 {\r
1330         return m_allocatedTriangleInfoMaps[index];\r
1331 }\r
1332 \r
1333 \r
1334 void    btWorldImporter::convertRigidBodyFloat( btRigidBodyFloatData* colObjData)\r
1335 {\r
1336         btScalar mass = btScalar(colObjData->m_inverseMass? 1.f/colObjData->m_inverseMass : 0.f);\r
1337         btVector3 localInertia;\r
1338         localInertia.setZero();\r
1339         btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionObjectData.m_collisionShape);\r
1340         if (shapePtr && *shapePtr)\r
1341         {\r
1342                 btTransform startTransform;\r
1343                 colObjData->m_collisionObjectData.m_worldTransform.m_origin.m_floats[3] = 0.f;\r
1344                 startTransform.deSerializeFloat(colObjData->m_collisionObjectData.m_worldTransform);\r
1345                                 \r
1346         //      startTransform.setBasis(btMatrix3x3::getIdentity());\r
1347                 btCollisionShape* shape = (btCollisionShape*)*shapePtr;\r
1348                 if (shape->isNonMoving())\r
1349                 {\r
1350                         mass = 0.f;\r
1351                 }\r
1352                 if (mass)\r
1353                 {\r
1354                         shape->calculateLocalInertia(mass,localInertia);\r
1355                 }\r
1356                 bool isDynamic = mass!=0.f;\r
1357                 btRigidBody* body = createRigidBody(isDynamic,mass,startTransform,shape,colObjData->m_collisionObjectData.m_name);\r
1358                 body->setFriction(colObjData->m_collisionObjectData.m_friction);\r
1359                 body->setRestitution(colObjData->m_collisionObjectData.m_restitution);\r
1360                                 \r
1361 \r
1362 #ifdef USE_INTERNAL_EDGE_UTILITY\r
1363                 if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)\r
1364                 {\r
1365                         btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape;\r
1366                         if (trimesh->getTriangleInfoMap())\r
1367                         {\r
1368                                 body->setCollisionFlags(body->getCollisionFlags()  | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);\r
1369                         }\r
1370                 }\r
1371 #endif //USE_INTERNAL_EDGE_UTILITY\r
1372                 m_bodyMap.insert(colObjData,body);\r
1373         } else\r
1374         {\r
1375                 printf("error: no shape found\n");\r
1376         }\r
1377 }\r
1378 \r
1379 void    btWorldImporter::convertRigidBodyDouble( btRigidBodyDoubleData* colObjData)\r
1380 {\r
1381         btScalar mass = btScalar(colObjData->m_inverseMass? 1.f/colObjData->m_inverseMass : 0.f);\r
1382         btVector3 localInertia;\r
1383         localInertia.setZero();\r
1384         btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionObjectData.m_collisionShape);\r
1385         if (shapePtr && *shapePtr)\r
1386         {\r
1387                 btTransform startTransform;\r
1388                 colObjData->m_collisionObjectData.m_worldTransform.m_origin.m_floats[3] = 0.f;\r
1389                 startTransform.deSerializeDouble(colObjData->m_collisionObjectData.m_worldTransform);\r
1390                                 \r
1391         //      startTransform.setBasis(btMatrix3x3::getIdentity());\r
1392                 btCollisionShape* shape = (btCollisionShape*)*shapePtr;\r
1393                 if (shape->isNonMoving())\r
1394                 {\r
1395                         mass = 0.f;\r
1396                 }\r
1397                 if (mass)\r
1398                 {\r
1399                         shape->calculateLocalInertia(mass,localInertia);\r
1400                 }\r
1401                 bool isDynamic = mass!=0.f;\r
1402                 btRigidBody* body = createRigidBody(isDynamic,mass,startTransform,shape,colObjData->m_collisionObjectData.m_name);\r
1403                 body->setFriction(colObjData->m_collisionObjectData.m_friction);\r
1404                 body->setRestitution(colObjData->m_collisionObjectData.m_restitution);\r
1405                                 \r
1406 \r
1407 #ifdef USE_INTERNAL_EDGE_UTILITY\r
1408                 if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)\r
1409                 {\r
1410                         btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape;\r
1411                         if (trimesh->getTriangleInfoMap())\r
1412                         {\r
1413                                 body->setCollisionFlags(body->getCollisionFlags()  | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);\r
1414                         }\r
1415                 }\r
1416 #endif //USE_INTERNAL_EDGE_UTILITY\r
1417                 m_bodyMap.insert(colObjData,body);\r
1418         } else\r
1419         {\r
1420                 printf("error: no shape found\n");\r
1421         }\r
1422 }\r