Imported Upstream version 2.81
[platform/upstream/libbullet.git] / Extras / Serialize / BulletWorldImporter / btBulletWorldImporter.cpp
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2012 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
17 #include "btBulletWorldImporter.h"
18 #include "../BulletFileLoader/btBulletFile.h"
19
20 #include "btBulletDynamicsCommon.h"
21 #include "BulletCollision/Gimpact/btGImpactShape.h"
22
23
24
25 //#define USE_INTERNAL_EDGE_UTILITY
26 #ifdef USE_INTERNAL_EDGE_UTILITY
27 #include "BulletCollision/CollisionDispatch/btInternalEdgeUtility.h"
28 #endif //USE_INTERNAL_EDGE_UTILITY
29
30 btBulletWorldImporter::btBulletWorldImporter(btDynamicsWorld* world)
31         :btWorldImporter(world)
32 {
33 }
34
35 btBulletWorldImporter::~btBulletWorldImporter()
36 {
37 }
38
39
40 bool    btBulletWorldImporter::loadFile( const char* fileName)
41 {
42         bParse::btBulletFile* bulletFile2 = new bParse::btBulletFile(fileName);
43
44         bool result = loadFileFromMemory(bulletFile2);
45
46         delete bulletFile2;
47         
48         return result;
49
50 }
51
52
53
54 bool    btBulletWorldImporter::loadFileFromMemory( char* memoryBuffer, int len)
55 {
56         bParse::btBulletFile* bulletFile2 = new bParse::btBulletFile(memoryBuffer,len);
57
58         bool result = loadFileFromMemory(bulletFile2);
59
60         delete bulletFile2;
61
62         return result;
63 }
64
65
66
67
68 bool    btBulletWorldImporter::loadFileFromMemory(  bParse::btBulletFile* bulletFile2)
69 {
70         bool ok = (bulletFile2->getFlags()& bParse::FD_OK)!=0;
71         
72         if (ok)
73                 bulletFile2->parse(m_verboseMode);
74         else 
75                 return false;
76         
77         if (m_verboseMode & bParse::FD_VERBOSE_DUMP_CHUNKS)
78         {
79                 bulletFile2->dumpChunks(bulletFile2->getFileDNA());
80         }
81
82         return convertAllObjects(bulletFile2);
83
84 }
85
86 bool    btBulletWorldImporter::convertAllObjects(  bParse::btBulletFile* bulletFile2)
87 {
88
89         m_shapeMap.clear();
90         m_bodyMap.clear();
91
92         int i;
93         
94         for (i=0;i<bulletFile2->m_bvhs.size();i++)
95         {
96                 btOptimizedBvh* bvh = createOptimizedBvh();
97
98                 if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
99                 {
100                         btQuantizedBvhDoubleData* bvhData = (btQuantizedBvhDoubleData*)bulletFile2->m_bvhs[i];
101                         bvh->deSerializeDouble(*bvhData);
102                 } else
103                 {
104                         btQuantizedBvhFloatData* bvhData = (btQuantizedBvhFloatData*)bulletFile2->m_bvhs[i];
105                         bvh->deSerializeFloat(*bvhData);
106                 }
107                 m_bvhMap.insert(bulletFile2->m_bvhs[i],bvh);
108         }
109
110
111
112         
113
114         for (i=0;i<bulletFile2->m_collisionShapes.size();i++)
115         {
116                 btCollisionShapeData* shapeData = (btCollisionShapeData*)bulletFile2->m_collisionShapes[i];
117                 btCollisionShape* shape = convertCollisionShape(shapeData);
118                 if (shape)
119                 {
120         //              printf("shapeMap.insert(%x,%x)\n",shapeData,shape);
121                         m_shapeMap.insert(shapeData,shape);
122                 }
123
124                 if (shape&& shapeData->m_name)
125                 {
126                         char* newname = duplicateName(shapeData->m_name);
127                         m_objectNameMap.insert(shape,newname);
128                         m_nameShapeMap.insert(newname,shape);
129                 }
130         }
131
132         
133
134
135         
136         for (int i=0;i<bulletFile2->m_dynamicsWorldInfo.size();i++)
137         {
138                 if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
139                 {
140                         btDynamicsWorldDoubleData* solverInfoData = (btDynamicsWorldDoubleData*)bulletFile2->m_dynamicsWorldInfo[i];
141                         btContactSolverInfo solverInfo;
142
143                         btVector3 gravity;
144                         gravity.deSerializeDouble(solverInfoData->m_gravity);
145
146                         solverInfo.m_tau = btScalar(solverInfoData->m_solverInfo.m_tau);
147                         solverInfo.m_damping = btScalar(solverInfoData->m_solverInfo.m_damping);
148                         solverInfo.m_friction = btScalar(solverInfoData->m_solverInfo.m_friction);
149                         solverInfo.m_timeStep = btScalar(solverInfoData->m_solverInfo.m_timeStep);
150
151                         solverInfo.m_restitution = btScalar(solverInfoData->m_solverInfo.m_restitution);
152                         solverInfo.m_maxErrorReduction = btScalar(solverInfoData->m_solverInfo.m_maxErrorReduction);
153                         solverInfo.m_sor = btScalar(solverInfoData->m_solverInfo.m_sor);
154                         solverInfo.m_erp = btScalar(solverInfoData->m_solverInfo.m_erp);
155
156                         solverInfo.m_erp2 = btScalar(solverInfoData->m_solverInfo.m_erp2);
157                         solverInfo.m_globalCfm = btScalar(solverInfoData->m_solverInfo.m_globalCfm);
158                         solverInfo.m_splitImpulsePenetrationThreshold = btScalar(solverInfoData->m_solverInfo.m_splitImpulsePenetrationThreshold);
159                         solverInfo.m_splitImpulseTurnErp = btScalar(solverInfoData->m_solverInfo.m_splitImpulseTurnErp);
160                 
161                         solverInfo.m_linearSlop = btScalar(solverInfoData->m_solverInfo.m_linearSlop);
162                         solverInfo.m_warmstartingFactor = btScalar(solverInfoData->m_solverInfo.m_warmstartingFactor);
163                         solverInfo.m_maxGyroscopicForce = btScalar(solverInfoData->m_solverInfo.m_maxGyroscopicForce);
164                         solverInfo.m_singleAxisRollingFrictionThreshold = btScalar(solverInfoData->m_solverInfo.m_singleAxisRollingFrictionThreshold);
165                 
166                         solverInfo.m_numIterations = solverInfoData->m_solverInfo.m_numIterations;
167                         solverInfo.m_solverMode = solverInfoData->m_solverInfo.m_solverMode;
168                         solverInfo.m_restingContactRestitutionThreshold = solverInfoData->m_solverInfo.m_restingContactRestitutionThreshold;
169                         solverInfo.m_minimumSolverBatchSize = solverInfoData->m_solverInfo.m_minimumSolverBatchSize;
170                 
171                         solverInfo.m_splitImpulse = solverInfoData->m_solverInfo.m_splitImpulse;
172
173                         setDynamicsWorldInfo(gravity,solverInfo);
174                 } else
175                 {
176                         btDynamicsWorldFloatData* solverInfoData = (btDynamicsWorldFloatData*)bulletFile2->m_dynamicsWorldInfo[i];
177                         btContactSolverInfo solverInfo;
178
179                         btVector3 gravity;
180                         gravity.deSerializeFloat(solverInfoData->m_gravity);
181
182                         solverInfo.m_tau = solverInfoData->m_solverInfo.m_tau;
183                         solverInfo.m_damping = solverInfoData->m_solverInfo.m_damping;
184                         solverInfo.m_friction = solverInfoData->m_solverInfo.m_friction;
185                         solverInfo.m_timeStep = solverInfoData->m_solverInfo.m_timeStep;
186
187                         solverInfo.m_restitution = solverInfoData->m_solverInfo.m_restitution;
188                         solverInfo.m_maxErrorReduction = solverInfoData->m_solverInfo.m_maxErrorReduction;
189                         solverInfo.m_sor = solverInfoData->m_solverInfo.m_sor;
190                         solverInfo.m_erp = solverInfoData->m_solverInfo.m_erp;
191
192                         solverInfo.m_erp2 = solverInfoData->m_solverInfo.m_erp2;
193                         solverInfo.m_globalCfm = solverInfoData->m_solverInfo.m_globalCfm;
194                         solverInfo.m_splitImpulsePenetrationThreshold = solverInfoData->m_solverInfo.m_splitImpulsePenetrationThreshold;
195                         solverInfo.m_splitImpulseTurnErp = solverInfoData->m_solverInfo.m_splitImpulseTurnErp;
196                 
197                         solverInfo.m_linearSlop = solverInfoData->m_solverInfo.m_linearSlop;
198                         solverInfo.m_warmstartingFactor = solverInfoData->m_solverInfo.m_warmstartingFactor;
199                         solverInfo.m_maxGyroscopicForce = solverInfoData->m_solverInfo.m_maxGyroscopicForce;
200                         solverInfo.m_singleAxisRollingFrictionThreshold = solverInfoData->m_solverInfo.m_singleAxisRollingFrictionThreshold;
201                 
202                         solverInfo.m_numIterations = solverInfoData->m_solverInfo.m_numIterations;
203                         solverInfo.m_solverMode = solverInfoData->m_solverInfo.m_solverMode;
204                         solverInfo.m_restingContactRestitutionThreshold = solverInfoData->m_solverInfo.m_restingContactRestitutionThreshold;
205                         solverInfo.m_minimumSolverBatchSize = solverInfoData->m_solverInfo.m_minimumSolverBatchSize;
206                 
207                         solverInfo.m_splitImpulse = solverInfoData->m_solverInfo.m_splitImpulse;
208
209                         setDynamicsWorldInfo(gravity,solverInfo);
210                 }
211         }
212
213
214         for (i=0;i<bulletFile2->m_rigidBodies.size();i++)
215         {
216                 if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
217                 {
218                         btRigidBodyDoubleData* colObjData = (btRigidBodyDoubleData*)bulletFile2->m_rigidBodies[i];
219                         convertRigidBodyDouble(colObjData);
220                 } else
221                 {
222                         btRigidBodyFloatData* colObjData = (btRigidBodyFloatData*)bulletFile2->m_rigidBodies[i];
223                         convertRigidBodyFloat(colObjData);
224                 }
225
226                 
227         }
228
229         for (i=0;i<bulletFile2->m_collisionObjects.size();i++)
230         {
231                 if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
232                 {
233                         btCollisionObjectDoubleData* colObjData = (btCollisionObjectDoubleData*)bulletFile2->m_collisionObjects[i];
234                         btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionShape);
235                         if (shapePtr && *shapePtr)
236                         {
237                                 btTransform startTransform;
238                                 colObjData->m_worldTransform.m_origin.m_floats[3] = 0.f;
239                                 startTransform.deSerializeDouble(colObjData->m_worldTransform);
240                                 
241                                 btCollisionShape* shape = (btCollisionShape*)*shapePtr;
242                                 btCollisionObject* body = createCollisionObject(startTransform,shape,colObjData->m_name);
243                                 body->setFriction(btScalar(colObjData->m_friction));
244                                 body->setRestitution(btScalar(colObjData->m_restitution));
245                                 
246 #ifdef USE_INTERNAL_EDGE_UTILITY
247                                 if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
248                                 {
249                                         btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape;
250                                         if (trimesh->getTriangleInfoMap())
251                                         {
252                                                 body->setCollisionFlags(body->getCollisionFlags()  | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
253                                         }
254                                 }
255 #endif //USE_INTERNAL_EDGE_UTILITY
256                                 m_bodyMap.insert(colObjData,body);
257                         } else
258                         {
259                                 printf("error: no shape found\n");
260                         }
261         
262                 } else
263                 {
264                         btCollisionObjectFloatData* colObjData = (btCollisionObjectFloatData*)bulletFile2->m_collisionObjects[i];
265                         btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionShape);
266                         if (shapePtr && *shapePtr)
267                         {
268                                 btTransform startTransform;
269                                 colObjData->m_worldTransform.m_origin.m_floats[3] = 0.f;
270                                 startTransform.deSerializeFloat(colObjData->m_worldTransform);
271                                 
272                                 btCollisionShape* shape = (btCollisionShape*)*shapePtr;
273                                 btCollisionObject* body = createCollisionObject(startTransform,shape,colObjData->m_name);
274
275 #ifdef USE_INTERNAL_EDGE_UTILITY
276                                 if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
277                                 {
278                                         btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape;
279                                         if (trimesh->getTriangleInfoMap())
280                                         {
281                                                 body->setCollisionFlags(body->getCollisionFlags()  | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
282                                         }
283                                 }
284 #endif //USE_INTERNAL_EDGE_UTILITY
285                                 m_bodyMap.insert(colObjData,body);
286                         } else
287                         {
288                                 printf("error: no shape found\n");
289                         }
290                 }
291                 
292         }
293
294         
295         for (i=0;i<bulletFile2->m_constraints.size();i++)
296         {
297                 btTypedConstraintData* constraintData = (btTypedConstraintData*)bulletFile2->m_constraints[i];
298                 btCollisionObject** colAptr = m_bodyMap.find(constraintData->m_rbA);
299                 btCollisionObject** colBptr = m_bodyMap.find(constraintData->m_rbB);
300
301                 btRigidBody* rbA = 0;
302                 btRigidBody* rbB = 0;
303
304                 if (colAptr)
305                 {
306                         rbA = btRigidBody::upcast(*colAptr);
307                         if (!rbA)
308                                 rbA = &getFixedBody();
309                 }
310                 if (colBptr)
311                 {
312                         rbB = btRigidBody::upcast(*colBptr);
313                         if (!rbB)
314                                 rbB = &getFixedBody();
315                 }
316                 if (!rbA && !rbB)
317                         continue;
318                                 
319                 bool isDoublePrecisionData = (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)!=0;
320                 convertConstraint(constraintData, rbA,rbB,isDoublePrecisionData, bulletFile2->getVersion());
321
322         }
323
324         return true;
325 }
326