2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2012 Erwin Coumans http://bulletphysics.org
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:
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.
17 #include "btBulletWorldImporter.h"
18 #include "../BulletFileLoader/btBulletFile.h"
20 #include "btBulletDynamicsCommon.h"
21 #include "BulletCollision/Gimpact/btGImpactShape.h"
25 //#define USE_INTERNAL_EDGE_UTILITY
26 #ifdef USE_INTERNAL_EDGE_UTILITY
27 #include "BulletCollision/CollisionDispatch/btInternalEdgeUtility.h"
28 #endif //USE_INTERNAL_EDGE_UTILITY
30 btBulletWorldImporter::btBulletWorldImporter(btDynamicsWorld* world)
31 :btWorldImporter(world)
35 btBulletWorldImporter::~btBulletWorldImporter()
40 bool btBulletWorldImporter::loadFile( const char* fileName)
42 bParse::btBulletFile* bulletFile2 = new bParse::btBulletFile(fileName);
44 bool result = loadFileFromMemory(bulletFile2);
54 bool btBulletWorldImporter::loadFileFromMemory( char* memoryBuffer, int len)
56 bParse::btBulletFile* bulletFile2 = new bParse::btBulletFile(memoryBuffer,len);
58 bool result = loadFileFromMemory(bulletFile2);
68 bool btBulletWorldImporter::loadFileFromMemory( bParse::btBulletFile* bulletFile2)
70 bool ok = (bulletFile2->getFlags()& bParse::FD_OK)!=0;
73 bulletFile2->parse(m_verboseMode);
77 if (m_verboseMode & bParse::FD_VERBOSE_DUMP_CHUNKS)
79 bulletFile2->dumpChunks(bulletFile2->getFileDNA());
82 return convertAllObjects(bulletFile2);
86 bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile2)
94 for (i=0;i<bulletFile2->m_bvhs.size();i++)
96 btOptimizedBvh* bvh = createOptimizedBvh();
98 if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
100 btQuantizedBvhDoubleData* bvhData = (btQuantizedBvhDoubleData*)bulletFile2->m_bvhs[i];
101 bvh->deSerializeDouble(*bvhData);
104 btQuantizedBvhFloatData* bvhData = (btQuantizedBvhFloatData*)bulletFile2->m_bvhs[i];
105 bvh->deSerializeFloat(*bvhData);
107 m_bvhMap.insert(bulletFile2->m_bvhs[i],bvh);
114 for (i=0;i<bulletFile2->m_collisionShapes.size();i++)
116 btCollisionShapeData* shapeData = (btCollisionShapeData*)bulletFile2->m_collisionShapes[i];
117 btCollisionShape* shape = convertCollisionShape(shapeData);
120 // printf("shapeMap.insert(%x,%x)\n",shapeData,shape);
121 m_shapeMap.insert(shapeData,shape);
124 if (shape&& shapeData->m_name)
126 char* newname = duplicateName(shapeData->m_name);
127 m_objectNameMap.insert(shape,newname);
128 m_nameShapeMap.insert(newname,shape);
136 for (int i=0;i<bulletFile2->m_dynamicsWorldInfo.size();i++)
138 if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
140 btDynamicsWorldDoubleData* solverInfoData = (btDynamicsWorldDoubleData*)bulletFile2->m_dynamicsWorldInfo[i];
141 btContactSolverInfo solverInfo;
144 gravity.deSerializeDouble(solverInfoData->m_gravity);
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);
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);
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);
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);
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;
171 solverInfo.m_splitImpulse = solverInfoData->m_solverInfo.m_splitImpulse;
173 setDynamicsWorldInfo(gravity,solverInfo);
176 btDynamicsWorldFloatData* solverInfoData = (btDynamicsWorldFloatData*)bulletFile2->m_dynamicsWorldInfo[i];
177 btContactSolverInfo solverInfo;
180 gravity.deSerializeFloat(solverInfoData->m_gravity);
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;
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;
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;
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;
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;
207 solverInfo.m_splitImpulse = solverInfoData->m_solverInfo.m_splitImpulse;
209 setDynamicsWorldInfo(gravity,solverInfo);
214 for (i=0;i<bulletFile2->m_rigidBodies.size();i++)
216 if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
218 btRigidBodyDoubleData* colObjData = (btRigidBodyDoubleData*)bulletFile2->m_rigidBodies[i];
219 convertRigidBodyDouble(colObjData);
222 btRigidBodyFloatData* colObjData = (btRigidBodyFloatData*)bulletFile2->m_rigidBodies[i];
223 convertRigidBodyFloat(colObjData);
229 for (i=0;i<bulletFile2->m_collisionObjects.size();i++)
231 if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
233 btCollisionObjectDoubleData* colObjData = (btCollisionObjectDoubleData*)bulletFile2->m_collisionObjects[i];
234 btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionShape);
235 if (shapePtr && *shapePtr)
237 btTransform startTransform;
238 colObjData->m_worldTransform.m_origin.m_floats[3] = 0.f;
239 startTransform.deSerializeDouble(colObjData->m_worldTransform);
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));
246 #ifdef USE_INTERNAL_EDGE_UTILITY
247 if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
249 btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape;
250 if (trimesh->getTriangleInfoMap())
252 body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
255 #endif //USE_INTERNAL_EDGE_UTILITY
256 m_bodyMap.insert(colObjData,body);
259 printf("error: no shape found\n");
264 btCollisionObjectFloatData* colObjData = (btCollisionObjectFloatData*)bulletFile2->m_collisionObjects[i];
265 btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionShape);
266 if (shapePtr && *shapePtr)
268 btTransform startTransform;
269 colObjData->m_worldTransform.m_origin.m_floats[3] = 0.f;
270 startTransform.deSerializeFloat(colObjData->m_worldTransform);
272 btCollisionShape* shape = (btCollisionShape*)*shapePtr;
273 btCollisionObject* body = createCollisionObject(startTransform,shape,colObjData->m_name);
275 #ifdef USE_INTERNAL_EDGE_UTILITY
276 if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
278 btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape;
279 if (trimesh->getTriangleInfoMap())
281 body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
284 #endif //USE_INTERNAL_EDGE_UTILITY
285 m_bodyMap.insert(colObjData,body);
288 printf("error: no shape found\n");
295 for (i=0;i<bulletFile2->m_constraints.size();i++)
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);
301 btRigidBody* rbA = 0;
302 btRigidBody* rbB = 0;
306 rbA = btRigidBody::upcast(*colAptr);
308 rbA = &getFixedBody();
312 rbB = btRigidBody::upcast(*colBptr);
314 rbB = &getFixedBody();
319 bool isDoublePrecisionData = (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)!=0;
320 convertConstraint(constraintData, rbA,rbB,isDoublePrecisionData, bulletFile2->getVersion());