Home | History | Annotate | Download | only in BulletWorldImporter
      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 #ifndef USE_GIMPACT
     22 #include "BulletCollision/Gimpact/btGImpactShape.h"
     23 #endif
     24 
     25 
     26 //#define USE_INTERNAL_EDGE_UTILITY
     27 #ifdef USE_INTERNAL_EDGE_UTILITY
     28 #include "BulletCollision/CollisionDispatch/btInternalEdgeUtility.h"
     29 #endif //USE_INTERNAL_EDGE_UTILITY
     30 
     31 btBulletWorldImporter::btBulletWorldImporter(btDynamicsWorld* world)
     32 	:btWorldImporter(world)
     33 {
     34 }
     35 
     36 btBulletWorldImporter::~btBulletWorldImporter()
     37 {
     38 }
     39 
     40 
     41 bool	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 
     66 bool	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 
     80 bool	btBulletWorldImporter::loadFileFromMemory(  bParse::btBulletFile* bulletFile2)
     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 
     89 	if (m_verboseMode & bParse::FD_VERBOSE_DUMP_CHUNKS)
     90 	{
     91 		bulletFile2->dumpChunks(bulletFile2->getFileDNA());
     92 	}
     93 
     94 	return convertAllObjects(bulletFile2);
     95 
     96 }
     97 
     98 bool	btBulletWorldImporter::convertAllObjects(  bParse::btBulletFile* bulletFile2)
     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 	{
    108 		btOptimizedBvh* bvh = createOptimizedBvh();
    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 		{
    152 			btDynamicsWorldDoubleData* solverInfoData = (btDynamicsWorldDoubleData*)bulletFile2->m_dynamicsWorldInfo[i];
    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 		{
    188 			btDynamicsWorldFloatData* solverInfoData = (btDynamicsWorldFloatData*)bulletFile2->m_dynamicsWorldInfo[i];
    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 		{
    245 			btCollisionObjectDoubleData* colObjData = (btCollisionObjectDoubleData*)bulletFile2->m_collisionObjects[i];
    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
    259 				if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
    260 				{
    261 					btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape;
    262 					if (trimesh->getTriangleInfoMap())
    263 					{
    264 						body->setCollisionFlags(body->getCollisionFlags()  | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
    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 		{
    276 			btCollisionObjectFloatData* colObjData = (btCollisionObjectFloatData*)bulletFile2->m_collisionObjects[i];
    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
    288 				if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
    289 				{
    290 					btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape;
    291 					if (trimesh->getTriangleInfoMap())
    292 					{
    293 						body->setCollisionFlags(body->getCollisionFlags()  | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
    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 		btTypedConstraintFloatData* singleC = (btTypedConstraintFloatData*)bulletFile2->m_constraints[i];
    311 		btTypedConstraintDoubleData* doubleC = (btTypedConstraintDoubleData*)bulletFile2->m_constraints[i];
    312 
    313 		btCollisionObject** colAptr = m_bodyMap.find(constraintData->m_rbA);
    314 		btCollisionObject** colBptr = m_bodyMap.find(constraintData->m_rbB);
    315 
    316 		btRigidBody* rbA = 0;
    317 		btRigidBody* rbB = 0;
    318 
    319 		if (colAptr)
    320 		{
    321 			rbA = btRigidBody::upcast(*colAptr);
    322 			if (!rbA)
    323 				rbA = &getFixedBody();
    324 		}
    325 		if (colBptr)
    326 		{
    327 			rbB = btRigidBody::upcast(*colBptr);
    328 			if (!rbB)
    329 				rbB = &getFixedBody();
    330 		}
    331 		if (!rbA && !rbB)
    332 			continue;
    333 
    334 		bool isDoublePrecisionData = (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)!=0;
    335 
    336 		if (isDoublePrecisionData)
    337 		{
    338 			if (bulletFile2->getVersion()>=282)
    339 			{
    340 				btTypedConstraintDoubleData* dc = (btTypedConstraintDoubleData*)constraintData;
    341 				convertConstraintDouble(dc, rbA,rbB, bulletFile2->getVersion());
    342 			} else
    343 			{
    344 				//double-precision constraints were messed up until 2.82, try to recover data...
    345 
    346 				btTypedConstraintData* oldData = (btTypedConstraintData*)constraintData;
    347 
    348 				convertConstraintBackwardsCompatible281(oldData, rbA,rbB, bulletFile2->getVersion());
    349 
    350 			}
    351 		}
    352 		else
    353 		{
    354 			btTypedConstraintFloatData* dc = (btTypedConstraintFloatData*)constraintData;
    355 			convertConstraintFloat(dc, rbA,rbB, bulletFile2->getVersion());
    356 		}
    357 
    358 
    359 	}
    360 
    361 	return true;
    362 }
    363 
    364