Bullet Collision Detection & Physics Library
btBulletWorldImporter.cpp
Go to the documentation of this file.
1/*
2Bullet Continuous Collision Detection and Physics Library
3Copyright (c) 2003-2012 Erwin Coumans http://bulletphysics.org
4
5This software is provided 'as-is', without any express or implied warranty.
6In no event will the authors be held liable for any damages arising from the use of this software.
7Permission is granted to anyone to use this software for any purpose,
8including commercial applications, and to alter it and redistribute it freely,
9subject to the following restrictions:
10
111. 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.
122. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
133. This notice may not be removed or altered from any source distribution.
14*/
15
16
18#include "../BulletFileLoader/btBulletFile.h"
19
21#ifndef USE_GIMPACT
23#endif
24
25
26//#define USE_INTERNAL_EDGE_UTILITY
27#ifdef USE_INTERNAL_EDGE_UTILITY
29#endif //USE_INTERNAL_EDGE_UTILITY
30
32 :btWorldImporter(world)
33{
34}
35
37{
38}
39
40
41bool btBulletWorldImporter::loadFile( const char* fileName, const char* preSwapFilenameOut)
42{
43 bParse::btBulletFile* bulletFile2 = new bParse::btBulletFile(fileName);
44
45
46 bool result = loadFileFromMemory(bulletFile2);
47 //now you could save the file in 'native' format using
48 //bulletFile2->writeFile("native.bullet");
49 if (result)
50 {
51 if (preSwapFilenameOut)
52 {
53 bulletFile2->preSwap();
54 bulletFile2->writeFile(preSwapFilenameOut);
55 }
56
57 }
58 delete bulletFile2;
59
60 return result;
61
62}
63
64
65
66bool btBulletWorldImporter::loadFileFromMemory( char* memoryBuffer, int len)
67{
68 bParse::btBulletFile* bulletFile2 = new bParse::btBulletFile(memoryBuffer,len);
69
70 bool result = loadFileFromMemory(bulletFile2);
71
72 delete bulletFile2;
73
74 return result;
75}
76
77
78
79
81{
82 bool ok = (bulletFile2->getFlags()& bParse::FD_OK)!=0;
83
84 if (ok)
85 bulletFile2->parse(m_verboseMode);
86 else
87 return false;
88
90 {
91 bulletFile2->dumpChunks(bulletFile2->getFileDNA());
92 }
93
94 return convertAllObjects(bulletFile2);
95
96}
97
99{
100
101 m_shapeMap.clear();
102 m_bodyMap.clear();
103
104 int i;
105
106 for (i=0;i<bulletFile2->m_bvhs.size();i++)
107 {
109
110 if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
111 {
112 btQuantizedBvhDoubleData* bvhData = (btQuantizedBvhDoubleData*)bulletFile2->m_bvhs[i];
113 bvh->deSerializeDouble(*bvhData);
114 } else
115 {
116 btQuantizedBvhFloatData* bvhData = (btQuantizedBvhFloatData*)bulletFile2->m_bvhs[i];
117 bvh->deSerializeFloat(*bvhData);
118 }
119 m_bvhMap.insert(bulletFile2->m_bvhs[i],bvh);
120 }
121
122
123
124
125
126 for (i=0;i<bulletFile2->m_collisionShapes.size();i++)
127 {
128 btCollisionShapeData* shapeData = (btCollisionShapeData*)bulletFile2->m_collisionShapes[i];
129 btCollisionShape* shape = convertCollisionShape(shapeData);
130 if (shape)
131 {
132 // printf("shapeMap.insert(%x,%x)\n",shapeData,shape);
133 m_shapeMap.insert(shapeData,shape);
134 }
135
136 if (shape&& shapeData->m_name)
137 {
138 char* newname = duplicateName(shapeData->m_name);
139 m_objectNameMap.insert(shape,newname);
140 m_nameShapeMap.insert(newname,shape);
141 }
142 }
143
144
145
146
147
148 for (int i=0;i<bulletFile2->m_dynamicsWorldInfo.size();i++)
149 {
150 if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
151 {
153 btContactSolverInfo solverInfo;
154
155 btVector3 gravity;
156 gravity.deSerializeDouble(solverInfoData->m_gravity);
157
158 solverInfo.m_tau = btScalar(solverInfoData->m_solverInfo.m_tau);
159 solverInfo.m_damping = btScalar(solverInfoData->m_solverInfo.m_damping);
160 solverInfo.m_friction = btScalar(solverInfoData->m_solverInfo.m_friction);
161 solverInfo.m_timeStep = btScalar(solverInfoData->m_solverInfo.m_timeStep);
162
163 solverInfo.m_restitution = btScalar(solverInfoData->m_solverInfo.m_restitution);
164 solverInfo.m_maxErrorReduction = btScalar(solverInfoData->m_solverInfo.m_maxErrorReduction);
165 solverInfo.m_sor = btScalar(solverInfoData->m_solverInfo.m_sor);
166 solverInfo.m_erp = btScalar(solverInfoData->m_solverInfo.m_erp);
167
168 solverInfo.m_erp2 = btScalar(solverInfoData->m_solverInfo.m_erp2);
169 solverInfo.m_globalCfm = btScalar(solverInfoData->m_solverInfo.m_globalCfm);
170 solverInfo.m_splitImpulsePenetrationThreshold = btScalar(solverInfoData->m_solverInfo.m_splitImpulsePenetrationThreshold);
171 solverInfo.m_splitImpulseTurnErp = btScalar(solverInfoData->m_solverInfo.m_splitImpulseTurnErp);
172
173 solverInfo.m_linearSlop = btScalar(solverInfoData->m_solverInfo.m_linearSlop);
174 solverInfo.m_warmstartingFactor = btScalar(solverInfoData->m_solverInfo.m_warmstartingFactor);
175 solverInfo.m_maxGyroscopicForce = btScalar(solverInfoData->m_solverInfo.m_maxGyroscopicForce);
176 solverInfo.m_singleAxisRollingFrictionThreshold = btScalar(solverInfoData->m_solverInfo.m_singleAxisRollingFrictionThreshold);
177
178 solverInfo.m_numIterations = solverInfoData->m_solverInfo.m_numIterations;
179 solverInfo.m_solverMode = solverInfoData->m_solverInfo.m_solverMode;
180 solverInfo.m_restingContactRestitutionThreshold = solverInfoData->m_solverInfo.m_restingContactRestitutionThreshold;
181 solverInfo.m_minimumSolverBatchSize = solverInfoData->m_solverInfo.m_minimumSolverBatchSize;
182
183 solverInfo.m_splitImpulse = solverInfoData->m_solverInfo.m_splitImpulse;
184
185 setDynamicsWorldInfo(gravity,solverInfo);
186 } else
187 {
189 btContactSolverInfo solverInfo;
190
191 btVector3 gravity;
192 gravity.deSerializeFloat(solverInfoData->m_gravity);
193
194 solverInfo.m_tau = solverInfoData->m_solverInfo.m_tau;
195 solverInfo.m_damping = solverInfoData->m_solverInfo.m_damping;
196 solverInfo.m_friction = solverInfoData->m_solverInfo.m_friction;
197 solverInfo.m_timeStep = solverInfoData->m_solverInfo.m_timeStep;
198
199 solverInfo.m_restitution = solverInfoData->m_solverInfo.m_restitution;
200 solverInfo.m_maxErrorReduction = solverInfoData->m_solverInfo.m_maxErrorReduction;
201 solverInfo.m_sor = solverInfoData->m_solverInfo.m_sor;
202 solverInfo.m_erp = solverInfoData->m_solverInfo.m_erp;
203
204 solverInfo.m_erp2 = solverInfoData->m_solverInfo.m_erp2;
205 solverInfo.m_globalCfm = solverInfoData->m_solverInfo.m_globalCfm;
206 solverInfo.m_splitImpulsePenetrationThreshold = solverInfoData->m_solverInfo.m_splitImpulsePenetrationThreshold;
207 solverInfo.m_splitImpulseTurnErp = solverInfoData->m_solverInfo.m_splitImpulseTurnErp;
208
209 solverInfo.m_linearSlop = solverInfoData->m_solverInfo.m_linearSlop;
210 solverInfo.m_warmstartingFactor = solverInfoData->m_solverInfo.m_warmstartingFactor;
211 solverInfo.m_maxGyroscopicForce = solverInfoData->m_solverInfo.m_maxGyroscopicForce;
212 solverInfo.m_singleAxisRollingFrictionThreshold = solverInfoData->m_solverInfo.m_singleAxisRollingFrictionThreshold;
213
214 solverInfo.m_numIterations = solverInfoData->m_solverInfo.m_numIterations;
215 solverInfo.m_solverMode = solverInfoData->m_solverInfo.m_solverMode;
216 solverInfo.m_restingContactRestitutionThreshold = solverInfoData->m_solverInfo.m_restingContactRestitutionThreshold;
217 solverInfo.m_minimumSolverBatchSize = solverInfoData->m_solverInfo.m_minimumSolverBatchSize;
218
219 solverInfo.m_splitImpulse = solverInfoData->m_solverInfo.m_splitImpulse;
220
221 setDynamicsWorldInfo(gravity,solverInfo);
222 }
223 }
224
225
226 for (i=0;i<bulletFile2->m_rigidBodies.size();i++)
227 {
228 if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
229 {
230 btRigidBodyDoubleData* colObjData = (btRigidBodyDoubleData*)bulletFile2->m_rigidBodies[i];
231 convertRigidBodyDouble(colObjData);
232 } else
233 {
234 btRigidBodyFloatData* colObjData = (btRigidBodyFloatData*)bulletFile2->m_rigidBodies[i];
235 convertRigidBodyFloat(colObjData);
236 }
237
238
239 }
240
241 for (i=0;i<bulletFile2->m_collisionObjects.size();i++)
242 {
243 if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
244 {
246 btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionShape);
247 if (shapePtr && *shapePtr)
248 {
249 btTransform startTransform;
250 colObjData->m_worldTransform.m_origin.m_floats[3] = 0.f;
251 startTransform.deSerializeDouble(colObjData->m_worldTransform);
252
253 btCollisionShape* shape = (btCollisionShape*)*shapePtr;
254 btCollisionObject* body = createCollisionObject(startTransform,shape,colObjData->m_name);
255 body->setFriction(btScalar(colObjData->m_friction));
256 body->setRestitution(btScalar(colObjData->m_restitution));
257
258#ifdef USE_INTERNAL_EDGE_UTILITY
260 {
262 if (trimesh->getTriangleInfoMap())
263 {
265 }
266 }
267#endif //USE_INTERNAL_EDGE_UTILITY
268 m_bodyMap.insert(colObjData,body);
269 } else
270 {
271 printf("error: no shape found\n");
272 }
273
274 } else
275 {
277 btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionShape);
278 if (shapePtr && *shapePtr)
279 {
280 btTransform startTransform;
281 colObjData->m_worldTransform.m_origin.m_floats[3] = 0.f;
282 startTransform.deSerializeFloat(colObjData->m_worldTransform);
283
284 btCollisionShape* shape = (btCollisionShape*)*shapePtr;
285 btCollisionObject* body = createCollisionObject(startTransform,shape,colObjData->m_name);
286
287#ifdef USE_INTERNAL_EDGE_UTILITY
289 {
291 if (trimesh->getTriangleInfoMap())
292 {
294 }
295 }
296#endif //USE_INTERNAL_EDGE_UTILITY
297 m_bodyMap.insert(colObjData,body);
298 } else
299 {
300 printf("error: no shape found\n");
301 }
302 }
303
304 }
305
306
307 for (i=0;i<bulletFile2->m_constraints.size();i++)
308 {
309 btTypedConstraintData2* constraintData = (btTypedConstraintData2*)bulletFile2->m_constraints[i];
310
311 btCollisionObject** colAptr = m_bodyMap.find(constraintData->m_rbA);
312 btCollisionObject** colBptr = m_bodyMap.find(constraintData->m_rbB);
313
314 btRigidBody* rbA = 0;
315 btRigidBody* rbB = 0;
316
317 if (colAptr)
318 {
319 rbA = btRigidBody::upcast(*colAptr);
320 if (!rbA)
321 rbA = &getFixedBody();
322 }
323 if (colBptr)
324 {
325 rbB = btRigidBody::upcast(*colBptr);
326 if (!rbB)
327 rbB = &getFixedBody();
328 }
329 if (!rbA && !rbB)
330 continue;
331
332 bool isDoublePrecisionData = (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)!=0;
333
334 if (isDoublePrecisionData)
335 {
336 if (bulletFile2->getVersion()>=282)
337 {
339 convertConstraintDouble(dc, rbA,rbB, bulletFile2->getVersion());
340 } else
341 {
342 //double-precision constraints were messed up until 2.82, try to recover data...
343
344 btTypedConstraintData* oldData = (btTypedConstraintData*)constraintData;
345
346 convertConstraintBackwardsCompatible281(oldData, rbA,rbB, bulletFile2->getVersion());
347
348 }
349 }
350 else
351 {
353 convertConstraintFloat(dc, rbA,rbB, bulletFile2->getVersion());
354 }
355
356
357 }
358
359 return true;
360}
361
@ TRIANGLE_MESH_SHAPE_PROXYTYPE
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:292
#define btTypedConstraintData2
void writeFile(const char *fileName)
Definition: bFile.cpp:567
void dumpChunks(bDNA *dna)
Definition: bFile.cpp:1530
int getFlags() const
Definition: bFile.h:127
bDNA * getFileDNA()
Definition: bFile.h:120
int getVersion() const
Definition: bFile.h:161
void preSwap()
Definition: bFile.cpp:574
btAlignedObjectArray< bStructHandle * > m_dynamicsWorldInfo
Definition: btBulletFile.h:58
btAlignedObjectArray< bStructHandle * > m_rigidBodies
Definition: btBulletFile.h:46
virtual void parse(int verboseMode)
btAlignedObjectArray< bStructHandle * > m_bvhs
Definition: btBulletFile.h:54
btAlignedObjectArray< bStructHandle * > m_constraints
Definition: btBulletFile.h:52
btAlignedObjectArray< bStructHandle * > m_collisionObjects
Definition: btBulletFile.h:48
btAlignedObjectArray< bStructHandle * > m_collisionShapes
Definition: btBulletFile.h:50
bool loadFileFromMemory(char *memoryBuffer, int len)
the memoryBuffer might be modified (for example if endian swaps are necessary)
btBulletWorldImporter(btDynamicsWorld *world=0)
bool loadFile(const char *fileName, const char *preSwapFilenameOut=0)
if you pass a valid preSwapFilenameOut, it will save a new file with a different endianness this pre-...
virtual bool convertAllObjects(bParse::btBulletFile *file)
The btBvhTriangleMeshShape is a static-triangle mesh shape, it can only be used for fixed/non-moving ...
const btTriangleInfoMap * getTriangleInfoMap() const
btCollisionObject can be used to manage collision detection objects.
void setRestitution(btScalar rest)
void setCollisionFlags(int flags)
void setFriction(btScalar frict)
int getCollisionFlags() const
The btCollisionShape class provides an interface for collision shapes that can be shared among btColl...
int getShapeType() const
The btDynamicsWorld is the interface class for several dynamics implementation, basic,...
The btOptimizedBvh extends the btQuantizedBvh to create AABB tree for triangle meshes,...
virtual void deSerializeFloat(struct btQuantizedBvhFloatData &quantizedBvhFloatData)
virtual void deSerializeDouble(struct btQuantizedBvhDoubleData &quantizedBvhDoubleData)
The btRigidBody is the main class for rigid body objects.
Definition: btRigidBody.h:63
static const btRigidBody * upcast(const btCollisionObject *colObj)
to keep collision detection and dynamics separate we don't store a rigidbody pointer but a rigidbody ...
Definition: btRigidBody.h:203
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:34
void deSerializeFloat(const struct btTransformFloatData &dataIn)
Definition: btTransform.h:286
void deSerializeDouble(const struct btTransformDoubleData &dataIn)
Definition: btTransform.h:292
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:84
void deSerializeFloat(const struct btVector3FloatData &dataIn)
Definition: btVector3.h:1330
void deSerializeDouble(const struct btVector3DoubleData &dataIn)
Definition: btVector3.h:1344
char * duplicateName(const char *name)
virtual btCollisionObject * createCollisionObject(const btTransform &startTransform, btCollisionShape *shape, const char *bodyName)
static btRigidBody & getFixedBody()
virtual btOptimizedBvh * createOptimizedBvh()
acceleration and connectivity structures
void convertConstraintBackwardsCompatible281(btTypedConstraintData *constraintData, btRigidBody *rbA, btRigidBody *rbB, int fileVersion)
btHashMap< btHashPtr, btOptimizedBvh * > m_bvhMap
btHashMap< btHashPtr, btCollisionObject * > m_bodyMap
btHashMap< btHashPtr, const char * > m_objectNameMap
void convertConstraintDouble(btTypedConstraintDoubleData *constraintData, btRigidBody *rbA, btRigidBody *rbB, int fileVersion)
virtual void setDynamicsWorldInfo(const btVector3 &gravity, const btContactSolverInfo &solverInfo)
those virtuals are called by load and can be overridden by the user
void convertConstraintFloat(btTypedConstraintFloatData *constraintData, btRigidBody *rbA, btRigidBody *rbB, int fileVersion)
btHashMap< btHashString, btCollisionShape * > m_nameShapeMap
btCollisionShape * convertCollisionShape(btCollisionShapeData *shapeData)
btHashMap< btHashPtr, btCollisionShape * > m_shapeMap
void convertRigidBodyDouble(btRigidBodyDoubleData *colObjData)
void convertRigidBodyFloat(btRigidBodyFloatData *colObjData)
@ FD_OK
Definition: bFile.h:29
@ FD_DOUBLE_PRECISION
Definition: bFile.h:35
@ FD_VERBOSE_DUMP_CHUNKS
Definition: bFile.h:44
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
btTransformDoubleData m_worldTransform
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
btTransformFloatData m_worldTransform
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
double m_singleAxisRollingFrictionThreshold
it is only used for 'explicit' version of gyroscopic force
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
btContactSolverInfoDoubleData m_solverInfo
btVector3DoubleData m_gravity
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
btVector3FloatData m_gravity
btContactSolverInfoFloatData m_solverInfo
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
Definition: btRigidBody.h:591
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
Definition: btRigidBody.h:565
btVector3DoubleData m_origin
Definition: btTransform.h:262
btVector3FloatData m_origin
Definition: btTransform.h:256
this structure is not used, except for loading pre-2.82 .bullet files
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
double m_floats[4]
Definition: btVector3.h:1319