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 #include "btWorldImporter.h"
     17 #include "btBulletDynamicsCommon.h"
     18 #ifdef USE_GIMPACT
     19 #include "BulletCollision/Gimpact/btGImpactShape.h"
     20 #endif
     21 btWorldImporter::btWorldImporter(btDynamicsWorld* world)
     22 :m_dynamicsWorld(world),
     23 m_verboseMode(0)
     24 {
     25 
     26 }
     27 
     28 btWorldImporter::~btWorldImporter()
     29 {
     30 }
     31 
     32 void btWorldImporter::deleteAllData()
     33 {
     34 	int i;
     35 	for (i=0;i<m_allocatedConstraints.size();i++)
     36 	{
     37 		if(m_dynamicsWorld)
     38 			m_dynamicsWorld->removeConstraint(m_allocatedConstraints[i]);
     39 		delete m_allocatedConstraints[i];
     40 	}
     41 	m_allocatedConstraints.clear();
     42 
     43 
     44 	for (i=0;i<m_allocatedRigidBodies.size();i++)
     45 	{
     46 		if(m_dynamicsWorld)
     47 			m_dynamicsWorld->removeRigidBody(btRigidBody::upcast(m_allocatedRigidBodies[i]));
     48 		delete m_allocatedRigidBodies[i];
     49 	}
     50 
     51 	m_allocatedRigidBodies.clear();
     52 
     53 
     54 	for (i=0;i<m_allocatedCollisionShapes.size();i++)
     55 	{
     56 		delete m_allocatedCollisionShapes[i];
     57 	}
     58 	m_allocatedCollisionShapes.clear();
     59 
     60 
     61 	for (i=0;i<m_allocatedBvhs.size();i++)
     62 	{
     63 		delete m_allocatedBvhs[i];
     64 	}
     65 	m_allocatedBvhs.clear();
     66 
     67 	for (i=0;i<m_allocatedTriangleInfoMaps.size();i++)
     68 	{
     69 		delete m_allocatedTriangleInfoMaps[i];
     70 	}
     71 	m_allocatedTriangleInfoMaps.clear();
     72 	for (i=0;i<m_allocatedTriangleIndexArrays.size();i++)
     73 	{
     74 		delete m_allocatedTriangleIndexArrays[i];
     75 	}
     76 	m_allocatedTriangleIndexArrays.clear();
     77 	for (i=0;i<m_allocatedNames.size();i++)
     78 	{
     79 		delete[] m_allocatedNames[i];
     80 	}
     81 	m_allocatedNames.clear();
     82 
     83 	for (i=0;i<m_allocatedbtStridingMeshInterfaceDatas.size();i++)
     84 	{
     85 		btStridingMeshInterfaceData* curData = m_allocatedbtStridingMeshInterfaceDatas[i];
     86 
     87 		for(int a = 0;a < curData->m_numMeshParts;a++)
     88 		{
     89 			btMeshPartData* curPart = &curData->m_meshPartsPtr[a];
     90 			if(curPart->m_vertices3f)
     91 				delete [] curPart->m_vertices3f;
     92 
     93 			if(curPart->m_vertices3d)
     94 				delete [] curPart->m_vertices3d;
     95 
     96 			if(curPart->m_indices32)
     97 				delete [] curPart->m_indices32;
     98 
     99 			if(curPart->m_3indices16)
    100 				delete [] curPart->m_3indices16;
    101 
    102 			if(curPart->m_indices16)
    103 				delete [] curPart->m_indices16;
    104 
    105 			if (curPart->m_3indices8)
    106 				delete [] curPart->m_3indices8;
    107 
    108 		}
    109 		delete [] curData->m_meshPartsPtr;
    110 		delete curData;
    111 	}
    112 	m_allocatedbtStridingMeshInterfaceDatas.clear();
    113 
    114 	for (i=0;i<m_indexArrays.size();i++)
    115 	{
    116 		btAlignedFree(m_indexArrays[i]);
    117 	}
    118   m_indexArrays.clear();
    119 
    120 	for (i=0;i<m_shortIndexArrays.size();i++)
    121 	{
    122 		btAlignedFree(m_shortIndexArrays[i]);
    123 	}
    124   m_shortIndexArrays.clear();
    125 
    126 	for (i=0;i<m_charIndexArrays.size();i++)
    127 	{
    128 		btAlignedFree(m_charIndexArrays[i]);
    129 	}
    130   m_charIndexArrays.clear();
    131 
    132 	for (i=0;i<m_floatVertexArrays.size();i++)
    133 	{
    134 		btAlignedFree(m_floatVertexArrays[i]);
    135 	}
    136   m_floatVertexArrays.clear();
    137 
    138 	for (i=0;i<m_doubleVertexArrays.size();i++)
    139 	{
    140 		btAlignedFree(m_doubleVertexArrays[i]);
    141 	}
    142    m_doubleVertexArrays.clear();
    143 
    144 
    145 }
    146 
    147 
    148 
    149 btCollisionShape* btWorldImporter::convertCollisionShape(  btCollisionShapeData* shapeData  )
    150 {
    151 	btCollisionShape* shape = 0;
    152 
    153 	switch (shapeData->m_shapeType)
    154 		{
    155 	case STATIC_PLANE_PROXYTYPE:
    156 		{
    157 			btStaticPlaneShapeData* planeData = (btStaticPlaneShapeData*)shapeData;
    158 			btVector3 planeNormal,localScaling;
    159 			planeNormal.deSerializeFloat(planeData->m_planeNormal);
    160 			localScaling.deSerializeFloat(planeData->m_localScaling);
    161 			shape = createPlaneShape(planeNormal,planeData->m_planeConstant);
    162 			shape->setLocalScaling(localScaling);
    163 
    164 			break;
    165 		}
    166 	case SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE:
    167 		{
    168 			btScaledTriangleMeshShapeData* scaledMesh = (btScaledTriangleMeshShapeData*) shapeData;
    169 			btCollisionShapeData* colShapeData = (btCollisionShapeData*) &scaledMesh->m_trimeshShapeData;
    170 			colShapeData->m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE;
    171 			btCollisionShape* childShape = convertCollisionShape(colShapeData);
    172 			btBvhTriangleMeshShape* meshShape = (btBvhTriangleMeshShape*)childShape;
    173 			btVector3 localScaling;
    174 			localScaling.deSerializeFloat(scaledMesh->m_localScaling);
    175 
    176 			shape = createScaledTrangleMeshShape(meshShape, localScaling);
    177 			break;
    178 		}
    179 	case GIMPACT_SHAPE_PROXYTYPE:
    180 		{
    181 #ifdef USE_GIMPACT
    182 			btGImpactMeshShapeData* gimpactData = (btGImpactMeshShapeData*) shapeData;
    183 			if (gimpactData->m_gimpactSubType == CONST_GIMPACT_TRIMESH_SHAPE)
    184 			{
    185 				btStridingMeshInterfaceData* interfaceData = createStridingMeshInterfaceData(&gimpactData->m_meshInterface);
    186 				btTriangleIndexVertexArray* meshInterface = createMeshInterface(*interfaceData);
    187 
    188 
    189 				btGImpactMeshShape* gimpactShape = createGimpactShape(meshInterface);
    190 				btVector3 localScaling;
    191 				localScaling.deSerializeFloat(gimpactData->m_localScaling);
    192 				gimpactShape->setLocalScaling(localScaling);
    193 				gimpactShape->setMargin(btScalar(gimpactData->m_collisionMargin));
    194 				gimpactShape->updateBound();
    195 				shape = gimpactShape;
    196 			} else
    197 			{
    198 				printf("unsupported gimpact sub type\n");
    199 			}
    200 #endif//USE_GIMPACT
    201 			break;
    202 		}
    203 	//The btCapsuleShape* API has issue passing the margin/scaling/halfextents unmodified through the API
    204 	//so deal with this
    205 		case CAPSULE_SHAPE_PROXYTYPE:
    206 		{
    207 			btCapsuleShapeData* capData = (btCapsuleShapeData*)shapeData;
    208 
    209 
    210 			switch (capData->m_upAxis)
    211 			{
    212 			case 0:
    213 				{
    214 					shape = createCapsuleShapeX(1,1);
    215 					break;
    216 				}
    217 			case 1:
    218 				{
    219 					shape = createCapsuleShapeY(1,1);
    220 					break;
    221 				}
    222 			case 2:
    223 				{
    224 					shape = createCapsuleShapeZ(1,1);
    225 					break;
    226 				}
    227 			default:
    228 				{
    229 					printf("error: wrong up axis for btCapsuleShape\n");
    230 				}
    231 
    232 
    233 			};
    234 			if (shape)
    235 			{
    236 				btCapsuleShape* cap = (btCapsuleShape*) shape;
    237 				cap->deSerializeFloat(capData);
    238 			}
    239 			break;
    240 		}
    241 		case CYLINDER_SHAPE_PROXYTYPE:
    242 		case CONE_SHAPE_PROXYTYPE:
    243 		case BOX_SHAPE_PROXYTYPE:
    244 		case SPHERE_SHAPE_PROXYTYPE:
    245 		case MULTI_SPHERE_SHAPE_PROXYTYPE:
    246 		case CONVEX_HULL_SHAPE_PROXYTYPE:
    247 			{
    248 				btConvexInternalShapeData* bsd = (btConvexInternalShapeData*)shapeData;
    249 				btVector3 implicitShapeDimensions;
    250 				implicitShapeDimensions.deSerializeFloat(bsd->m_implicitShapeDimensions);
    251 				btVector3 localScaling;
    252 				localScaling.deSerializeFloat(bsd->m_localScaling);
    253 				btVector3 margin(bsd->m_collisionMargin,bsd->m_collisionMargin,bsd->m_collisionMargin);
    254 				switch (shapeData->m_shapeType)
    255 				{
    256 					case BOX_SHAPE_PROXYTYPE:
    257 						{
    258 							btBoxShape* box= (btBoxShape*)createBoxShape(implicitShapeDimensions/localScaling+margin);
    259 							//box->initializePolyhedralFeatures();
    260 							shape = box;
    261 
    262 							break;
    263 						}
    264 					case SPHERE_SHAPE_PROXYTYPE:
    265 						{
    266 							shape = createSphereShape(implicitShapeDimensions.getX());
    267 							break;
    268 						}
    269 
    270 					case CYLINDER_SHAPE_PROXYTYPE:
    271 						{
    272 							btCylinderShapeData* cylData = (btCylinderShapeData*) shapeData;
    273 							btVector3 halfExtents = implicitShapeDimensions+margin;
    274 							switch (cylData->m_upAxis)
    275 							{
    276 							case 0:
    277 								{
    278 									shape = createCylinderShapeX(halfExtents.getY(),halfExtents.getX());
    279 									break;
    280 								}
    281 							case 1:
    282 								{
    283 									shape = createCylinderShapeY(halfExtents.getX(),halfExtents.getY());
    284 									break;
    285 								}
    286 							case 2:
    287 								{
    288 									shape = createCylinderShapeZ(halfExtents.getX(),halfExtents.getZ());
    289 									break;
    290 								}
    291 							default:
    292 								{
    293 									printf("unknown Cylinder up axis\n");
    294 								}
    295 
    296 							};
    297 
    298 
    299 
    300 							break;
    301 						}
    302 					case CONE_SHAPE_PROXYTYPE:
    303 						{
    304 							btConeShapeData* conData = (btConeShapeData*) shapeData;
    305 							btVector3 halfExtents = implicitShapeDimensions;//+margin;
    306 							switch (conData->m_upIndex)
    307 							{
    308 							case 0:
    309 								{
    310 									shape = createConeShapeX(halfExtents.getY(),halfExtents.getX());
    311 									break;
    312 								}
    313 							case 1:
    314 								{
    315 									shape = createConeShapeY(halfExtents.getX(),halfExtents.getY());
    316 									break;
    317 								}
    318 							case 2:
    319 								{
    320 									shape = createConeShapeZ(halfExtents.getX(),halfExtents.getZ());
    321 									break;
    322 								}
    323 							default:
    324 								{
    325 									printf("unknown Cone up axis\n");
    326 								}
    327 
    328 							};
    329 
    330 
    331 
    332 							break;
    333 						}
    334 					case MULTI_SPHERE_SHAPE_PROXYTYPE:
    335 						{
    336 							btMultiSphereShapeData* mss = (btMultiSphereShapeData*)bsd;
    337 							int numSpheres = mss->m_localPositionArraySize;
    338 
    339 							btAlignedObjectArray<btVector3> tmpPos;
    340 							btAlignedObjectArray<btScalar> radii;
    341 							radii.resize(numSpheres);
    342 							tmpPos.resize(numSpheres);
    343 							int i;
    344 							for ( i=0;i<numSpheres;i++)
    345 							{
    346 								tmpPos[i].deSerializeFloat(mss->m_localPositionArrayPtr[i].m_pos);
    347 								radii[i] = mss->m_localPositionArrayPtr[i].m_radius;
    348 							}
    349 							shape = createMultiSphereShape(&tmpPos[0],&radii[0],numSpheres);
    350 							break;
    351 						}
    352 					case CONVEX_HULL_SHAPE_PROXYTYPE:
    353 						{
    354 						//	int sz = sizeof(btConvexHullShapeData);
    355 						//	int sz2 = sizeof(btConvexInternalShapeData);
    356 						//	int sz3 = sizeof(btCollisionShapeData);
    357 							btConvexHullShapeData* convexData = (btConvexHullShapeData*)bsd;
    358 							int numPoints = convexData->m_numUnscaledPoints;
    359 
    360 							btAlignedObjectArray<btVector3> tmpPoints;
    361 							tmpPoints.resize(numPoints);
    362 							int i;
    363 							for ( i=0;i<numPoints;i++)
    364 							{
    365 #ifdef BT_USE_DOUBLE_PRECISION
    366 							if (convexData->m_unscaledPointsDoublePtr)
    367 								tmpPoints[i].deSerialize(convexData->m_unscaledPointsDoublePtr[i]);
    368 							if (convexData->m_unscaledPointsFloatPtr)
    369 								tmpPoints[i].deSerializeFloat(convexData->m_unscaledPointsFloatPtr[i]);
    370 #else
    371 							if (convexData->m_unscaledPointsFloatPtr)
    372 								tmpPoints[i].deSerialize(convexData->m_unscaledPointsFloatPtr[i]);
    373 							if (convexData->m_unscaledPointsDoublePtr)
    374 								tmpPoints[i].deSerializeDouble(convexData->m_unscaledPointsDoublePtr[i]);
    375 #endif //BT_USE_DOUBLE_PRECISION
    376 							}
    377 							btConvexHullShape* hullShape = createConvexHullShape();
    378 							for (i=0;i<numPoints;i++)
    379 							{
    380 								hullShape->addPoint(tmpPoints[i]);
    381 							}
    382 							hullShape->setMargin(bsd->m_collisionMargin);
    383 							//hullShape->initializePolyhedralFeatures();
    384 							shape = hullShape;
    385 							break;
    386 						}
    387 					default:
    388 						{
    389 							printf("error: cannot create shape type (%d)\n",shapeData->m_shapeType);
    390 						}
    391 				}
    392 
    393 				if (shape)
    394 				{
    395 					shape->setMargin(bsd->m_collisionMargin);
    396 
    397 					btVector3 localScaling;
    398 					localScaling.deSerializeFloat(bsd->m_localScaling);
    399 					shape->setLocalScaling(localScaling);
    400 
    401 				}
    402 				break;
    403 			}
    404 		case TRIANGLE_MESH_SHAPE_PROXYTYPE:
    405 		{
    406 			btTriangleMeshShapeData* trimesh = (btTriangleMeshShapeData*)shapeData;
    407 			btStridingMeshInterfaceData* interfaceData = createStridingMeshInterfaceData(&trimesh->m_meshInterface);
    408 			btTriangleIndexVertexArray* meshInterface = createMeshInterface(*interfaceData);
    409 			if (!meshInterface->getNumSubParts())
    410 			{
    411 				return 0;
    412 			}
    413 
    414 			btVector3 scaling; scaling.deSerializeFloat(trimesh->m_meshInterface.m_scaling);
    415 			meshInterface->setScaling(scaling);
    416 
    417 
    418 			btOptimizedBvh* bvh = 0;
    419 #if 1
    420 			if (trimesh->m_quantizedFloatBvh)
    421 			{
    422 				btOptimizedBvh** bvhPtr = m_bvhMap.find(trimesh->m_quantizedFloatBvh);
    423 				if (bvhPtr && *bvhPtr)
    424 				{
    425 					bvh = *bvhPtr;
    426 				} else
    427 				{
    428 					bvh = createOptimizedBvh();
    429 					bvh->deSerializeFloat(*trimesh->m_quantizedFloatBvh);
    430 				}
    431 			}
    432 			if (trimesh->m_quantizedDoubleBvh)
    433 			{
    434 				btOptimizedBvh** bvhPtr = m_bvhMap.find(trimesh->m_quantizedDoubleBvh);
    435 				if (bvhPtr && *bvhPtr)
    436 				{
    437 					bvh = *bvhPtr;
    438 				} else
    439 				{
    440 					bvh = createOptimizedBvh();
    441 					bvh->deSerializeDouble(*trimesh->m_quantizedDoubleBvh);
    442 				}
    443 			}
    444 #endif
    445 
    446 
    447 			btBvhTriangleMeshShape* trimeshShape = createBvhTriangleMeshShape(meshInterface,bvh);
    448 			trimeshShape->setMargin(trimesh->m_collisionMargin);
    449 			shape = trimeshShape;
    450 
    451 			if (trimesh->m_triangleInfoMap)
    452 			{
    453 				btTriangleInfoMap* map = createTriangleInfoMap();
    454 				map->deSerialize(*trimesh->m_triangleInfoMap);
    455 				trimeshShape->setTriangleInfoMap(map);
    456 
    457 #ifdef USE_INTERNAL_EDGE_UTILITY
    458 				gContactAddedCallback = btAdjustInternalEdgeContactsCallback;
    459 #endif //USE_INTERNAL_EDGE_UTILITY
    460 
    461 			}
    462 
    463 			//printf("trimesh->m_collisionMargin=%f\n",trimesh->m_collisionMargin);
    464 			break;
    465 		}
    466 		case COMPOUND_SHAPE_PROXYTYPE:
    467 			{
    468 				btCompoundShapeData* compoundData = (btCompoundShapeData*)shapeData;
    469 				btCompoundShape* compoundShape = createCompoundShape();
    470 
    471 				btCompoundShapeChildData* childShapeDataArray = &compoundData->m_childShapePtr[0];
    472 
    473 
    474 				btAlignedObjectArray<btCollisionShape*> childShapes;
    475 				for (int i=0;i<compoundData->m_numChildShapes;i++)
    476 				{
    477 					btCompoundShapeChildData* ptr = &compoundData->m_childShapePtr[i];
    478 
    479 					btCollisionShapeData* cd = compoundData->m_childShapePtr[i].m_childShape;
    480 
    481 					btCollisionShape* childShape = convertCollisionShape(cd);
    482 					if (childShape)
    483 					{
    484 						btTransform localTransform;
    485 						localTransform.deSerializeFloat(compoundData->m_childShapePtr[i].m_transform);
    486 						compoundShape->addChildShape(localTransform,childShape);
    487 					} else
    488 					{
    489 #ifdef _DEBUG
    490 						printf("error: couldn't create childShape for compoundShape\n");
    491 #endif
    492 					}
    493 
    494 				}
    495 				shape = compoundShape;
    496 
    497 				break;
    498 			}
    499 		case SOFTBODY_SHAPE_PROXYTYPE:
    500 			{
    501 				return 0;
    502 			}
    503 		default:
    504 			{
    505 #ifdef _DEBUG
    506 				printf("unsupported shape type (%d)\n",shapeData->m_shapeType);
    507 #endif
    508 			}
    509 		}
    510 
    511 		return shape;
    512 
    513 }
    514 
    515 
    516 
    517 char* btWorldImporter::duplicateName(const char* name)
    518 {
    519 	if (name)
    520 	{
    521 		int l = (int)strlen(name);
    522 		char* newName = new char[l+1];
    523 		memcpy(newName,name,l);
    524 		newName[l] = 0;
    525 		m_allocatedNames.push_back(newName);
    526 		return newName;
    527 	}
    528 	return 0;
    529 }
    530 
    531 void	btWorldImporter::convertConstraintBackwardsCompatible281(btTypedConstraintData* constraintData, btRigidBody* rbA, btRigidBody* rbB, int fileVersion)
    532 {
    533 
    534 	btTypedConstraint* constraint = 0;
    535 
    536 		switch (constraintData->m_objectType)
    537 		{
    538 		case POINT2POINT_CONSTRAINT_TYPE:
    539 			{
    540 				btPoint2PointConstraintDoubleData* p2pData = (btPoint2PointConstraintDoubleData*)constraintData;
    541 				if (rbA && rbB)
    542 				{
    543 					btVector3 pivotInA,pivotInB;
    544 					pivotInA.deSerializeDouble(p2pData->m_pivotInA);
    545 					pivotInB.deSerializeDouble(p2pData->m_pivotInB);
    546 					constraint = createPoint2PointConstraint(*rbA,*rbB,pivotInA,pivotInB);
    547 				} else
    548 				{
    549 					btVector3 pivotInA;
    550 					pivotInA.deSerializeDouble(p2pData->m_pivotInA);
    551 					constraint = createPoint2PointConstraint(*rbA,pivotInA);
    552 				}
    553 				break;
    554 			}
    555 		case HINGE_CONSTRAINT_TYPE:
    556 			{
    557 				btHingeConstraint* hinge = 0;
    558 
    559 				btHingeConstraintDoubleData* hingeData = (btHingeConstraintDoubleData*)constraintData;
    560 				if (rbA&& rbB)
    561 				{
    562 					btTransform rbAFrame,rbBFrame;
    563 					rbAFrame.deSerializeDouble(hingeData->m_rbAFrame);
    564 					rbBFrame.deSerializeDouble(hingeData->m_rbBFrame);
    565 					hinge = createHingeConstraint(*rbA,*rbB,rbAFrame,rbBFrame,hingeData->m_useReferenceFrameA!=0);
    566 				} else
    567 				{
    568 					btTransform rbAFrame;
    569 					rbAFrame.deSerializeDouble(hingeData->m_rbAFrame);
    570 					hinge = createHingeConstraint(*rbA,rbAFrame,hingeData->m_useReferenceFrameA!=0);
    571 				}
    572 				if (hingeData->m_enableAngularMotor)
    573 				{
    574 					hinge->enableAngularMotor(true,(btScalar)hingeData->m_motorTargetVelocity,(btScalar)hingeData->m_maxMotorImpulse);
    575 				}
    576 				hinge->setAngularOnly(hingeData->m_angularOnly!=0);
    577 				hinge->setLimit(btScalar(hingeData->m_lowerLimit),btScalar(hingeData->m_upperLimit),btScalar(hingeData->m_limitSoftness),btScalar(hingeData->m_biasFactor),btScalar(hingeData->m_relaxationFactor));
    578 
    579 				constraint = hinge;
    580 				break;
    581 
    582 			}
    583 		case CONETWIST_CONSTRAINT_TYPE:
    584 			{
    585 				btConeTwistConstraintData* coneData = (btConeTwistConstraintData*)constraintData;
    586 				btConeTwistConstraint* coneTwist = 0;
    587 
    588 				if (rbA&& rbB)
    589 				{
    590 					btTransform rbAFrame,rbBFrame;
    591 					rbAFrame.deSerializeFloat(coneData->m_rbAFrame);
    592 					rbBFrame.deSerializeFloat(coneData->m_rbBFrame);
    593 					coneTwist = createConeTwistConstraint(*rbA,*rbB,rbAFrame,rbBFrame);
    594 				} else
    595 				{
    596 					btTransform rbAFrame;
    597 					rbAFrame.deSerializeFloat(coneData->m_rbAFrame);
    598 					coneTwist = createConeTwistConstraint(*rbA,rbAFrame);
    599 				}
    600 				coneTwist->setLimit((btScalar)coneData->m_swingSpan1,(btScalar)coneData->m_swingSpan2,(btScalar)coneData->m_twistSpan,(btScalar)coneData->m_limitSoftness,
    601 					(btScalar)coneData->m_biasFactor,(btScalar)coneData->m_relaxationFactor);
    602 				coneTwist->setDamping((btScalar)coneData->m_damping);
    603 
    604 				constraint = coneTwist;
    605 				break;
    606 			}
    607 
    608 		case D6_SPRING_CONSTRAINT_TYPE:
    609 			{
    610 
    611 				btGeneric6DofSpringConstraintData* dofData = (btGeneric6DofSpringConstraintData*)constraintData;
    612 			//	int sz = sizeof(btGeneric6DofSpringConstraintData);
    613 				btGeneric6DofSpringConstraint* dof = 0;
    614 
    615 				if (rbA && rbB)
    616 				{
    617 					btTransform rbAFrame,rbBFrame;
    618 					rbAFrame.deSerializeFloat(dofData->m_6dofData.m_rbAFrame);
    619 					rbBFrame.deSerializeFloat(dofData->m_6dofData.m_rbBFrame);
    620 					dof = createGeneric6DofSpringConstraint(*rbA,*rbB,rbAFrame,rbBFrame,dofData->m_6dofData.m_useLinearReferenceFrameA!=0);
    621 				} else
    622 				{
    623 					printf("Error in btWorldImporter::createGeneric6DofSpringConstraint: requires rbA && rbB\n");
    624 				}
    625 
    626 				if (dof)
    627 				{
    628 					btVector3 angLowerLimit,angUpperLimit, linLowerLimit,linUpperlimit;
    629 					angLowerLimit.deSerializeFloat(dofData->m_6dofData.m_angularLowerLimit);
    630 					angUpperLimit.deSerializeFloat(dofData->m_6dofData.m_angularUpperLimit);
    631 					linLowerLimit.deSerializeFloat(dofData->m_6dofData.m_linearLowerLimit);
    632 					linUpperlimit.deSerializeFloat(dofData->m_6dofData.m_linearUpperLimit);
    633 
    634 					angLowerLimit.setW(0.f);
    635 					dof->setAngularLowerLimit(angLowerLimit);
    636 					dof->setAngularUpperLimit(angUpperLimit);
    637 					dof->setLinearLowerLimit(linLowerLimit);
    638 					dof->setLinearUpperLimit(linUpperlimit);
    639 
    640 					int i;
    641 					if (fileVersion>280)
    642 					{
    643 						for (i=0;i<6;i++)
    644 						{
    645 							dof->setStiffness(i,(btScalar)dofData->m_springStiffness[i]);
    646 							dof->setEquilibriumPoint(i,(btScalar)dofData->m_equilibriumPoint[i]);
    647 							dof->enableSpring(i,dofData->m_springEnabled[i]!=0);
    648 							dof->setDamping(i,(btScalar)dofData->m_springDamping[i]);
    649 						}
    650 					}
    651 				}
    652 
    653 				constraint = dof;
    654 				break;
    655 
    656 			}
    657 		case D6_CONSTRAINT_TYPE:
    658 			{
    659 				btGeneric6DofConstraintData* dofData = (btGeneric6DofConstraintData*)constraintData;
    660 				btGeneric6DofConstraint* dof = 0;
    661 
    662 				if (rbA&& rbB)
    663 				{
    664 					btTransform rbAFrame,rbBFrame;
    665 					rbAFrame.deSerializeFloat(dofData->m_rbAFrame);
    666 					rbBFrame.deSerializeFloat(dofData->m_rbBFrame);
    667 					dof = createGeneric6DofConstraint(*rbA,*rbB,rbAFrame,rbBFrame,dofData->m_useLinearReferenceFrameA!=0);
    668 				} else
    669 				{
    670 					if (rbB)
    671 					{
    672 						btTransform rbBFrame;
    673 						rbBFrame.deSerializeFloat(dofData->m_rbBFrame);
    674 						dof = createGeneric6DofConstraint(*rbB,rbBFrame,dofData->m_useLinearReferenceFrameA!=0);
    675 					} else
    676 					{
    677 						printf("Error in btWorldImporter::createGeneric6DofConstraint: missing rbB\n");
    678 					}
    679 				}
    680 
    681 				if (dof)
    682 				{
    683 					btVector3 angLowerLimit,angUpperLimit, linLowerLimit,linUpperlimit;
    684 					angLowerLimit.deSerializeFloat(dofData->m_angularLowerLimit);
    685 					angUpperLimit.deSerializeFloat(dofData->m_angularUpperLimit);
    686 					linLowerLimit.deSerializeFloat(dofData->m_linearLowerLimit);
    687 					linUpperlimit.deSerializeFloat(dofData->m_linearUpperLimit);
    688 
    689 					dof->setAngularLowerLimit(angLowerLimit);
    690 					dof->setAngularUpperLimit(angUpperLimit);
    691 					dof->setLinearLowerLimit(linLowerLimit);
    692 					dof->setLinearUpperLimit(linUpperlimit);
    693 				}
    694 
    695 				constraint = dof;
    696 				break;
    697 			}
    698 		case SLIDER_CONSTRAINT_TYPE:
    699 			{
    700 				btSliderConstraintData* sliderData = (btSliderConstraintData*)constraintData;
    701 				btSliderConstraint* slider = 0;
    702 				if (rbA&& rbB)
    703 				{
    704 					btTransform rbAFrame,rbBFrame;
    705 					rbAFrame.deSerializeFloat(sliderData->m_rbAFrame);
    706 					rbBFrame.deSerializeFloat(sliderData->m_rbBFrame);
    707 					slider = createSliderConstraint(*rbA,*rbB,rbAFrame,rbBFrame,sliderData->m_useLinearReferenceFrameA!=0);
    708 				} else
    709 				{
    710 					btTransform rbBFrame;
    711 					rbBFrame.deSerializeFloat(sliderData->m_rbBFrame);
    712 					slider = createSliderConstraint(*rbB,rbBFrame,sliderData->m_useLinearReferenceFrameA!=0);
    713 				}
    714 				slider->setLowerLinLimit((btScalar)sliderData->m_linearLowerLimit);
    715 				slider->setUpperLinLimit((btScalar)sliderData->m_linearUpperLimit);
    716 				slider->setLowerAngLimit((btScalar)sliderData->m_angularLowerLimit);
    717 				slider->setUpperAngLimit((btScalar)sliderData->m_angularUpperLimit);
    718 				slider->setUseFrameOffset(sliderData->m_useOffsetForConstraintFrame!=0);
    719 				constraint = slider;
    720 				break;
    721 			}
    722 
    723 		default:
    724 			{
    725 				printf("unknown constraint type\n");
    726 			}
    727 		};
    728 
    729 		if (constraint)
    730 		{
    731 			constraint->setDbgDrawSize((btScalar)constraintData->m_dbgDrawSize);
    732 			///those fields didn't exist and set to zero for pre-280 versions, so do a check here
    733 			if (fileVersion>=280)
    734 			{
    735 				constraint->setBreakingImpulseThreshold((btScalar)constraintData->m_breakingImpulseThreshold);
    736 				constraint->setEnabled(constraintData->m_isEnabled!=0);
    737 				constraint->setOverrideNumSolverIterations(constraintData->m_overrideNumSolverIterations);
    738 			}
    739 
    740 			if (constraintData->m_name)
    741 			{
    742 				char* newname = duplicateName(constraintData->m_name);
    743 				m_nameConstraintMap.insert(newname,constraint);
    744 				m_objectNameMap.insert(constraint,newname);
    745 			}
    746 			if(m_dynamicsWorld)
    747 				m_dynamicsWorld->addConstraint(constraint,constraintData->m_disableCollisionsBetweenLinkedBodies!=0);
    748 		}
    749 
    750 }
    751 
    752 void	btWorldImporter::convertConstraintFloat(btTypedConstraintFloatData* constraintData, btRigidBody* rbA, btRigidBody* rbB, int fileVersion)
    753 {
    754 	btTypedConstraint* constraint = 0;
    755 
    756 		switch (constraintData->m_objectType)
    757 		{
    758 		case POINT2POINT_CONSTRAINT_TYPE:
    759 			{
    760 				btPoint2PointConstraintFloatData* p2pData = (btPoint2PointConstraintFloatData*)constraintData;
    761 				if (rbA&& rbB)
    762 				{
    763 					btVector3 pivotInA,pivotInB;
    764 					pivotInA.deSerializeFloat(p2pData->m_pivotInA);
    765 					pivotInB.deSerializeFloat(p2pData->m_pivotInB);
    766 					constraint = createPoint2PointConstraint(*rbA,*rbB,pivotInA,pivotInB);
    767 
    768 				} else
    769 				{
    770 					btVector3 pivotInA;
    771 					pivotInA.deSerializeFloat(p2pData->m_pivotInA);
    772 					constraint = createPoint2PointConstraint(*rbA,pivotInA);
    773 				}
    774 				break;
    775 			}
    776 		case HINGE_CONSTRAINT_TYPE:
    777 			{
    778 				btHingeConstraint* hinge = 0;
    779 				btHingeConstraintFloatData* hingeData = (btHingeConstraintFloatData*)constraintData;
    780 				if (rbA&& rbB)
    781 				{
    782 					btTransform rbAFrame,rbBFrame;
    783 					rbAFrame.deSerializeFloat(hingeData->m_rbAFrame);
    784 					rbBFrame.deSerializeFloat(hingeData->m_rbBFrame);
    785 					hinge = createHingeConstraint(*rbA,*rbB,rbAFrame,rbBFrame,hingeData->m_useReferenceFrameA!=0);
    786 				} else
    787 				{
    788 					btTransform rbAFrame;
    789 					rbAFrame.deSerializeFloat(hingeData->m_rbAFrame);
    790 					hinge = createHingeConstraint(*rbA,rbAFrame,hingeData->m_useReferenceFrameA!=0);
    791 				}
    792 				if (hingeData->m_enableAngularMotor)
    793 				{
    794 					hinge->enableAngularMotor(true,hingeData->m_motorTargetVelocity,hingeData->m_maxMotorImpulse);
    795 				}
    796 				hinge->setAngularOnly(hingeData->m_angularOnly!=0);
    797 				hinge->setLimit(btScalar(hingeData->m_lowerLimit),btScalar(hingeData->m_upperLimit),btScalar(hingeData->m_limitSoftness),btScalar(hingeData->m_biasFactor),btScalar(hingeData->m_relaxationFactor));
    798 
    799 				constraint = hinge;
    800 				break;
    801 
    802 			}
    803 		case CONETWIST_CONSTRAINT_TYPE:
    804 			{
    805 				btConeTwistConstraintData* coneData = (btConeTwistConstraintData*)constraintData;
    806 				btConeTwistConstraint* coneTwist = 0;
    807 
    808 				if (rbA&& rbB)
    809 				{
    810 					btTransform rbAFrame,rbBFrame;
    811 					rbAFrame.deSerializeFloat(coneData->m_rbAFrame);
    812 					rbBFrame.deSerializeFloat(coneData->m_rbBFrame);
    813 					coneTwist = createConeTwistConstraint(*rbA,*rbB,rbAFrame,rbBFrame);
    814 				} else
    815 				{
    816 					btTransform rbAFrame;
    817 					rbAFrame.deSerializeFloat(coneData->m_rbAFrame);
    818 					coneTwist = createConeTwistConstraint(*rbA,rbAFrame);
    819 				}
    820 				coneTwist->setLimit(coneData->m_swingSpan1,coneData->m_swingSpan2,coneData->m_twistSpan,coneData->m_limitSoftness,coneData->m_biasFactor,coneData->m_relaxationFactor);
    821 				coneTwist->setDamping(coneData->m_damping);
    822 
    823 				constraint = coneTwist;
    824 				break;
    825 			}
    826 
    827 		case D6_SPRING_CONSTRAINT_TYPE:
    828 			{
    829 
    830 				btGeneric6DofSpringConstraintData* dofData = (btGeneric6DofSpringConstraintData*)constraintData;
    831 			//	int sz = sizeof(btGeneric6DofSpringConstraintData);
    832 				btGeneric6DofSpringConstraint* dof = 0;
    833 
    834 				if (rbA && rbB)
    835 				{
    836 					btTransform rbAFrame,rbBFrame;
    837 					rbAFrame.deSerializeFloat(dofData->m_6dofData.m_rbAFrame);
    838 					rbBFrame.deSerializeFloat(dofData->m_6dofData.m_rbBFrame);
    839 					dof = createGeneric6DofSpringConstraint(*rbA,*rbB,rbAFrame,rbBFrame,dofData->m_6dofData.m_useLinearReferenceFrameA!=0);
    840 				} else
    841 				{
    842 					printf("Error in btWorldImporter::createGeneric6DofSpringConstraint: requires rbA && rbB\n");
    843 				}
    844 
    845 				if (dof)
    846 				{
    847 					btVector3 angLowerLimit,angUpperLimit, linLowerLimit,linUpperlimit;
    848 					angLowerLimit.deSerializeFloat(dofData->m_6dofData.m_angularLowerLimit);
    849 					angUpperLimit.deSerializeFloat(dofData->m_6dofData.m_angularUpperLimit);
    850 					linLowerLimit.deSerializeFloat(dofData->m_6dofData.m_linearLowerLimit);
    851 					linUpperlimit.deSerializeFloat(dofData->m_6dofData.m_linearUpperLimit);
    852 
    853 					angLowerLimit.setW(0.f);
    854 					dof->setAngularLowerLimit(angLowerLimit);
    855 					dof->setAngularUpperLimit(angUpperLimit);
    856 					dof->setLinearLowerLimit(linLowerLimit);
    857 					dof->setLinearUpperLimit(linUpperlimit);
    858 
    859 					int i;
    860 					if (fileVersion>280)
    861 					{
    862 						for (i=0;i<6;i++)
    863 						{
    864 							dof->setStiffness(i,dofData->m_springStiffness[i]);
    865 							dof->setEquilibriumPoint(i,dofData->m_equilibriumPoint[i]);
    866 							dof->enableSpring(i,dofData->m_springEnabled[i]!=0);
    867 							dof->setDamping(i,dofData->m_springDamping[i]);
    868 						}
    869 					}
    870 				}
    871 
    872 				constraint = dof;
    873 				break;
    874 			}
    875 		case D6_CONSTRAINT_TYPE:
    876 			{
    877 				btGeneric6DofConstraintData* dofData = (btGeneric6DofConstraintData*)constraintData;
    878 				btGeneric6DofConstraint* dof = 0;
    879 
    880 				if (rbA&& rbB)
    881 				{
    882 					btTransform rbAFrame,rbBFrame;
    883 					rbAFrame.deSerializeFloat(dofData->m_rbAFrame);
    884 					rbBFrame.deSerializeFloat(dofData->m_rbBFrame);
    885 					dof = createGeneric6DofConstraint(*rbA,*rbB,rbAFrame,rbBFrame,dofData->m_useLinearReferenceFrameA!=0);
    886 				} else
    887 				{
    888 					if (rbB)
    889 					{
    890 						btTransform rbBFrame;
    891 						rbBFrame.deSerializeFloat(dofData->m_rbBFrame);
    892 						dof = createGeneric6DofConstraint(*rbB,rbBFrame,dofData->m_useLinearReferenceFrameA!=0);
    893 					} else
    894 					{
    895 						printf("Error in btWorldImporter::createGeneric6DofConstraint: missing rbB\n");
    896 					}
    897 				}
    898 
    899 				if (dof)
    900 				{
    901 					btVector3 angLowerLimit,angUpperLimit, linLowerLimit,linUpperlimit;
    902 					angLowerLimit.deSerializeFloat(dofData->m_angularLowerLimit);
    903 					angUpperLimit.deSerializeFloat(dofData->m_angularUpperLimit);
    904 					linLowerLimit.deSerializeFloat(dofData->m_linearLowerLimit);
    905 					linUpperlimit.deSerializeFloat(dofData->m_linearUpperLimit);
    906 
    907 					dof->setAngularLowerLimit(angLowerLimit);
    908 					dof->setAngularUpperLimit(angUpperLimit);
    909 					dof->setLinearLowerLimit(linLowerLimit);
    910 					dof->setLinearUpperLimit(linUpperlimit);
    911 				}
    912 
    913 				constraint = dof;
    914 				break;
    915 			}
    916 		case SLIDER_CONSTRAINT_TYPE:
    917 			{
    918 				btSliderConstraintData* sliderData = (btSliderConstraintData*)constraintData;
    919 				btSliderConstraint* slider = 0;
    920 				if (rbA&& rbB)
    921 				{
    922 					btTransform rbAFrame,rbBFrame;
    923 					rbAFrame.deSerializeFloat(sliderData->m_rbAFrame);
    924 					rbBFrame.deSerializeFloat(sliderData->m_rbBFrame);
    925 					slider = createSliderConstraint(*rbA,*rbB,rbAFrame,rbBFrame,sliderData->m_useLinearReferenceFrameA!=0);
    926 				} else
    927 				{
    928 					btTransform rbBFrame;
    929 					rbBFrame.deSerializeFloat(sliderData->m_rbBFrame);
    930 					slider = createSliderConstraint(*rbB,rbBFrame,sliderData->m_useLinearReferenceFrameA!=0);
    931 				}
    932 				slider->setLowerLinLimit(sliderData->m_linearLowerLimit);
    933 				slider->setUpperLinLimit(sliderData->m_linearUpperLimit);
    934 				slider->setLowerAngLimit(sliderData->m_angularLowerLimit);
    935 				slider->setUpperAngLimit(sliderData->m_angularUpperLimit);
    936 				slider->setUseFrameOffset(sliderData->m_useOffsetForConstraintFrame!=0);
    937 				constraint = slider;
    938 				break;
    939 			}
    940 		case GEAR_CONSTRAINT_TYPE:
    941 			{
    942 				btGearConstraintFloatData* gearData = (btGearConstraintFloatData*) constraintData;
    943 				btGearConstraint* gear = 0;
    944 				if (rbA&&rbB)
    945 				{
    946 					btVector3 axisInA,axisInB;
    947 					axisInA.deSerializeFloat(gearData->m_axisInA);
    948 					axisInB.deSerializeFloat(gearData->m_axisInB);
    949 					gear = createGearConstraint(*rbA, *rbB, axisInA,axisInB, gearData->m_ratio);
    950 				} else
    951 				{
    952 					btAssert(0);
    953 					//perhaps a gear against a 'fixed' body, while the 'fixed' body is not serialized?
    954 					//btGearConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& axisInA,const btVector3& axisInB, btScalar ratio=1.f);
    955 				}
    956 				constraint = gear;
    957 				break;
    958 			}
    959 		case D6_SPRING_2_CONSTRAINT_TYPE:
    960 			{
    961 
    962 			btGeneric6DofSpring2ConstraintData* dofData = (btGeneric6DofSpring2ConstraintData*)constraintData;
    963 
    964 			btGeneric6DofSpring2Constraint* dof = 0;
    965 
    966 			if (rbA && rbB)
    967 			{
    968 				btTransform rbAFrame,rbBFrame;
    969 				rbAFrame.deSerializeFloat(dofData->m_rbAFrame);
    970 				rbBFrame.deSerializeFloat(dofData->m_rbBFrame);
    971 				dof = createGeneric6DofSpring2Constraint(*rbA,*rbB,rbAFrame,rbBFrame, dofData->m_rotateOrder);
    972 			} else
    973 			{
    974 				printf("Error in btWorldImporter::createGeneric6DofSpring2Constraint: requires rbA && rbB\n");
    975 			}
    976 
    977 			if (dof)
    978 			{
    979 				btVector3 angLowerLimit,angUpperLimit, linLowerLimit,linUpperlimit;
    980 				angLowerLimit.deSerializeFloat(dofData->m_angularLowerLimit);
    981 				angUpperLimit.deSerializeFloat(dofData->m_angularUpperLimit);
    982 				linLowerLimit.deSerializeFloat(dofData->m_linearLowerLimit);
    983 				linUpperlimit.deSerializeFloat(dofData->m_linearUpperLimit);
    984 
    985 				angLowerLimit.setW(0.f);
    986 				dof->setAngularLowerLimit(angLowerLimit);
    987 				dof->setAngularUpperLimit(angUpperLimit);
    988 				dof->setLinearLowerLimit(linLowerLimit);
    989 				dof->setLinearUpperLimit(linUpperlimit);
    990 
    991 				int i;
    992 				if (fileVersion>280)
    993 				{
    994 					//6-dof: 3 linear followed by 3 angular
    995 					for (i=0;i<3;i++)
    996 					{
    997 						dof->setStiffness(i,dofData->m_linearSpringStiffness.m_floats[i],dofData->m_linearSpringStiffnessLimited[i]!=0);
    998 						dof->setEquilibriumPoint(i,dofData->m_linearEquilibriumPoint.m_floats[i]);
    999 						dof->enableSpring(i,dofData->m_linearEnableSpring[i]!=0);
   1000 						dof->setDamping(i,dofData->m_linearSpringDamping.m_floats[i],dofData->m_linearSpringDampingLimited[i]);
   1001 					}
   1002 					for (i=0;i<3;i++)
   1003 					{
   1004 						dof->setStiffness(i+3,dofData->m_angularSpringStiffness.m_floats[i],dofData->m_angularSpringStiffnessLimited[i]);
   1005 						dof->setEquilibriumPoint(i+3,dofData->m_angularEquilibriumPoint.m_floats[i]);
   1006 						dof->enableSpring(i+3,dofData->m_angularEnableSpring[i]!=0);
   1007 						dof->setDamping(i+3,dofData->m_angularSpringDamping.m_floats[i],dofData->m_angularSpringDampingLimited[i]);
   1008 					}
   1009 
   1010 				}
   1011 			}
   1012 
   1013 			constraint = dof;
   1014 			break;
   1015 
   1016 			}
   1017 			case FIXED_CONSTRAINT_TYPE:
   1018 			{
   1019 
   1020 				btGeneric6DofSpring2Constraint* dof = 0;
   1021 				if (rbA && rbB)
   1022 				{
   1023 					btTransform rbAFrame,rbBFrame;
   1024 					//compute a shared world frame, and compute frameInA, frameInB relative to this
   1025 					btTransform sharedFrame;
   1026 					sharedFrame.setIdentity();
   1027 					btVector3 centerPos = btScalar(0.5)*(rbA->getWorldTransform().getOrigin()+
   1028 											rbB->getWorldTransform().getOrigin());
   1029 					sharedFrame.setOrigin(centerPos);
   1030 					rbAFrame = rbA->getWorldTransform().inverse()*sharedFrame;
   1031 					rbBFrame = rbB->getWorldTransform().inverse()*sharedFrame;
   1032 
   1033 
   1034 					dof = createGeneric6DofSpring2Constraint(*rbA,*rbB,rbAFrame,rbBFrame, RO_XYZ);
   1035 					dof->setLinearUpperLimit(btVector3(0,0,0));
   1036 					dof->setLinearLowerLimit(btVector3(0,0,0));
   1037 					dof->setAngularUpperLimit(btVector3(0,0,0));
   1038 					dof->setAngularLowerLimit(btVector3(0,0,0));
   1039 
   1040 				} else
   1041 				{
   1042 					printf("Error in btWorldImporter::createGeneric6DofSpring2Constraint: requires rbA && rbB\n");
   1043 				}
   1044 
   1045 				constraint = dof;
   1046 				break;
   1047 			}
   1048 		default:
   1049 			{
   1050 				printf("unknown constraint type\n");
   1051 			}
   1052 		};
   1053 
   1054 		if (constraint)
   1055 		{
   1056 			constraint->setDbgDrawSize(constraintData->m_dbgDrawSize);
   1057 			///those fields didn't exist and set to zero for pre-280 versions, so do a check here
   1058 			if (fileVersion>=280)
   1059 			{
   1060 				constraint->setBreakingImpulseThreshold(constraintData->m_breakingImpulseThreshold);
   1061 				constraint->setEnabled(constraintData->m_isEnabled!=0);
   1062 				constraint->setOverrideNumSolverIterations(constraintData->m_overrideNumSolverIterations);
   1063 			}
   1064 
   1065 			if (constraintData->m_name)
   1066 			{
   1067 				char* newname = duplicateName(constraintData->m_name);
   1068 				m_nameConstraintMap.insert(newname,constraint);
   1069 				m_objectNameMap.insert(constraint,newname);
   1070 			}
   1071 			if(m_dynamicsWorld)
   1072 				m_dynamicsWorld->addConstraint(constraint,constraintData->m_disableCollisionsBetweenLinkedBodies!=0);
   1073 		}
   1074 
   1075 
   1076 }
   1077 
   1078 
   1079 
   1080 void	btWorldImporter::convertConstraintDouble(btTypedConstraintDoubleData* constraintData, btRigidBody* rbA, btRigidBody* rbB, int fileVersion)
   1081 {
   1082 	btTypedConstraint* constraint = 0;
   1083 
   1084 		switch (constraintData->m_objectType)
   1085 		{
   1086 		case POINT2POINT_CONSTRAINT_TYPE:
   1087 			{
   1088 				btPoint2PointConstraintDoubleData2* p2pData = (btPoint2PointConstraintDoubleData2*)constraintData;
   1089 				if (rbA && rbB)
   1090 				{
   1091 					btVector3 pivotInA,pivotInB;
   1092 					pivotInA.deSerializeDouble(p2pData->m_pivotInA);
   1093 					pivotInB.deSerializeDouble(p2pData->m_pivotInB);
   1094 					constraint = createPoint2PointConstraint(*rbA,*rbB,pivotInA,pivotInB);
   1095 				} else
   1096 				{
   1097 					btVector3 pivotInA;
   1098 					pivotInA.deSerializeDouble(p2pData->m_pivotInA);
   1099 					constraint = createPoint2PointConstraint(*rbA,pivotInA);
   1100 				}
   1101 				break;
   1102 			}
   1103 		case HINGE_CONSTRAINT_TYPE:
   1104 			{
   1105 				btHingeConstraint* hinge = 0;
   1106 
   1107 				btHingeConstraintDoubleData2* hingeData = (btHingeConstraintDoubleData2*)constraintData;
   1108 				if (rbA&& rbB)
   1109 				{
   1110 					btTransform rbAFrame,rbBFrame;
   1111 					rbAFrame.deSerializeDouble(hingeData->m_rbAFrame);
   1112 					rbBFrame.deSerializeDouble(hingeData->m_rbBFrame);
   1113 					hinge = createHingeConstraint(*rbA,*rbB,rbAFrame,rbBFrame,hingeData->m_useReferenceFrameA!=0);
   1114 				} else
   1115 				{
   1116 					btTransform rbAFrame;
   1117 					rbAFrame.deSerializeDouble(hingeData->m_rbAFrame);
   1118 					hinge = createHingeConstraint(*rbA,rbAFrame,hingeData->m_useReferenceFrameA!=0);
   1119 				}
   1120 				if (hingeData->m_enableAngularMotor)
   1121 				{
   1122 					hinge->enableAngularMotor(true,(btScalar)hingeData->m_motorTargetVelocity,(btScalar)hingeData->m_maxMotorImpulse);
   1123 				}
   1124 				hinge->setAngularOnly(hingeData->m_angularOnly!=0);
   1125 				hinge->setLimit(btScalar(hingeData->m_lowerLimit),btScalar(hingeData->m_upperLimit),btScalar(hingeData->m_limitSoftness),btScalar(hingeData->m_biasFactor),btScalar(hingeData->m_relaxationFactor));
   1126 
   1127 				constraint = hinge;
   1128 				break;
   1129 
   1130 			}
   1131 		case CONETWIST_CONSTRAINT_TYPE:
   1132 			{
   1133 				btConeTwistConstraintDoubleData* coneData = (btConeTwistConstraintDoubleData*)constraintData;
   1134 				btConeTwistConstraint* coneTwist = 0;
   1135 
   1136 				if (rbA&& rbB)
   1137 				{
   1138 					btTransform rbAFrame,rbBFrame;
   1139 					rbAFrame.deSerializeDouble(coneData->m_rbAFrame);
   1140 					rbBFrame.deSerializeDouble(coneData->m_rbBFrame);
   1141 					coneTwist = createConeTwistConstraint(*rbA,*rbB,rbAFrame,rbBFrame);
   1142 				} else
   1143 				{
   1144 					btTransform rbAFrame;
   1145 					rbAFrame.deSerializeDouble(coneData->m_rbAFrame);
   1146 					coneTwist = createConeTwistConstraint(*rbA,rbAFrame);
   1147 				}
   1148 				coneTwist->setLimit((btScalar)coneData->m_swingSpan1,(btScalar)coneData->m_swingSpan2,(btScalar)coneData->m_twistSpan,(btScalar)coneData->m_limitSoftness,
   1149 					(btScalar)coneData->m_biasFactor,(btScalar)coneData->m_relaxationFactor);
   1150 				coneTwist->setDamping((btScalar)coneData->m_damping);
   1151 
   1152 				constraint = coneTwist;
   1153 				break;
   1154 			}
   1155 
   1156 		case D6_SPRING_CONSTRAINT_TYPE:
   1157 			{
   1158 
   1159 				btGeneric6DofSpringConstraintDoubleData2* dofData = (btGeneric6DofSpringConstraintDoubleData2*)constraintData;
   1160 			//	int sz = sizeof(btGeneric6DofSpringConstraintData);
   1161 				btGeneric6DofSpringConstraint* dof = 0;
   1162 
   1163 				if (rbA && rbB)
   1164 				{
   1165 					btTransform rbAFrame,rbBFrame;
   1166 					rbAFrame.deSerializeDouble(dofData->m_6dofData.m_rbAFrame);
   1167 					rbBFrame.deSerializeDouble(dofData->m_6dofData.m_rbBFrame);
   1168 					dof = createGeneric6DofSpringConstraint(*rbA,*rbB,rbAFrame,rbBFrame,dofData->m_6dofData.m_useLinearReferenceFrameA!=0);
   1169 				} else
   1170 				{
   1171 					printf("Error in btWorldImporter::createGeneric6DofSpringConstraint: requires rbA && rbB\n");
   1172 				}
   1173 
   1174 				if (dof)
   1175 				{
   1176 					btVector3 angLowerLimit,angUpperLimit, linLowerLimit,linUpperlimit;
   1177 					angLowerLimit.deSerializeDouble(dofData->m_6dofData.m_angularLowerLimit);
   1178 					angUpperLimit.deSerializeDouble(dofData->m_6dofData.m_angularUpperLimit);
   1179 					linLowerLimit.deSerializeDouble(dofData->m_6dofData.m_linearLowerLimit);
   1180 					linUpperlimit.deSerializeDouble(dofData->m_6dofData.m_linearUpperLimit);
   1181 
   1182 					angLowerLimit.setW(0.f);
   1183 					dof->setAngularLowerLimit(angLowerLimit);
   1184 					dof->setAngularUpperLimit(angUpperLimit);
   1185 					dof->setLinearLowerLimit(linLowerLimit);
   1186 					dof->setLinearUpperLimit(linUpperlimit);
   1187 
   1188 					int i;
   1189 					if (fileVersion>280)
   1190 					{
   1191 						for (i=0;i<6;i++)
   1192 						{
   1193 							dof->setStiffness(i,(btScalar)dofData->m_springStiffness[i]);
   1194 							dof->setEquilibriumPoint(i,(btScalar)dofData->m_equilibriumPoint[i]);
   1195 							dof->enableSpring(i,dofData->m_springEnabled[i]!=0);
   1196 							dof->setDamping(i,(btScalar)dofData->m_springDamping[i]);
   1197 						}
   1198 					}
   1199 				}
   1200 
   1201 				constraint = dof;
   1202 				break;
   1203 			}
   1204 		case D6_CONSTRAINT_TYPE:
   1205 			{
   1206 				btGeneric6DofConstraintDoubleData2* dofData = (btGeneric6DofConstraintDoubleData2*)constraintData;
   1207 				btGeneric6DofConstraint* dof = 0;
   1208 
   1209 				if (rbA&& rbB)
   1210 				{
   1211 					btTransform rbAFrame,rbBFrame;
   1212 					rbAFrame.deSerializeDouble(dofData->m_rbAFrame);
   1213 					rbBFrame.deSerializeDouble(dofData->m_rbBFrame);
   1214 					dof = createGeneric6DofConstraint(*rbA,*rbB,rbAFrame,rbBFrame,dofData->m_useLinearReferenceFrameA!=0);
   1215 				} else
   1216 				{
   1217 					if (rbB)
   1218 					{
   1219 						btTransform rbBFrame;
   1220 						rbBFrame.deSerializeDouble(dofData->m_rbBFrame);
   1221 						dof = createGeneric6DofConstraint(*rbB,rbBFrame,dofData->m_useLinearReferenceFrameA!=0);
   1222 					} else
   1223 					{
   1224 						printf("Error in btWorldImporter::createGeneric6DofConstraint: missing rbB\n");
   1225 					}
   1226 				}
   1227 
   1228 				if (dof)
   1229 				{
   1230 					btVector3 angLowerLimit,angUpperLimit, linLowerLimit,linUpperlimit;
   1231 					angLowerLimit.deSerializeDouble(dofData->m_angularLowerLimit);
   1232 					angUpperLimit.deSerializeDouble(dofData->m_angularUpperLimit);
   1233 					linLowerLimit.deSerializeDouble(dofData->m_linearLowerLimit);
   1234 					linUpperlimit.deSerializeDouble(dofData->m_linearUpperLimit);
   1235 
   1236 					dof->setAngularLowerLimit(angLowerLimit);
   1237 					dof->setAngularUpperLimit(angUpperLimit);
   1238 					dof->setLinearLowerLimit(linLowerLimit);
   1239 					dof->setLinearUpperLimit(linUpperlimit);
   1240 				}
   1241 
   1242 				constraint = dof;
   1243 				break;
   1244 			}
   1245 		case SLIDER_CONSTRAINT_TYPE:
   1246 			{
   1247 				btSliderConstraintDoubleData* sliderData = (btSliderConstraintDoubleData*)constraintData;
   1248 				btSliderConstraint* slider = 0;
   1249 				if (rbA&& rbB)
   1250 				{
   1251 					btTransform rbAFrame,rbBFrame;
   1252 					rbAFrame.deSerializeDouble(sliderData->m_rbAFrame);
   1253 					rbBFrame.deSerializeDouble(sliderData->m_rbBFrame);
   1254 					slider = createSliderConstraint(*rbA,*rbB,rbAFrame,rbBFrame,sliderData->m_useLinearReferenceFrameA!=0);
   1255 				} else
   1256 				{
   1257 					btTransform rbBFrame;
   1258 					rbBFrame.deSerializeDouble(sliderData->m_rbBFrame);
   1259 					slider = createSliderConstraint(*rbB,rbBFrame,sliderData->m_useLinearReferenceFrameA!=0);
   1260 				}
   1261 				slider->setLowerLinLimit((btScalar)sliderData->m_linearLowerLimit);
   1262 				slider->setUpperLinLimit((btScalar)sliderData->m_linearUpperLimit);
   1263 				slider->setLowerAngLimit((btScalar)sliderData->m_angularLowerLimit);
   1264 				slider->setUpperAngLimit((btScalar)sliderData->m_angularUpperLimit);
   1265 				slider->setUseFrameOffset(sliderData->m_useOffsetForConstraintFrame!=0);
   1266 				constraint = slider;
   1267 				break;
   1268 			}
   1269 		case GEAR_CONSTRAINT_TYPE:
   1270 			{
   1271 				btGearConstraintDoubleData* gearData = (btGearConstraintDoubleData*) constraintData;
   1272 				btGearConstraint* gear = 0;
   1273 				if (rbA&&rbB)
   1274 				{
   1275 					btVector3 axisInA,axisInB;
   1276 					axisInA.deSerializeDouble(gearData->m_axisInA);
   1277 					axisInB.deSerializeDouble(gearData->m_axisInB);
   1278 					gear = createGearConstraint(*rbA, *rbB, axisInA,axisInB, gearData->m_ratio);
   1279 				} else
   1280 				{
   1281 					btAssert(0);
   1282 					//perhaps a gear against a 'fixed' body, while the 'fixed' body is not serialized?
   1283 					//btGearConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& axisInA,const btVector3& axisInB, btScalar ratio=1.f);
   1284 				}
   1285 				constraint = gear;
   1286 				break;
   1287 			}
   1288 
   1289 		case D6_SPRING_2_CONSTRAINT_TYPE:
   1290 			{
   1291 
   1292 			btGeneric6DofSpring2ConstraintDoubleData2* dofData = (btGeneric6DofSpring2ConstraintDoubleData2*)constraintData;
   1293 
   1294 			btGeneric6DofSpring2Constraint* dof = 0;
   1295 
   1296 			if (rbA && rbB)
   1297 			{
   1298 				btTransform rbAFrame,rbBFrame;
   1299 				rbAFrame.deSerializeDouble(dofData->m_rbAFrame);
   1300 				rbBFrame.deSerializeDouble(dofData->m_rbBFrame);
   1301 				dof = createGeneric6DofSpring2Constraint(*rbA,*rbB,rbAFrame,rbBFrame, dofData->m_rotateOrder);
   1302 			} else
   1303 			{
   1304 				printf("Error in btWorldImporter::createGeneric6DofSpring2Constraint: requires rbA && rbB\n");
   1305 			}
   1306 
   1307 			if (dof)
   1308 			{
   1309 				btVector3 angLowerLimit,angUpperLimit, linLowerLimit,linUpperlimit;
   1310 				angLowerLimit.deSerializeDouble(dofData->m_angularLowerLimit);
   1311 				angUpperLimit.deSerializeDouble(dofData->m_angularUpperLimit);
   1312 				linLowerLimit.deSerializeDouble(dofData->m_linearLowerLimit);
   1313 				linUpperlimit.deSerializeDouble(dofData->m_linearUpperLimit);
   1314 
   1315 				angLowerLimit.setW(0.f);
   1316 				dof->setAngularLowerLimit(angLowerLimit);
   1317 				dof->setAngularUpperLimit(angUpperLimit);
   1318 				dof->setLinearLowerLimit(linLowerLimit);
   1319 				dof->setLinearUpperLimit(linUpperlimit);
   1320 
   1321 				int i;
   1322 				if (fileVersion>280)
   1323 				{
   1324 					//6-dof: 3 linear followed by 3 angular
   1325 					for (i=0;i<3;i++)
   1326 					{
   1327 						dof->setStiffness(i,dofData->m_linearSpringStiffness.m_floats[i],dofData->m_linearSpringStiffnessLimited[i]);
   1328 						dof->setEquilibriumPoint(i,dofData->m_linearEquilibriumPoint.m_floats[i]);
   1329 						dof->enableSpring(i,dofData->m_linearEnableSpring[i]!=0);
   1330 						dof->setDamping(i,dofData->m_linearSpringDamping.m_floats[i],dofData->m_linearSpringDampingLimited[i]);
   1331 					}
   1332 					for (i=0;i<3;i++)
   1333 					{
   1334 						dof->setStiffness(i+3,dofData->m_angularSpringStiffness.m_floats[i],dofData->m_angularSpringStiffnessLimited[i]);
   1335 						dof->setEquilibriumPoint(i+3,dofData->m_angularEquilibriumPoint.m_floats[i]);
   1336 						dof->enableSpring(i+3,dofData->m_angularEnableSpring[i]!=0);
   1337 						dof->setDamping(i+3,dofData->m_angularSpringDamping.m_floats[i],dofData->m_angularSpringDampingLimited[i]);
   1338 					}
   1339 
   1340 				}
   1341 			}
   1342 
   1343 			constraint = dof;
   1344 			break;
   1345 
   1346 			}
   1347 			case FIXED_CONSTRAINT_TYPE:
   1348 			{
   1349 
   1350 				btGeneric6DofSpring2Constraint* dof = 0;
   1351 				if (rbA && rbB)
   1352 				{
   1353 					btTransform rbAFrame,rbBFrame;
   1354 					//compute a shared world frame, and compute frameInA, frameInB relative to this
   1355 					btTransform sharedFrame;
   1356 					sharedFrame.setIdentity();
   1357 					btVector3 centerPos = btScalar(0.5)*(rbA->getWorldTransform().getOrigin()+
   1358 														 rbB->getWorldTransform().getOrigin());
   1359 					sharedFrame.setOrigin(centerPos);
   1360 					rbAFrame = rbA->getWorldTransform().inverse()*sharedFrame;
   1361 					rbBFrame = rbB->getWorldTransform().inverse()*sharedFrame;
   1362 
   1363 
   1364 					dof = createGeneric6DofSpring2Constraint(*rbA,*rbB,rbAFrame,rbBFrame, RO_XYZ);
   1365 					dof->setLinearUpperLimit(btVector3(0,0,0));
   1366 					dof->setLinearLowerLimit(btVector3(0,0,0));
   1367 					dof->setAngularUpperLimit(btVector3(0,0,0));
   1368 					dof->setAngularLowerLimit(btVector3(0,0,0));
   1369 
   1370 				} else
   1371 				{
   1372 					printf("Error in btWorldImporter::createGeneric6DofSpring2Constraint: requires rbA && rbB\n");
   1373 				}
   1374 
   1375 				constraint = dof;
   1376 				break;
   1377 			}
   1378 
   1379 		default:
   1380 			{
   1381 				printf("unknown constraint type\n");
   1382 			}
   1383 		};
   1384 
   1385 		if (constraint)
   1386 		{
   1387 			constraint->setDbgDrawSize((btScalar)constraintData->m_dbgDrawSize);
   1388 			///those fields didn't exist and set to zero for pre-280 versions, so do a check here
   1389 			if (fileVersion>=280)
   1390 			{
   1391 				constraint->setBreakingImpulseThreshold((btScalar)constraintData->m_breakingImpulseThreshold);
   1392 				constraint->setEnabled(constraintData->m_isEnabled!=0);
   1393 				constraint->setOverrideNumSolverIterations(constraintData->m_overrideNumSolverIterations);
   1394 			}
   1395 
   1396 			if (constraintData->m_name)
   1397 			{
   1398 				char* newname = duplicateName(constraintData->m_name);
   1399 				m_nameConstraintMap.insert(newname,constraint);
   1400 				m_objectNameMap.insert(constraint,newname);
   1401 			}
   1402 			if(m_dynamicsWorld)
   1403 				m_dynamicsWorld->addConstraint(constraint,constraintData->m_disableCollisionsBetweenLinkedBodies!=0);
   1404 		}
   1405 
   1406 
   1407 }
   1408 
   1409 
   1410 
   1411 
   1412 
   1413 
   1414 
   1415 
   1416 
   1417 
   1418 btTriangleIndexVertexArray* btWorldImporter::createMeshInterface(btStridingMeshInterfaceData&  meshData)
   1419 {
   1420 	btTriangleIndexVertexArray* meshInterface = createTriangleMeshContainer();
   1421 
   1422 	for (int i=0;i<meshData.m_numMeshParts;i++)
   1423 	{
   1424 		btIndexedMesh meshPart;
   1425 		meshPart.m_numTriangles = meshData.m_meshPartsPtr[i].m_numTriangles;
   1426 		meshPart.m_numVertices = meshData.m_meshPartsPtr[i].m_numVertices;
   1427 
   1428 
   1429 		if (meshData.m_meshPartsPtr[i].m_indices32)
   1430 		{
   1431 			meshPart.m_indexType = PHY_INTEGER;
   1432 			meshPart.m_triangleIndexStride = 3*sizeof(int);
   1433 			int* indexArray = (int*)btAlignedAlloc(sizeof(int)*3*meshPart.m_numTriangles,16);
   1434 			m_indexArrays.push_back(indexArray);
   1435 			for (int j=0;j<3*meshPart.m_numTriangles;j++)
   1436 			{
   1437 				indexArray[j] = meshData.m_meshPartsPtr[i].m_indices32[j].m_value;
   1438 			}
   1439 			meshPart.m_triangleIndexBase = (const unsigned char*)indexArray;
   1440 		} else
   1441 		{
   1442 			if (meshData.m_meshPartsPtr[i].m_3indices16)
   1443 			{
   1444 				meshPart.m_indexType = PHY_SHORT;
   1445 				meshPart.m_triangleIndexStride = sizeof(short int)*3;//sizeof(btShortIntIndexTripletData);
   1446 
   1447 				short int* indexArray = (short int*)btAlignedAlloc(sizeof(short int)*3*meshPart.m_numTriangles,16);
   1448 				m_shortIndexArrays.push_back(indexArray);
   1449 
   1450 				for (int j=0;j<meshPart.m_numTriangles;j++)
   1451 				{
   1452 					indexArray[3*j] = meshData.m_meshPartsPtr[i].m_3indices16[j].m_values[0];
   1453 					indexArray[3*j+1] = meshData.m_meshPartsPtr[i].m_3indices16[j].m_values[1];
   1454 					indexArray[3*j+2] = meshData.m_meshPartsPtr[i].m_3indices16[j].m_values[2];
   1455 				}
   1456 
   1457 				meshPart.m_triangleIndexBase = (const unsigned char*)indexArray;
   1458 			}
   1459 			if (meshData.m_meshPartsPtr[i].m_indices16)
   1460 			{
   1461 				meshPart.m_indexType = PHY_SHORT;
   1462 				meshPart.m_triangleIndexStride = 3*sizeof(short int);
   1463 				short int* indexArray = (short int*)btAlignedAlloc(sizeof(short int)*3*meshPart.m_numTriangles,16);
   1464 				m_shortIndexArrays.push_back(indexArray);
   1465 				for (int j=0;j<3*meshPart.m_numTriangles;j++)
   1466 				{
   1467 					indexArray[j] = meshData.m_meshPartsPtr[i].m_indices16[j].m_value;
   1468 				}
   1469 
   1470 				meshPart.m_triangleIndexBase = (const unsigned char*)indexArray;
   1471 			}
   1472 
   1473 			if (meshData.m_meshPartsPtr[i].m_3indices8)
   1474 			{
   1475 				meshPart.m_indexType = PHY_UCHAR;
   1476 				meshPart.m_triangleIndexStride = sizeof(unsigned char)*3;
   1477 
   1478 				unsigned char* indexArray = (unsigned char*)btAlignedAlloc(sizeof(unsigned char)*3*meshPart.m_numTriangles,16);
   1479 				m_charIndexArrays.push_back(indexArray);
   1480 
   1481 				for (int j=0;j<meshPart.m_numTriangles;j++)
   1482 				{
   1483 					indexArray[3*j] = meshData.m_meshPartsPtr[i].m_3indices8[j].m_values[0];
   1484 					indexArray[3*j+1] = meshData.m_meshPartsPtr[i].m_3indices8[j].m_values[1];
   1485 					indexArray[3*j+2] = meshData.m_meshPartsPtr[i].m_3indices8[j].m_values[2];
   1486 				}
   1487 
   1488 				meshPart.m_triangleIndexBase = (const unsigned char*)indexArray;
   1489 			}
   1490 		}
   1491 
   1492 		if (meshData.m_meshPartsPtr[i].m_vertices3f)
   1493 		{
   1494 			meshPart.m_vertexType = PHY_FLOAT;
   1495 			meshPart.m_vertexStride = sizeof(btVector3FloatData);
   1496 			btVector3FloatData* vertices = (btVector3FloatData*) btAlignedAlloc(sizeof(btVector3FloatData)*meshPart.m_numVertices,16);
   1497 			m_floatVertexArrays.push_back(vertices);
   1498 
   1499 			for (int j=0;j<meshPart.m_numVertices;j++)
   1500 			{
   1501 				vertices[j].m_floats[0] = meshData.m_meshPartsPtr[i].m_vertices3f[j].m_floats[0];
   1502 				vertices[j].m_floats[1] = meshData.m_meshPartsPtr[i].m_vertices3f[j].m_floats[1];
   1503 				vertices[j].m_floats[2] = meshData.m_meshPartsPtr[i].m_vertices3f[j].m_floats[2];
   1504 				vertices[j].m_floats[3] = meshData.m_meshPartsPtr[i].m_vertices3f[j].m_floats[3];
   1505 			}
   1506 			meshPart.m_vertexBase = (const unsigned char*)vertices;
   1507 		} else
   1508 		{
   1509 			meshPart.m_vertexType = PHY_DOUBLE;
   1510 			meshPart.m_vertexStride = sizeof(btVector3DoubleData);
   1511 
   1512 
   1513 			btVector3DoubleData* vertices = (btVector3DoubleData*) btAlignedAlloc(sizeof(btVector3DoubleData)*meshPart.m_numVertices,16);
   1514 			m_doubleVertexArrays.push_back(vertices);
   1515 
   1516 			for (int j=0;j<meshPart.m_numVertices;j++)
   1517 			{
   1518 				vertices[j].m_floats[0] = meshData.m_meshPartsPtr[i].m_vertices3d[j].m_floats[0];
   1519 				vertices[j].m_floats[1] = meshData.m_meshPartsPtr[i].m_vertices3d[j].m_floats[1];
   1520 				vertices[j].m_floats[2] = meshData.m_meshPartsPtr[i].m_vertices3d[j].m_floats[2];
   1521 				vertices[j].m_floats[3] = meshData.m_meshPartsPtr[i].m_vertices3d[j].m_floats[3];
   1522 			}
   1523 			meshPart.m_vertexBase = (const unsigned char*)vertices;
   1524 		}
   1525 
   1526 		if (meshPart.m_triangleIndexBase && meshPart.m_vertexBase)
   1527 		{
   1528 			meshInterface->addIndexedMesh(meshPart,meshPart.m_indexType);
   1529 		}
   1530 	}
   1531 
   1532 	return meshInterface;
   1533 }
   1534 
   1535 
   1536 btStridingMeshInterfaceData* btWorldImporter::createStridingMeshInterfaceData(btStridingMeshInterfaceData* interfaceData)
   1537 {
   1538 	//create a new btStridingMeshInterfaceData that is an exact copy of shapedata and store it in the WorldImporter
   1539 	btStridingMeshInterfaceData* newData = new btStridingMeshInterfaceData;
   1540 
   1541 	newData->m_scaling = interfaceData->m_scaling;
   1542 	newData->m_numMeshParts = interfaceData->m_numMeshParts;
   1543 	newData->m_meshPartsPtr = new btMeshPartData[newData->m_numMeshParts];
   1544 
   1545 	for(int i = 0;i < newData->m_numMeshParts;i++)
   1546 	{
   1547 		btMeshPartData* curPart = &interfaceData->m_meshPartsPtr[i];
   1548 		btMeshPartData* curNewPart = &newData->m_meshPartsPtr[i];
   1549 
   1550 		curNewPart->m_numTriangles = curPart->m_numTriangles;
   1551 		curNewPart->m_numVertices = curPart->m_numVertices;
   1552 
   1553 		if(curPart->m_vertices3f)
   1554 		{
   1555 			curNewPart->m_vertices3f = new btVector3FloatData[curNewPart->m_numVertices];
   1556 			memcpy(curNewPart->m_vertices3f,curPart->m_vertices3f,sizeof(btVector3FloatData) * curNewPart->m_numVertices);
   1557 		}
   1558 		else
   1559 			curNewPart->m_vertices3f = NULL;
   1560 
   1561 		if(curPart->m_vertices3d)
   1562 		{
   1563 			curNewPart->m_vertices3d = new btVector3DoubleData[curNewPart->m_numVertices];
   1564 			memcpy(curNewPart->m_vertices3d,curPart->m_vertices3d,sizeof(btVector3DoubleData) * curNewPart->m_numVertices);
   1565 		}
   1566 		else
   1567 			curNewPart->m_vertices3d = NULL;
   1568 
   1569 		int numIndices = curNewPart->m_numTriangles * 3;
   1570 		///the m_3indices8 was not initialized in some Bullet versions, this can cause crashes at loading time
   1571 		///we catch it by only dealing with m_3indices8 if none of the other indices are initialized
   1572 		bool uninitialized3indices8Workaround =false;
   1573 
   1574 		if(curPart->m_indices32)
   1575 		{
   1576 			uninitialized3indices8Workaround=true;
   1577 			curNewPart->m_indices32 = new btIntIndexData[numIndices];
   1578 			memcpy(curNewPart->m_indices32,curPart->m_indices32,sizeof(btIntIndexData) * numIndices);
   1579 		}
   1580 		else
   1581 			curNewPart->m_indices32 = NULL;
   1582 
   1583 		if(curPart->m_3indices16)
   1584 		{
   1585 			uninitialized3indices8Workaround=true;
   1586 			curNewPart->m_3indices16 = new btShortIntIndexTripletData[curNewPart->m_numTriangles];
   1587 			memcpy(curNewPart->m_3indices16,curPart->m_3indices16,sizeof(btShortIntIndexTripletData) * curNewPart->m_numTriangles);
   1588 		}
   1589 		else
   1590 			curNewPart->m_3indices16 = NULL;
   1591 
   1592 		if(curPart->m_indices16)
   1593 		{
   1594 			uninitialized3indices8Workaround=true;
   1595 			curNewPart->m_indices16 = new btShortIntIndexData[numIndices];
   1596 			memcpy(curNewPart->m_indices16,curPart->m_indices16,sizeof(btShortIntIndexData) * numIndices);
   1597 		}
   1598 		else
   1599 			curNewPart->m_indices16 = NULL;
   1600 
   1601 		if(!uninitialized3indices8Workaround && curPart->m_3indices8)
   1602 		{
   1603 			curNewPart->m_3indices8 = new btCharIndexTripletData[curNewPart->m_numTriangles];
   1604 			memcpy(curNewPart->m_3indices8,curPart->m_3indices8,sizeof(btCharIndexTripletData) * curNewPart->m_numTriangles);
   1605 		}
   1606 		else
   1607 			curNewPart->m_3indices8 = NULL;
   1608 
   1609 	}
   1610 
   1611 	m_allocatedbtStridingMeshInterfaceDatas.push_back(newData);
   1612 
   1613 	return(newData);
   1614 }
   1615 
   1616 #ifdef USE_INTERNAL_EDGE_UTILITY
   1617 extern ContactAddedCallback		gContactAddedCallback;
   1618 
   1619 static bool btAdjustInternalEdgeContactsCallback(btManifoldPoint& cp,	const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1)
   1620 {
   1621 
   1622 	btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1);
   1623 		//btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_BACKFACE_MODE);
   1624 		//btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_DOUBLE_SIDED+BT_TRIANGLE_CONCAVE_DOUBLE_SIDED);
   1625 	return true;
   1626 }
   1627 #endif //USE_INTERNAL_EDGE_UTILITY
   1628 
   1629 
   1630 
   1631 
   1632 btCollisionObject* btWorldImporter::createCollisionObject(const btTransform& startTransform,btCollisionShape* shape, const char* bodyName)
   1633 {
   1634 	return createRigidBody(false,0,startTransform,shape,bodyName);
   1635 }
   1636 
   1637 void	btWorldImporter::setDynamicsWorldInfo(const btVector3& gravity, const btContactSolverInfo& solverInfo)
   1638 {
   1639 	if (m_dynamicsWorld)
   1640 	{
   1641 		m_dynamicsWorld->setGravity(gravity);
   1642 		m_dynamicsWorld->getSolverInfo() = solverInfo;
   1643 	}
   1644 
   1645 }
   1646 
   1647 btRigidBody*  btWorldImporter::createRigidBody(bool isDynamic, btScalar mass, const btTransform& startTransform,btCollisionShape* shape,const char* bodyName)
   1648 {
   1649 	btVector3 localInertia;
   1650 	localInertia.setZero();
   1651 
   1652 	if (mass)
   1653 		shape->calculateLocalInertia(mass,localInertia);
   1654 
   1655 	btRigidBody* body = new btRigidBody(mass,0,shape,localInertia);
   1656 	body->setWorldTransform(startTransform);
   1657 
   1658 	if (m_dynamicsWorld)
   1659 		m_dynamicsWorld->addRigidBody(body);
   1660 
   1661 	if (bodyName)
   1662 	{
   1663 		char* newname = duplicateName(bodyName);
   1664 		m_objectNameMap.insert(body,newname);
   1665 		m_nameBodyMap.insert(newname,body);
   1666 	}
   1667 	m_allocatedRigidBodies.push_back(body);
   1668 	return body;
   1669 
   1670 }
   1671 
   1672 btCollisionShape* btWorldImporter::createPlaneShape(const btVector3& planeNormal,btScalar planeConstant)
   1673 {
   1674 	btStaticPlaneShape* shape = new btStaticPlaneShape(planeNormal,planeConstant);
   1675 	m_allocatedCollisionShapes.push_back(shape);
   1676 	return shape;
   1677 }
   1678 btCollisionShape* btWorldImporter::createBoxShape(const btVector3& halfExtents)
   1679 {
   1680 	btBoxShape* shape = new btBoxShape(halfExtents);
   1681 	m_allocatedCollisionShapes.push_back(shape);
   1682 	return shape;
   1683 }
   1684 btCollisionShape* btWorldImporter::createSphereShape(btScalar radius)
   1685 {
   1686 	btSphereShape* shape = new btSphereShape(radius);
   1687 	m_allocatedCollisionShapes.push_back(shape);
   1688 	return shape;
   1689 }
   1690 
   1691 
   1692 btCollisionShape* btWorldImporter::createCapsuleShapeX(btScalar radius, btScalar height)
   1693 {
   1694 	btCapsuleShapeX* shape = new btCapsuleShapeX(radius,height);
   1695 	m_allocatedCollisionShapes.push_back(shape);
   1696 	return shape;
   1697 }
   1698 
   1699 btCollisionShape* btWorldImporter::createCapsuleShapeY(btScalar radius, btScalar height)
   1700 {
   1701 	btCapsuleShape* shape = new btCapsuleShape(radius,height);
   1702 	m_allocatedCollisionShapes.push_back(shape);
   1703 	return shape;
   1704 }
   1705 
   1706 btCollisionShape* btWorldImporter::createCapsuleShapeZ(btScalar radius, btScalar height)
   1707 {
   1708 	btCapsuleShapeZ* shape = new btCapsuleShapeZ(radius,height);
   1709 	m_allocatedCollisionShapes.push_back(shape);
   1710 	return shape;
   1711 }
   1712 
   1713 btCollisionShape* btWorldImporter::createCylinderShapeX(btScalar radius,btScalar height)
   1714 {
   1715 	btCylinderShapeX* shape = new btCylinderShapeX(btVector3(height,radius,radius));
   1716 	m_allocatedCollisionShapes.push_back(shape);
   1717 	return shape;
   1718 }
   1719 
   1720 btCollisionShape* btWorldImporter::createCylinderShapeY(btScalar radius,btScalar height)
   1721 {
   1722 	btCylinderShape* shape = new btCylinderShape(btVector3(radius,height,radius));
   1723 	m_allocatedCollisionShapes.push_back(shape);
   1724 	return shape;
   1725 }
   1726 
   1727 btCollisionShape* btWorldImporter::createCylinderShapeZ(btScalar radius,btScalar height)
   1728 {
   1729 	btCylinderShapeZ* shape = new btCylinderShapeZ(btVector3(radius,radius,height));
   1730 	m_allocatedCollisionShapes.push_back(shape);
   1731 	return shape;
   1732 }
   1733 
   1734 btCollisionShape* btWorldImporter::createConeShapeX(btScalar radius,btScalar height)
   1735 {
   1736 	btConeShapeX* shape = new btConeShapeX(radius,height);
   1737 	m_allocatedCollisionShapes.push_back(shape);
   1738 	return shape;
   1739 }
   1740 
   1741 btCollisionShape* btWorldImporter::createConeShapeY(btScalar radius,btScalar height)
   1742 {
   1743 	btConeShape* shape = new btConeShape(radius,height);
   1744 	m_allocatedCollisionShapes.push_back(shape);
   1745 	return shape;
   1746 }
   1747 
   1748 btCollisionShape* btWorldImporter::createConeShapeZ(btScalar radius,btScalar height)
   1749 {
   1750 	btConeShapeZ* shape = new btConeShapeZ(radius,height);
   1751 	m_allocatedCollisionShapes.push_back(shape);
   1752 	return shape;
   1753 }
   1754 
   1755 btTriangleIndexVertexArray*	btWorldImporter::createTriangleMeshContainer()
   1756 {
   1757 	btTriangleIndexVertexArray* in = new btTriangleIndexVertexArray();
   1758 	m_allocatedTriangleIndexArrays.push_back(in);
   1759 	return in;
   1760 }
   1761 
   1762 btOptimizedBvh*	btWorldImporter::createOptimizedBvh()
   1763 {
   1764 	btOptimizedBvh* bvh = new btOptimizedBvh();
   1765 	m_allocatedBvhs.push_back(bvh);
   1766 	return bvh;
   1767 }
   1768 
   1769 
   1770 btTriangleInfoMap* btWorldImporter::createTriangleInfoMap()
   1771 {
   1772 	btTriangleInfoMap* tim = new btTriangleInfoMap();
   1773 	m_allocatedTriangleInfoMaps.push_back(tim);
   1774 	return tim;
   1775 }
   1776 
   1777 btBvhTriangleMeshShape* btWorldImporter::createBvhTriangleMeshShape(btStridingMeshInterface* trimesh, btOptimizedBvh* bvh)
   1778 {
   1779 	if (bvh)
   1780 	{
   1781 		btBvhTriangleMeshShape* bvhTriMesh = new btBvhTriangleMeshShape(trimesh,bvh->isQuantized(), false);
   1782 		bvhTriMesh->setOptimizedBvh(bvh);
   1783 		m_allocatedCollisionShapes.push_back(bvhTriMesh);
   1784 		return bvhTriMesh;
   1785 	}
   1786 
   1787 	btBvhTriangleMeshShape* ts = new btBvhTriangleMeshShape(trimesh,true);
   1788 	m_allocatedCollisionShapes.push_back(ts);
   1789 	return ts;
   1790 
   1791 }
   1792 btCollisionShape* btWorldImporter::createConvexTriangleMeshShape(btStridingMeshInterface* trimesh)
   1793 {
   1794 	return 0;
   1795 }
   1796 btGImpactMeshShape* btWorldImporter::createGimpactShape(btStridingMeshInterface* trimesh)
   1797 {
   1798 #ifdef USE_GIMPACT
   1799 	btGImpactMeshShape* shape = new btGImpactMeshShape(trimesh);
   1800 	m_allocatedCollisionShapes.push_back(shape);
   1801 	return shape;
   1802 #else
   1803 	return 0;
   1804 #endif
   1805 
   1806 }
   1807 btConvexHullShape* btWorldImporter::createConvexHullShape()
   1808 {
   1809 	btConvexHullShape* shape = new btConvexHullShape();
   1810 	m_allocatedCollisionShapes.push_back(shape);
   1811 	return shape;
   1812 }
   1813 
   1814 btCompoundShape* btWorldImporter::createCompoundShape()
   1815 {
   1816 	btCompoundShape* shape = new btCompoundShape();
   1817 	m_allocatedCollisionShapes.push_back(shape);
   1818 	return shape;
   1819 }
   1820 
   1821 
   1822 btScaledBvhTriangleMeshShape* btWorldImporter::createScaledTrangleMeshShape(btBvhTriangleMeshShape* meshShape,const btVector3& localScaling)
   1823 {
   1824 	btScaledBvhTriangleMeshShape* shape = new btScaledBvhTriangleMeshShape(meshShape,localScaling);
   1825 	m_allocatedCollisionShapes.push_back(shape);
   1826 	return shape;
   1827 }
   1828 
   1829 btMultiSphereShape* btWorldImporter::createMultiSphereShape(const btVector3* positions,const btScalar* radi,int numSpheres)
   1830 {
   1831 	btMultiSphereShape* shape = new btMultiSphereShape(positions, radi, numSpheres);
   1832 	m_allocatedCollisionShapes.push_back(shape);
   1833 	return shape;
   1834 }
   1835 
   1836 btRigidBody& btWorldImporter::getFixedBody()
   1837 {
   1838 	static btRigidBody s_fixed(0, 0,0);
   1839 	s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.)));
   1840 	return s_fixed;
   1841 }
   1842 
   1843 btPoint2PointConstraint* btWorldImporter::createPoint2PointConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB)
   1844 {
   1845 	btPoint2PointConstraint* p2p = new btPoint2PointConstraint(rbA,rbB,pivotInA,pivotInB);
   1846 	m_allocatedConstraints.push_back(p2p);
   1847 	return p2p;
   1848 }
   1849 
   1850 btPoint2PointConstraint* btWorldImporter::createPoint2PointConstraint(btRigidBody& rbA,const btVector3& pivotInA)
   1851 {
   1852 	btPoint2PointConstraint* p2p = new btPoint2PointConstraint(rbA,pivotInA);
   1853 	m_allocatedConstraints.push_back(p2p);
   1854 	return p2p;
   1855 }
   1856 
   1857 
   1858 btHingeConstraint* btWorldImporter::createHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA)
   1859 {
   1860 	btHingeConstraint* hinge = new btHingeConstraint(rbA,rbB,rbAFrame,rbBFrame,useReferenceFrameA);
   1861 	m_allocatedConstraints.push_back(hinge);
   1862 	return hinge;
   1863 }
   1864 
   1865 btHingeConstraint* btWorldImporter::createHingeConstraint(btRigidBody& rbA,const btTransform& rbAFrame, bool useReferenceFrameA)
   1866 {
   1867 	btHingeConstraint* hinge = new btHingeConstraint(rbA,rbAFrame,useReferenceFrameA);
   1868 	m_allocatedConstraints.push_back(hinge);
   1869 	return hinge;
   1870 }
   1871 
   1872 btConeTwistConstraint* btWorldImporter::createConeTwistConstraint(btRigidBody& rbA,btRigidBody& rbB,const btTransform& rbAFrame, const btTransform& rbBFrame)
   1873 {
   1874 	btConeTwistConstraint* cone = new btConeTwistConstraint(rbA,rbB,rbAFrame,rbBFrame);
   1875 	m_allocatedConstraints.push_back(cone);
   1876 	return cone;
   1877 }
   1878 
   1879 btConeTwistConstraint* btWorldImporter::createConeTwistConstraint(btRigidBody& rbA,const btTransform& rbAFrame)
   1880 {
   1881 	btConeTwistConstraint* cone = new btConeTwistConstraint(rbA,rbAFrame);
   1882 	m_allocatedConstraints.push_back(cone);
   1883 	return cone;
   1884 }
   1885 
   1886 
   1887 btGeneric6DofConstraint* btWorldImporter::createGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA)
   1888 {
   1889 	btGeneric6DofConstraint* dof = new btGeneric6DofConstraint(rbA,rbB,frameInA,frameInB,useLinearReferenceFrameA);
   1890 	m_allocatedConstraints.push_back(dof);
   1891 	return dof;
   1892 }
   1893 
   1894 btGeneric6DofConstraint* btWorldImporter::createGeneric6DofConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB)
   1895 {
   1896 	btGeneric6DofConstraint* dof =  new btGeneric6DofConstraint(rbB,frameInB,useLinearReferenceFrameB);
   1897 	m_allocatedConstraints.push_back(dof);
   1898 	return dof;
   1899 }
   1900 
   1901 btGeneric6DofSpring2Constraint* btWorldImporter::createGeneric6DofSpring2Constraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, int rotateOrder)
   1902 {
   1903 	btGeneric6DofSpring2Constraint* dof = new btGeneric6DofSpring2Constraint(rbA,rbB,frameInA,frameInB, (RotateOrder)rotateOrder);
   1904 	m_allocatedConstraints.push_back(dof);
   1905 	return dof;
   1906 }
   1907 
   1908 
   1909 
   1910 btGeneric6DofSpringConstraint* btWorldImporter::createGeneric6DofSpringConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA)
   1911 {
   1912 	btGeneric6DofSpringConstraint* dof = new btGeneric6DofSpringConstraint(rbA,rbB,frameInA,frameInB,useLinearReferenceFrameA);
   1913 	m_allocatedConstraints.push_back(dof);
   1914 	return dof;
   1915 }
   1916 
   1917 
   1918 btSliderConstraint* btWorldImporter::createSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA)
   1919 {
   1920 	btSliderConstraint* slider = new btSliderConstraint(rbA,rbB,frameInA,frameInB,useLinearReferenceFrameA);
   1921 	m_allocatedConstraints.push_back(slider);
   1922 	return slider;
   1923 }
   1924 
   1925 btSliderConstraint* btWorldImporter::createSliderConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameA)
   1926 {
   1927 	btSliderConstraint* slider = new btSliderConstraint(rbB,frameInB,useLinearReferenceFrameA);
   1928 	m_allocatedConstraints.push_back(slider);
   1929 	return slider;
   1930 }
   1931 
   1932 btGearConstraint* btWorldImporter::createGearConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& axisInA,const btVector3& axisInB, btScalar ratio)
   1933 {
   1934 	btGearConstraint* gear = new btGearConstraint(rbA,rbB,axisInA,axisInB,ratio);
   1935 	m_allocatedConstraints.push_back(gear);
   1936 	return gear;
   1937 }
   1938 
   1939 	// query for data
   1940 int	btWorldImporter::getNumCollisionShapes() const
   1941 {
   1942 	return m_allocatedCollisionShapes.size();
   1943 }
   1944 
   1945 btCollisionShape* btWorldImporter::getCollisionShapeByIndex(int index)
   1946 {
   1947 	return m_allocatedCollisionShapes[index];
   1948 }
   1949 
   1950 btCollisionShape* btWorldImporter::getCollisionShapeByName(const char* name)
   1951 {
   1952 	btCollisionShape** shapePtr = m_nameShapeMap.find(name);
   1953 	if (shapePtr&& *shapePtr)
   1954 	{
   1955 		return *shapePtr;
   1956 	}
   1957 	return 0;
   1958 }
   1959 
   1960 btRigidBody* btWorldImporter::getRigidBodyByName(const char* name)
   1961 {
   1962 	btRigidBody** bodyPtr = m_nameBodyMap.find(name);
   1963 	if (bodyPtr && *bodyPtr)
   1964 	{
   1965 		return *bodyPtr;
   1966 	}
   1967 	return 0;
   1968 }
   1969 
   1970 btTypedConstraint* btWorldImporter::getConstraintByName(const char* name)
   1971 {
   1972 	btTypedConstraint** constraintPtr = m_nameConstraintMap.find(name);
   1973 	if (constraintPtr && *constraintPtr)
   1974 	{
   1975 		return *constraintPtr;
   1976 	}
   1977 	return 0;
   1978 }
   1979 
   1980 const char*	btWorldImporter::getNameForPointer(const void* ptr) const
   1981 {
   1982 	const char*const * namePtr = m_objectNameMap.find(ptr);
   1983 	if (namePtr && *namePtr)
   1984 		return *namePtr;
   1985 	return 0;
   1986 }
   1987 
   1988 
   1989 int btWorldImporter::getNumRigidBodies() const
   1990 {
   1991 	return m_allocatedRigidBodies.size();
   1992 }
   1993 
   1994 btCollisionObject* btWorldImporter::getRigidBodyByIndex(int index) const
   1995 {
   1996 	return m_allocatedRigidBodies[index];
   1997 }
   1998 int btWorldImporter::getNumConstraints() const
   1999 {
   2000 	return m_allocatedConstraints.size();
   2001 }
   2002 
   2003 btTypedConstraint* btWorldImporter::getConstraintByIndex(int index) const
   2004 {
   2005 	return m_allocatedConstraints[index];
   2006 }
   2007 
   2008 int btWorldImporter::getNumBvhs() const
   2009 {
   2010 	return m_allocatedBvhs.size();
   2011 }
   2012  btOptimizedBvh* btWorldImporter::getBvhByIndex(int index) const
   2013 {
   2014 	return m_allocatedBvhs[index];
   2015 }
   2016 
   2017 int btWorldImporter::getNumTriangleInfoMaps() const
   2018 {
   2019 	return m_allocatedTriangleInfoMaps.size();
   2020 }
   2021 
   2022 btTriangleInfoMap* btWorldImporter::getTriangleInfoMapByIndex(int index) const
   2023 {
   2024 	return m_allocatedTriangleInfoMaps[index];
   2025 }
   2026 
   2027 
   2028 void	btWorldImporter::convertRigidBodyFloat( btRigidBodyFloatData* colObjData)
   2029 {
   2030 	btScalar mass = btScalar(colObjData->m_inverseMass? 1.f/colObjData->m_inverseMass : 0.f);
   2031 	btVector3 localInertia;
   2032 	localInertia.setZero();
   2033 	btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionObjectData.m_collisionShape);
   2034 	if (shapePtr && *shapePtr)
   2035 	{
   2036 		btTransform startTransform;
   2037 		colObjData->m_collisionObjectData.m_worldTransform.m_origin.m_floats[3] = 0.f;
   2038 		startTransform.deSerializeFloat(colObjData->m_collisionObjectData.m_worldTransform);
   2039 
   2040 	//	startTransform.setBasis(btMatrix3x3::getIdentity());
   2041 		btCollisionShape* shape = (btCollisionShape*)*shapePtr;
   2042 		if (shape->isNonMoving())
   2043 		{
   2044 			mass = 0.f;
   2045 		}
   2046 		if (mass)
   2047 		{
   2048 			shape->calculateLocalInertia(mass,localInertia);
   2049 		}
   2050 		bool isDynamic = mass!=0.f;
   2051 		btRigidBody* body = createRigidBody(isDynamic,mass,startTransform,shape,colObjData->m_collisionObjectData.m_name);
   2052 		body->setFriction(colObjData->m_collisionObjectData.m_friction);
   2053 		body->setRestitution(colObjData->m_collisionObjectData.m_restitution);
   2054 		btVector3 linearFactor,angularFactor;
   2055 		linearFactor.deSerializeFloat(colObjData->m_linearFactor);
   2056 		angularFactor.deSerializeFloat(colObjData->m_angularFactor);
   2057 		body->setLinearFactor(linearFactor);
   2058 		body->setAngularFactor(angularFactor);
   2059 
   2060 #ifdef USE_INTERNAL_EDGE_UTILITY
   2061 		if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
   2062 		{
   2063 			btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape;
   2064 			if (trimesh->getTriangleInfoMap())
   2065 			{
   2066 				body->setCollisionFlags(body->getCollisionFlags()  | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
   2067 			}
   2068 		}
   2069 #endif //USE_INTERNAL_EDGE_UTILITY
   2070 		m_bodyMap.insert(colObjData,body);
   2071 	} else
   2072 	{
   2073 		printf("error: no shape found\n");
   2074 	}
   2075 }
   2076 
   2077 void	btWorldImporter::convertRigidBodyDouble( btRigidBodyDoubleData* colObjData)
   2078 {
   2079 	btScalar mass = btScalar(colObjData->m_inverseMass? 1.f/colObjData->m_inverseMass : 0.f);
   2080 	btVector3 localInertia;
   2081 	localInertia.setZero();
   2082 	btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionObjectData.m_collisionShape);
   2083 	if (shapePtr && *shapePtr)
   2084 	{
   2085 		btTransform startTransform;
   2086 		colObjData->m_collisionObjectData.m_worldTransform.m_origin.m_floats[3] = 0.f;
   2087 		startTransform.deSerializeDouble(colObjData->m_collisionObjectData.m_worldTransform);
   2088 
   2089 	//	startTransform.setBasis(btMatrix3x3::getIdentity());
   2090 		btCollisionShape* shape = (btCollisionShape*)*shapePtr;
   2091 		if (shape->isNonMoving())
   2092 		{
   2093 			mass = 0.f;
   2094 		}
   2095 		if (mass)
   2096 		{
   2097 			shape->calculateLocalInertia(mass,localInertia);
   2098 		}
   2099 		bool isDynamic = mass!=0.f;
   2100 		btRigidBody* body = createRigidBody(isDynamic,mass,startTransform,shape,colObjData->m_collisionObjectData.m_name);
   2101 		body->setFriction(btScalar(colObjData->m_collisionObjectData.m_friction));
   2102 		body->setRestitution(btScalar(colObjData->m_collisionObjectData.m_restitution));
   2103 		btVector3 linearFactor,angularFactor;
   2104 		linearFactor.deSerializeDouble(colObjData->m_linearFactor);
   2105 		angularFactor.deSerializeDouble(colObjData->m_angularFactor);
   2106 		body->setLinearFactor(linearFactor);
   2107 		body->setAngularFactor(angularFactor);
   2108 
   2109 
   2110 #ifdef USE_INTERNAL_EDGE_UTILITY
   2111 		if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
   2112 		{
   2113 			btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape;
   2114 			if (trimesh->getTriangleInfoMap())
   2115 			{
   2116 				body->setCollisionFlags(body->getCollisionFlags()  | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
   2117 			}
   2118 		}
   2119 #endif //USE_INTERNAL_EDGE_UTILITY
   2120 		m_bodyMap.insert(colObjData,body);
   2121 	} else
   2122 	{
   2123 		printf("error: no shape found\n");
   2124 	}
   2125 }
   2126