diff --git a/src/BulletCollision/CMakeLists.txt b/src/BulletCollision/CMakeLists.txt index c4723ae25..3648fb404 100644 --- a/src/BulletCollision/CMakeLists.txt +++ b/src/BulletCollision/CMakeLists.txt @@ -18,6 +18,7 @@ SET(BulletCollision_SRCS CollisionDispatch/btCollisionDispatcher.cpp CollisionDispatch/btCollisionObject.cpp CollisionDispatch/btCollisionWorld.cpp + CollisionDispatch/btCollisionWorldImporter.cpp CollisionDispatch/btCompoundCollisionAlgorithm.cpp CollisionDispatch/btCompoundCompoundCollisionAlgorithm.cpp CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp @@ -126,6 +127,7 @@ SET(CollisionDispatch_HDRS CollisionDispatch/btCollisionObject.h CollisionDispatch/btCollisionObjectWrapper.h CollisionDispatch/btCollisionWorld.h + CollisionDispatch/btCollisionWorldImporter.h CollisionDispatch/btCompoundCollisionAlgorithm.h CollisionDispatch/btCompoundCompoundCollisionAlgorithm.h CollisionDispatch/btConvexConcaveCollisionAlgorithm.h diff --git a/src/BulletCollision/CollisionDispatch/btCollisionWorldImporter.cpp b/src/BulletCollision/CollisionDispatch/btCollisionWorldImporter.cpp new file mode 100644 index 000000000..36dd04350 --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btCollisionWorldImporter.cpp @@ -0,0 +1,1147 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2014 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +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. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btCollisionWorldImporter.h" +#include "btBulletCollisionCommon.h" +#include "LinearMath/btSerializer.h" //for btBulletSerializedArrays definition + +#ifdef SUPPORT_GIMPACT_SHAPE_IMPORT +#include "BulletCollision/Gimpact/btGImpactShape.h" +#endif //SUPPORT_GIMPACT_SHAPE_IMPORT + +btCollisionWorldImporter::btCollisionWorldImporter(btCollisionWorld* world) +:m_collisionWorld(world), +m_verboseMode(0) +{ + +} + +btCollisionWorldImporter::~btCollisionWorldImporter() +{ +} + + + + + +bool btCollisionWorldImporter::convertAllObjects( btBulletSerializedArrays* arrays) +{ + + m_shapeMap.clear(); + m_bodyMap.clear(); + + int i; + + for (i=0;im_bvhsDouble.size();i++) + { + btOptimizedBvh* bvh = createOptimizedBvh(); + btQuantizedBvhDoubleData* bvhData = arrays->m_bvhsDouble[i]; + bvh->deSerializeDouble(*bvhData); + m_bvhMap.insert(arrays->m_bvhsDouble[i],bvh); + } + for (i=0;im_bvhsFloat.size();i++) + { + btOptimizedBvh* bvh = createOptimizedBvh(); + btQuantizedBvhFloatData* bvhData = arrays->m_bvhsFloat[i]; + bvh->deSerializeFloat(*bvhData); + m_bvhMap.insert(arrays->m_bvhsFloat[i],bvh); + } + + + + + + for (i=0;im_colShapeData.size();i++) + { + btCollisionShapeData* shapeData = arrays->m_colShapeData[i]; + btCollisionShape* shape = convertCollisionShape(shapeData); + if (shape) + { + // printf("shapeMap.insert(%x,%x)\n",shapeData,shape); + m_shapeMap.insert(shapeData,shape); + } + + if (shape&& shapeData->m_name) + { + char* newname = duplicateName(shapeData->m_name); + m_objectNameMap.insert(shape,newname); + m_nameShapeMap.insert(newname,shape); + } + } + + + for (i=0;im_collisionObjectDataDouble.size();i++) + { + btCollisionObjectDoubleData* colObjData = arrays->m_collisionObjectDataDouble[i]; + btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionShape); + if (shapePtr && *shapePtr) + { + btTransform startTransform; + colObjData->m_worldTransform.m_origin.m_floats[3] = 0.f; + startTransform.deSerializeDouble(colObjData->m_worldTransform); + + btCollisionShape* shape = (btCollisionShape*)*shapePtr; + btCollisionObject* body = createCollisionObject(startTransform,shape,colObjData->m_name); + body->setFriction(btScalar(colObjData->m_friction)); + body->setRestitution(btScalar(colObjData->m_restitution)); + +#ifdef USE_INTERNAL_EDGE_UTILITY + if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) + { + btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape; + if (trimesh->getTriangleInfoMap()) + { + body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); + } + } +#endif //USE_INTERNAL_EDGE_UTILITY + m_bodyMap.insert(colObjData,body); + } else + { + printf("error: no shape found\n"); + } + } + for (i=0;im_collisionObjectDataFloat.size();i++) + { + btCollisionObjectFloatData* colObjData = arrays->m_collisionObjectDataFloat[i]; + btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionShape); + if (shapePtr && *shapePtr) + { + btTransform startTransform; + colObjData->m_worldTransform.m_origin.m_floats[3] = 0.f; + startTransform.deSerializeFloat(colObjData->m_worldTransform); + + btCollisionShape* shape = (btCollisionShape*)*shapePtr; + btCollisionObject* body = createCollisionObject(startTransform,shape,colObjData->m_name); + +#ifdef USE_INTERNAL_EDGE_UTILITY + if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) + { + btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape; + if (trimesh->getTriangleInfoMap()) + { + body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); + } + } +#endif //USE_INTERNAL_EDGE_UTILITY + m_bodyMap.insert(colObjData,body); + } else + { + printf("error: no shape found\n"); + } + } + + return true; +} + + + +void btCollisionWorldImporter::deleteAllData() +{ + int i; + + for (i=0;iremoveCollisionObject(m_allocatedCollisionObjects[i]); + delete m_allocatedCollisionObjects[i]; + } + + m_allocatedCollisionObjects.clear(); + + + for (i=0;im_numMeshParts;a++) + { + btMeshPartData* curPart = &curData->m_meshPartsPtr[a]; + if(curPart->m_vertices3f) + delete [] curPart->m_vertices3f; + + if(curPart->m_vertices3d) + delete [] curPart->m_vertices3d; + + if(curPart->m_indices32) + delete [] curPart->m_indices32; + + if(curPart->m_3indices16) + delete [] curPart->m_3indices16; + + if(curPart->m_indices16) + delete [] curPart->m_indices16; + + if (curPart->m_3indices8) + delete [] curPart->m_3indices8; + + } + delete [] curData->m_meshPartsPtr; + delete curData; + } + m_allocatedbtStridingMeshInterfaceDatas.clear(); + + for (i=0;im_shapeType) + { + case STATIC_PLANE_PROXYTYPE: + { + btStaticPlaneShapeData* planeData = (btStaticPlaneShapeData*)shapeData; + btVector3 planeNormal,localScaling; + planeNormal.deSerializeFloat(planeData->m_planeNormal); + localScaling.deSerializeFloat(planeData->m_localScaling); + shape = createPlaneShape(planeNormal,planeData->m_planeConstant); + shape->setLocalScaling(localScaling); + + break; + } + case SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE: + { + btScaledTriangleMeshShapeData* scaledMesh = (btScaledTriangleMeshShapeData*) shapeData; + btCollisionShapeData* colShapeData = (btCollisionShapeData*) &scaledMesh->m_trimeshShapeData; + colShapeData->m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE; + btCollisionShape* childShape = convertCollisionShape(colShapeData); + btBvhTriangleMeshShape* meshShape = (btBvhTriangleMeshShape*)childShape; + btVector3 localScaling; + localScaling.deSerializeFloat(scaledMesh->m_localScaling); + + shape = createScaledTrangleMeshShape(meshShape, localScaling); + break; + } +#ifdef SUPPORT_GIMPACT_SHAPE_IMPORT + case GIMPACT_SHAPE_PROXYTYPE: + { + btGImpactMeshShapeData* gimpactData = (btGImpactMeshShapeData*) shapeData; + if (gimpactData->m_gimpactSubType == CONST_GIMPACT_TRIMESH_SHAPE) + { + btStridingMeshInterfaceData* interfaceData = createStridingMeshInterfaceData(&gimpactData->m_meshInterface); + btTriangleIndexVertexArray* meshInterface = createMeshInterface(*interfaceData); + + + btGImpactMeshShape* gimpactShape = createGimpactShape(meshInterface); + btVector3 localScaling; + localScaling.deSerializeFloat(gimpactData->m_localScaling); + gimpactShape->setLocalScaling(localScaling); + gimpactShape->setMargin(btScalar(gimpactData->m_collisionMargin)); + gimpactShape->updateBound(); + shape = gimpactShape; + } else + { + printf("unsupported gimpact sub type\n"); + } + break; + } +#endif //SUPPORT_GIMPACT_SHAPE_IMPORT + //The btCapsuleShape* API has issue passing the margin/scaling/halfextents unmodified through the API + //so deal with this + case CAPSULE_SHAPE_PROXYTYPE: + { + btCapsuleShapeData* capData = (btCapsuleShapeData*)shapeData; + + + switch (capData->m_upAxis) + { + case 0: + { + shape = createCapsuleShapeX(1,1); + break; + } + case 1: + { + shape = createCapsuleShapeY(1,1); + break; + } + case 2: + { + shape = createCapsuleShapeZ(1,1); + break; + } + default: + { + printf("error: wrong up axis for btCapsuleShape\n"); + } + + + }; + if (shape) + { + btCapsuleShape* cap = (btCapsuleShape*) shape; + cap->deSerializeFloat(capData); + } + break; + } + case CYLINDER_SHAPE_PROXYTYPE: + case CONE_SHAPE_PROXYTYPE: + case BOX_SHAPE_PROXYTYPE: + case SPHERE_SHAPE_PROXYTYPE: + case MULTI_SPHERE_SHAPE_PROXYTYPE: + case CONVEX_HULL_SHAPE_PROXYTYPE: + { + btConvexInternalShapeData* bsd = (btConvexInternalShapeData*)shapeData; + btVector3 implicitShapeDimensions; + implicitShapeDimensions.deSerializeFloat(bsd->m_implicitShapeDimensions); + btVector3 localScaling; + localScaling.deSerializeFloat(bsd->m_localScaling); + btVector3 margin(bsd->m_collisionMargin,bsd->m_collisionMargin,bsd->m_collisionMargin); + switch (shapeData->m_shapeType) + { + case BOX_SHAPE_PROXYTYPE: + { + btBoxShape* box= (btBoxShape*)createBoxShape(implicitShapeDimensions/localScaling+margin); + //box->initializePolyhedralFeatures(); + shape = box; + + break; + } + case SPHERE_SHAPE_PROXYTYPE: + { + shape = createSphereShape(implicitShapeDimensions.getX()); + break; + } + + case CYLINDER_SHAPE_PROXYTYPE: + { + btCylinderShapeData* cylData = (btCylinderShapeData*) shapeData; + btVector3 halfExtents = implicitShapeDimensions+margin; + switch (cylData->m_upAxis) + { + case 0: + { + shape = createCylinderShapeX(halfExtents.getY(),halfExtents.getX()); + break; + } + case 1: + { + shape = createCylinderShapeY(halfExtents.getX(),halfExtents.getY()); + break; + } + case 2: + { + shape = createCylinderShapeZ(halfExtents.getX(),halfExtents.getZ()); + break; + } + default: + { + printf("unknown Cylinder up axis\n"); + } + + }; + + + + break; + } + case CONE_SHAPE_PROXYTYPE: + { + btConeShapeData* conData = (btConeShapeData*) shapeData; + btVector3 halfExtents = implicitShapeDimensions;//+margin; + switch (conData->m_upIndex) + { + case 0: + { + shape = createConeShapeX(halfExtents.getY(),halfExtents.getX()); + break; + } + case 1: + { + shape = createConeShapeY(halfExtents.getX(),halfExtents.getY()); + break; + } + case 2: + { + shape = createConeShapeZ(halfExtents.getX(),halfExtents.getZ()); + break; + } + default: + { + printf("unknown Cone up axis\n"); + } + + }; + + + + break; + } + case MULTI_SPHERE_SHAPE_PROXYTYPE: + { + btMultiSphereShapeData* mss = (btMultiSphereShapeData*)bsd; + int numSpheres = mss->m_localPositionArraySize; + + btAlignedObjectArray tmpPos; + btAlignedObjectArray radii; + radii.resize(numSpheres); + tmpPos.resize(numSpheres); + int i; + for ( i=0;im_localPositionArrayPtr[i].m_pos); + radii[i] = mss->m_localPositionArrayPtr[i].m_radius; + } + shape = createMultiSphereShape(&tmpPos[0],&radii[0],numSpheres); + break; + } + case CONVEX_HULL_SHAPE_PROXYTYPE: + { + // int sz = sizeof(btConvexHullShapeData); + // int sz2 = sizeof(btConvexInternalShapeData); + // int sz3 = sizeof(btCollisionShapeData); + btConvexHullShapeData* convexData = (btConvexHullShapeData*)bsd; + int numPoints = convexData->m_numUnscaledPoints; + + btAlignedObjectArray tmpPoints; + tmpPoints.resize(numPoints); + int i; + for ( i=0;im_unscaledPointsDoublePtr) + tmpPoints[i].deSerialize(convexData->m_unscaledPointsDoublePtr[i]); + if (convexData->m_unscaledPointsFloatPtr) + tmpPoints[i].deSerializeFloat(convexData->m_unscaledPointsFloatPtr[i]); +#else + if (convexData->m_unscaledPointsFloatPtr) + tmpPoints[i].deSerialize(convexData->m_unscaledPointsFloatPtr[i]); + if (convexData->m_unscaledPointsDoublePtr) + tmpPoints[i].deSerializeDouble(convexData->m_unscaledPointsDoublePtr[i]); +#endif //BT_USE_DOUBLE_PRECISION + } + btConvexHullShape* hullShape = createConvexHullShape(); + for (i=0;iaddPoint(tmpPoints[i]); + } + hullShape->setMargin(bsd->m_collisionMargin); + //hullShape->initializePolyhedralFeatures(); + shape = hullShape; + break; + } + default: + { + printf("error: cannot create shape type (%d)\n",shapeData->m_shapeType); + } + } + + if (shape) + { + shape->setMargin(bsd->m_collisionMargin); + + btVector3 localScaling; + localScaling.deSerializeFloat(bsd->m_localScaling); + shape->setLocalScaling(localScaling); + + } + break; + } + case TRIANGLE_MESH_SHAPE_PROXYTYPE: + { + btTriangleMeshShapeData* trimesh = (btTriangleMeshShapeData*)shapeData; + btStridingMeshInterfaceData* interfaceData = createStridingMeshInterfaceData(&trimesh->m_meshInterface); + btTriangleIndexVertexArray* meshInterface = createMeshInterface(*interfaceData); + if (!meshInterface->getNumSubParts()) + { + return 0; + } + + btVector3 scaling; scaling.deSerializeFloat(trimesh->m_meshInterface.m_scaling); + meshInterface->setScaling(scaling); + + + btOptimizedBvh* bvh = 0; +#if 1 + if (trimesh->m_quantizedFloatBvh) + { + btOptimizedBvh** bvhPtr = m_bvhMap.find(trimesh->m_quantizedFloatBvh); + if (bvhPtr && *bvhPtr) + { + bvh = *bvhPtr; + } else + { + bvh = createOptimizedBvh(); + bvh->deSerializeFloat(*trimesh->m_quantizedFloatBvh); + } + } + if (trimesh->m_quantizedDoubleBvh) + { + btOptimizedBvh** bvhPtr = m_bvhMap.find(trimesh->m_quantizedDoubleBvh); + if (bvhPtr && *bvhPtr) + { + bvh = *bvhPtr; + } else + { + bvh = createOptimizedBvh(); + bvh->deSerializeDouble(*trimesh->m_quantizedDoubleBvh); + } + } +#endif + + + btBvhTriangleMeshShape* trimeshShape = createBvhTriangleMeshShape(meshInterface,bvh); + trimeshShape->setMargin(trimesh->m_collisionMargin); + shape = trimeshShape; + + if (trimesh->m_triangleInfoMap) + { + btTriangleInfoMap* map = createTriangleInfoMap(); + map->deSerialize(*trimesh->m_triangleInfoMap); + trimeshShape->setTriangleInfoMap(map); + +#ifdef USE_INTERNAL_EDGE_UTILITY + gContactAddedCallback = btAdjustInternalEdgeContactsCallback; +#endif //USE_INTERNAL_EDGE_UTILITY + + } + + //printf("trimesh->m_collisionMargin=%f\n",trimesh->m_collisionMargin); + break; + } + case COMPOUND_SHAPE_PROXYTYPE: + { + btCompoundShapeData* compoundData = (btCompoundShapeData*)shapeData; + btCompoundShape* compoundShape = createCompoundShape(); + + btCompoundShapeChildData* childShapeDataArray = &compoundData->m_childShapePtr[0]; + + + btAlignedObjectArray childShapes; + for (int i=0;im_numChildShapes;i++) + { + btCompoundShapeChildData* ptr = &compoundData->m_childShapePtr[i]; + + btCollisionShapeData* cd = compoundData->m_childShapePtr[i].m_childShape; + + btCollisionShape* childShape = convertCollisionShape(cd); + if (childShape) + { + btTransform localTransform; + localTransform.deSerializeFloat(compoundData->m_childShapePtr[i].m_transform); + compoundShape->addChildShape(localTransform,childShape); + } else + { +#ifdef _DEBUG + printf("error: couldn't create childShape for compoundShape\n"); +#endif + } + + } + shape = compoundShape; + + break; + } + case SOFTBODY_SHAPE_PROXYTYPE: + { + return 0; + } + default: + { +#ifdef _DEBUG + printf("unsupported shape type (%d)\n",shapeData->m_shapeType); +#endif + } + } + + return shape; + +} + + + +char* btCollisionWorldImporter::duplicateName(const char* name) +{ + if (name) + { + int l = (int)strlen(name); + char* newName = new char[l+1]; + memcpy(newName,name,l); + newName[l] = 0; + m_allocatedNames.push_back(newName); + return newName; + } + return 0; +} + + + + + + + + + + + +btTriangleIndexVertexArray* btCollisionWorldImporter::createMeshInterface(btStridingMeshInterfaceData& meshData) +{ + btTriangleIndexVertexArray* meshInterface = createTriangleMeshContainer(); + + for (int i=0;iaddIndexedMesh(meshPart,meshPart.m_indexType); + } + } + + return meshInterface; +} + + +btStridingMeshInterfaceData* btCollisionWorldImporter::createStridingMeshInterfaceData(btStridingMeshInterfaceData* interfaceData) +{ + //create a new btStridingMeshInterfaceData that is an exact copy of shapedata and store it in the WorldImporter + btStridingMeshInterfaceData* newData = new btStridingMeshInterfaceData; + + newData->m_scaling = interfaceData->m_scaling; + newData->m_numMeshParts = interfaceData->m_numMeshParts; + newData->m_meshPartsPtr = new btMeshPartData[newData->m_numMeshParts]; + + for(int i = 0;i < newData->m_numMeshParts;i++) + { + btMeshPartData* curPart = &interfaceData->m_meshPartsPtr[i]; + btMeshPartData* curNewPart = &newData->m_meshPartsPtr[i]; + + curNewPart->m_numTriangles = curPart->m_numTriangles; + curNewPart->m_numVertices = curPart->m_numVertices; + + if(curPart->m_vertices3f) + { + curNewPart->m_vertices3f = new btVector3FloatData[curNewPart->m_numVertices]; + memcpy(curNewPart->m_vertices3f,curPart->m_vertices3f,sizeof(btVector3FloatData) * curNewPart->m_numVertices); + } + else + curNewPart->m_vertices3f = NULL; + + if(curPart->m_vertices3d) + { + curNewPart->m_vertices3d = new btVector3DoubleData[curNewPart->m_numVertices]; + memcpy(curNewPart->m_vertices3d,curPart->m_vertices3d,sizeof(btVector3DoubleData) * curNewPart->m_numVertices); + } + else + curNewPart->m_vertices3d = NULL; + + int numIndices = curNewPart->m_numTriangles * 3; + ///the m_3indices8 was not initialized in some Bullet versions, this can cause crashes at loading time + ///we catch it by only dealing with m_3indices8 if none of the other indices are initialized + bool uninitialized3indices8Workaround =false; + + if(curPart->m_indices32) + { + uninitialized3indices8Workaround=true; + curNewPart->m_indices32 = new btIntIndexData[numIndices]; + memcpy(curNewPart->m_indices32,curPart->m_indices32,sizeof(btIntIndexData) * numIndices); + } + else + curNewPart->m_indices32 = NULL; + + if(curPart->m_3indices16) + { + uninitialized3indices8Workaround=true; + curNewPart->m_3indices16 = new btShortIntIndexTripletData[curNewPart->m_numTriangles]; + memcpy(curNewPart->m_3indices16,curPart->m_3indices16,sizeof(btShortIntIndexTripletData) * curNewPart->m_numTriangles); + } + else + curNewPart->m_3indices16 = NULL; + + if(curPart->m_indices16) + { + uninitialized3indices8Workaround=true; + curNewPart->m_indices16 = new btShortIntIndexData[numIndices]; + memcpy(curNewPart->m_indices16,curPart->m_indices16,sizeof(btShortIntIndexData) * numIndices); + } + else + curNewPart->m_indices16 = NULL; + + if(!uninitialized3indices8Workaround && curPart->m_3indices8) + { + curNewPart->m_3indices8 = new btCharIndexTripletData[curNewPart->m_numTriangles]; + memcpy(curNewPart->m_3indices8,curPart->m_3indices8,sizeof(btCharIndexTripletData) * curNewPart->m_numTriangles); + } + else + curNewPart->m_3indices8 = NULL; + + } + + m_allocatedbtStridingMeshInterfaceDatas.push_back(newData); + + return(newData); +} + +#ifdef USE_INTERNAL_EDGE_UTILITY +extern ContactAddedCallback gContactAddedCallback; + +static bool btAdjustInternalEdgeContactsCallback(btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1) +{ + + btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1); + //btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_BACKFACE_MODE); + //btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_DOUBLE_SIDED+BT_TRIANGLE_CONCAVE_DOUBLE_SIDED); + return true; +} +#endif //USE_INTERNAL_EDGE_UTILITY + + +/* +btRigidBody* btWorldImporter::createRigidBody(bool isDynamic, btScalar mass, const btTransform& startTransform,btCollisionShape* shape,const char* bodyName) +{ + btVector3 localInertia; + localInertia.setZero(); + + if (mass) + shape->calculateLocalInertia(mass,localInertia); + + btRigidBody* body = new btRigidBody(mass,0,shape,localInertia); + body->setWorldTransform(startTransform); + + if (m_dynamicsWorld) + m_dynamicsWorld->addRigidBody(body); + + if (bodyName) + { + char* newname = duplicateName(bodyName); + m_objectNameMap.insert(body,newname); + m_nameBodyMap.insert(newname,body); + } + m_allocatedRigidBodies.push_back(body); + return body; + +} +*/ + +btCollisionObject* btCollisionWorldImporter::getCollisionObjectByName(const char* name) +{ + btCollisionObject** bodyPtr = m_nameColObjMap.find(name); + if (bodyPtr && *bodyPtr) + { + return *bodyPtr; + } + return 0; +} + +btCollisionObject* btCollisionWorldImporter::createCollisionObject(const btTransform& startTransform,btCollisionShape* shape, const char* bodyName) +{ + btCollisionObject* colObj = new btCollisionObject(); + colObj->setWorldTransform(startTransform); + colObj->setCollisionShape(shape); + m_collisionWorld->addCollisionObject(colObj);//todo: flags etc + + if (bodyName) + { + char* newname = duplicateName(bodyName); + m_objectNameMap.insert(colObj,newname); + m_nameColObjMap.insert(newname,colObj); + } + m_allocatedCollisionObjects.push_back(colObj); + + return colObj; +} + + + +btCollisionShape* btCollisionWorldImporter::createPlaneShape(const btVector3& planeNormal,btScalar planeConstant) +{ + btStaticPlaneShape* shape = new btStaticPlaneShape(planeNormal,planeConstant); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} +btCollisionShape* btCollisionWorldImporter::createBoxShape(const btVector3& halfExtents) +{ + btBoxShape* shape = new btBoxShape(halfExtents); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} +btCollisionShape* btCollisionWorldImporter::createSphereShape(btScalar radius) +{ + btSphereShape* shape = new btSphereShape(radius); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + + +btCollisionShape* btCollisionWorldImporter::createCapsuleShapeX(btScalar radius, btScalar height) +{ + btCapsuleShapeX* shape = new btCapsuleShapeX(radius,height); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btCollisionShape* btCollisionWorldImporter::createCapsuleShapeY(btScalar radius, btScalar height) +{ + btCapsuleShape* shape = new btCapsuleShape(radius,height); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btCollisionShape* btCollisionWorldImporter::createCapsuleShapeZ(btScalar radius, btScalar height) +{ + btCapsuleShapeZ* shape = new btCapsuleShapeZ(radius,height); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btCollisionShape* btCollisionWorldImporter::createCylinderShapeX(btScalar radius,btScalar height) +{ + btCylinderShapeX* shape = new btCylinderShapeX(btVector3(height,radius,radius)); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btCollisionShape* btCollisionWorldImporter::createCylinderShapeY(btScalar radius,btScalar height) +{ + btCylinderShape* shape = new btCylinderShape(btVector3(radius,height,radius)); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btCollisionShape* btCollisionWorldImporter::createCylinderShapeZ(btScalar radius,btScalar height) +{ + btCylinderShapeZ* shape = new btCylinderShapeZ(btVector3(radius,radius,height)); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btCollisionShape* btCollisionWorldImporter::createConeShapeX(btScalar radius,btScalar height) +{ + btConeShapeX* shape = new btConeShapeX(radius,height); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btCollisionShape* btCollisionWorldImporter::createConeShapeY(btScalar radius,btScalar height) +{ + btConeShape* shape = new btConeShape(radius,height); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btCollisionShape* btCollisionWorldImporter::createConeShapeZ(btScalar radius,btScalar height) +{ + btConeShapeZ* shape = new btConeShapeZ(radius,height); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btTriangleIndexVertexArray* btCollisionWorldImporter::createTriangleMeshContainer() +{ + btTriangleIndexVertexArray* in = new btTriangleIndexVertexArray(); + m_allocatedTriangleIndexArrays.push_back(in); + return in; +} + +btOptimizedBvh* btCollisionWorldImporter::createOptimizedBvh() +{ + btOptimizedBvh* bvh = new btOptimizedBvh(); + m_allocatedBvhs.push_back(bvh); + return bvh; +} + + +btTriangleInfoMap* btCollisionWorldImporter::createTriangleInfoMap() +{ + btTriangleInfoMap* tim = new btTriangleInfoMap(); + m_allocatedTriangleInfoMaps.push_back(tim); + return tim; +} + +btBvhTriangleMeshShape* btCollisionWorldImporter::createBvhTriangleMeshShape(btStridingMeshInterface* trimesh, btOptimizedBvh* bvh) +{ + if (bvh) + { + btBvhTriangleMeshShape* bvhTriMesh = new btBvhTriangleMeshShape(trimesh,bvh->isQuantized(), false); + bvhTriMesh->setOptimizedBvh(bvh); + m_allocatedCollisionShapes.push_back(bvhTriMesh); + return bvhTriMesh; + } + + btBvhTriangleMeshShape* ts = new btBvhTriangleMeshShape(trimesh,true); + m_allocatedCollisionShapes.push_back(ts); + return ts; + +} +btCollisionShape* btCollisionWorldImporter::createConvexTriangleMeshShape(btStridingMeshInterface* trimesh) +{ + return 0; +} +#ifdef SUPPORT_GIMPACT_SHAPE_IMPORT +btGImpactMeshShape* btCollisionWorldImporter::createGimpactShape(btStridingMeshInterface* trimesh) +{ + btGImpactMeshShape* shape = new btGImpactMeshShape(trimesh); + m_allocatedCollisionShapes.push_back(shape); + return shape; + +} +#endif //SUPPORT_GIMPACT_SHAPE_IMPORT + +btConvexHullShape* btCollisionWorldImporter::createConvexHullShape() +{ + btConvexHullShape* shape = new btConvexHullShape(); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btCompoundShape* btCollisionWorldImporter::createCompoundShape() +{ + btCompoundShape* shape = new btCompoundShape(); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + + +btScaledBvhTriangleMeshShape* btCollisionWorldImporter::createScaledTrangleMeshShape(btBvhTriangleMeshShape* meshShape,const btVector3& localScaling) +{ + btScaledBvhTriangleMeshShape* shape = new btScaledBvhTriangleMeshShape(meshShape,localScaling); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btMultiSphereShape* btCollisionWorldImporter::createMultiSphereShape(const btVector3* positions,const btScalar* radi,int numSpheres) +{ + btMultiSphereShape* shape = new btMultiSphereShape(positions, radi, numSpheres); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + + + + // query for data +int btCollisionWorldImporter::getNumCollisionShapes() const +{ + return m_allocatedCollisionShapes.size(); +} + +btCollisionShape* btCollisionWorldImporter::getCollisionShapeByIndex(int index) +{ + return m_allocatedCollisionShapes[index]; +} + +btCollisionShape* btCollisionWorldImporter::getCollisionShapeByName(const char* name) +{ + btCollisionShape** shapePtr = m_nameShapeMap.find(name); + if (shapePtr&& *shapePtr) + { + return *shapePtr; + } + return 0; +} + + +const char* btCollisionWorldImporter::getNameForPointer(const void* ptr) const +{ + const char*const * namePtr = m_objectNameMap.find(ptr); + if (namePtr && *namePtr) + return *namePtr; + return 0; +} + + +int btCollisionWorldImporter::getNumRigidBodies() const +{ + return m_allocatedRigidBodies.size(); +} + +btCollisionObject* btCollisionWorldImporter::getRigidBodyByIndex(int index) const +{ + return m_allocatedRigidBodies[index]; +} + + +int btCollisionWorldImporter::getNumBvhs() const +{ + return m_allocatedBvhs.size(); +} + btOptimizedBvh* btCollisionWorldImporter::getBvhByIndex(int index) const +{ + return m_allocatedBvhs[index]; +} + +int btCollisionWorldImporter::getNumTriangleInfoMaps() const +{ + return m_allocatedTriangleInfoMaps.size(); +} + +btTriangleInfoMap* btCollisionWorldImporter::getTriangleInfoMapByIndex(int index) const +{ + return m_allocatedTriangleInfoMaps[index]; +} + + diff --git a/src/BulletCollision/CollisionDispatch/btCollisionWorldImporter.h b/src/BulletCollision/CollisionDispatch/btCollisionWorldImporter.h new file mode 100644 index 000000000..ba03015d4 --- /dev/null +++ b/src/BulletCollision/CollisionDispatch/btCollisionWorldImporter.h @@ -0,0 +1,190 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2014 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +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. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef BT_COLLISION_WORLD_IMPORTER_H +#define BT_COLLISION_WORLD_IMPORTER_H + +#include "LinearMath/btTransform.h" +#include "LinearMath/btVector3.h" +#include "LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btHashMap.h" + +class btCollisionShape; +class btCollisionObject; +class btBulletSerializedArrays; + + +struct ConstraintInput; +class btCollisionWorld; +struct btCollisionShapeData; +class btTriangleIndexVertexArray; +class btStridingMeshInterface; +struct btStridingMeshInterfaceData; +class btGImpactMeshShape; +class btOptimizedBvh; +struct btTriangleInfoMap; +class btBvhTriangleMeshShape; +class btPoint2PointConstraint; +class btHingeConstraint; +class btConeTwistConstraint; +class btGeneric6DofConstraint; +class btGeneric6DofSpringConstraint; +class btSliderConstraint; +class btGearConstraint; +struct btContactSolverInfo; + + + + +class btCollisionWorldImporter +{ +protected: + btCollisionWorld* m_collisionWorld; + + int m_verboseMode; + + btAlignedObjectArray m_allocatedCollisionShapes; + btAlignedObjectArray m_allocatedRigidBodies; + + btAlignedObjectArray m_allocatedBvhs; + btAlignedObjectArray m_allocatedTriangleInfoMaps; + btAlignedObjectArray m_allocatedTriangleIndexArrays; + btAlignedObjectArray m_allocatedbtStridingMeshInterfaceDatas; + btAlignedObjectArray m_allocatedCollisionObjects; + + + btAlignedObjectArray m_allocatedNames; + + btAlignedObjectArray m_indexArrays; + btAlignedObjectArray m_shortIndexArrays; + btAlignedObjectArray m_charIndexArrays; + + btAlignedObjectArray m_floatVertexArrays; + btAlignedObjectArray m_doubleVertexArrays; + + + btHashMap m_bvhMap; + btHashMap m_timMap; + + btHashMap m_nameShapeMap; + btHashMap m_nameColObjMap; + + btHashMap m_objectNameMap; + + btHashMap m_shapeMap; + btHashMap m_bodyMap; + + + //methods + + + + char* duplicateName(const char* name); + + btCollisionShape* convertCollisionShape( btCollisionShapeData* shapeData ); + + +public: + + btCollisionWorldImporter(btCollisionWorld* world); + + virtual ~btCollisionWorldImporter(); + + bool convertAllObjects( btBulletSerializedArrays* arrays); + + ///delete all memory collision shapes, rigid bodies, constraints etc. allocated during the load. + ///make sure you don't use the dynamics world containing objects after you call this method + virtual void deleteAllData(); + + void setVerboseMode(int verboseMode) + { + m_verboseMode = verboseMode; + } + + int getVerboseMode() const + { + return m_verboseMode; + } + + // query for data + int getNumCollisionShapes() const; + btCollisionShape* getCollisionShapeByIndex(int index); + int getNumRigidBodies() const; + btCollisionObject* getRigidBodyByIndex(int index) const; + int getNumConstraints() const; + + int getNumBvhs() const; + btOptimizedBvh* getBvhByIndex(int index) const; + int getNumTriangleInfoMaps() const; + btTriangleInfoMap* getTriangleInfoMapByIndex(int index) const; + + // queris involving named objects + btCollisionShape* getCollisionShapeByName(const char* name); + btCollisionObject* getCollisionObjectByName(const char* name); + + + const char* getNameForPointer(const void* ptr) const; + + ///those virtuals are called by load and can be overridden by the user + + + + //bodies + + virtual btCollisionObject* createCollisionObject( const btTransform& startTransform, btCollisionShape* shape,const char* bodyName); + + ///shapes + + virtual btCollisionShape* createPlaneShape(const btVector3& planeNormal,btScalar planeConstant); + virtual btCollisionShape* createBoxShape(const btVector3& halfExtents); + virtual btCollisionShape* createSphereShape(btScalar radius); + virtual btCollisionShape* createCapsuleShapeX(btScalar radius, btScalar height); + virtual btCollisionShape* createCapsuleShapeY(btScalar radius, btScalar height); + virtual btCollisionShape* createCapsuleShapeZ(btScalar radius, btScalar height); + + virtual btCollisionShape* createCylinderShapeX(btScalar radius,btScalar height); + virtual btCollisionShape* createCylinderShapeY(btScalar radius,btScalar height); + virtual btCollisionShape* createCylinderShapeZ(btScalar radius,btScalar height); + virtual btCollisionShape* createConeShapeX(btScalar radius,btScalar height); + virtual btCollisionShape* createConeShapeY(btScalar radius,btScalar height); + virtual btCollisionShape* createConeShapeZ(btScalar radius,btScalar height); + virtual class btTriangleIndexVertexArray* createTriangleMeshContainer(); + virtual btBvhTriangleMeshShape* createBvhTriangleMeshShape(btStridingMeshInterface* trimesh, btOptimizedBvh* bvh); + virtual btCollisionShape* createConvexTriangleMeshShape(btStridingMeshInterface* trimesh); +#ifdef SUPPORT_GIMPACT_SHAPE_IMPORT + virtual btGImpactMeshShape* createGimpactShape(btStridingMeshInterface* trimesh); +#endif //SUPPORT_GIMPACT_SHAPE_IMPORT + virtual btStridingMeshInterfaceData* createStridingMeshInterfaceData(btStridingMeshInterfaceData* interfaceData); + + virtual class btConvexHullShape* createConvexHullShape(); + virtual class btCompoundShape* createCompoundShape(); + virtual class btScaledBvhTriangleMeshShape* createScaledTrangleMeshShape(btBvhTriangleMeshShape* meshShape,const btVector3& localScalingbtBvhTriangleMeshShape); + + virtual class btMultiSphereShape* createMultiSphereShape(const btVector3* positions,const btScalar* radi,int numSpheres); + + virtual btTriangleIndexVertexArray* createMeshInterface(btStridingMeshInterfaceData& meshData); + + ///acceleration and connectivity structures + virtual btOptimizedBvh* createOptimizedBvh(); + virtual btTriangleInfoMap* createTriangleInfoMap(); + + + + +}; + + +#endif //BT_WORLD_IMPORTER_H diff --git a/src/LinearMath/btSerializer.h b/src/LinearMath/btSerializer.h index 96914981d..d22b04574 100644 --- a/src/LinearMath/btSerializer.h +++ b/src/LinearMath/btSerializer.h @@ -4,8 +4,8 @@ Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it freely, +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 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. @@ -32,12 +32,12 @@ extern int sBulletDNAlen; extern char sBulletDNAstr64[]; extern int sBulletDNAlen64; -SIMD_FORCE_INLINE int btStrLen(const char* str) +SIMD_FORCE_INLINE int btStrLen(const char* str) { - if (!str) + if (!str) return(0); int len = 0; - + while (*str != 0) { str++; @@ -85,7 +85,7 @@ public: virtual void* getUniquePointer(void*oldPtr) = 0; virtual void startSerialization() = 0; - + virtual void finishSerialization() = 0; virtual const char* findNameForPointer(const void* ptr) const = 0; @@ -149,12 +149,13 @@ struct btBulletSerializedArrays btAlignedObjectArray m_dynamicWorldInfoDataFloat; btAlignedObjectArray m_rigidBodyDataDouble; btAlignedObjectArray m_rigidBodyDataFloat; - btAlignedObjectArray m_collisionDataDouble; - btAlignedObjectArray m_collisionDataFloat; + btAlignedObjectArray m_collisionObjectDataDouble; + btAlignedObjectArray m_collisionObjectDataFloat; btAlignedObjectArray m_constraintDataFloat; btAlignedObjectArray m_constraintDataDouble; btAlignedObjectArray m_constraintData;//for backwards compatibility - + btAlignedObjectArray m_softBodyFloatData; + btAlignedObjectArray m_softBodyDoubleData; }; @@ -172,9 +173,9 @@ protected: btHashMap mStructReverse; btHashMap mTypeLookup; - + btHashMap m_chunkP; - + btHashMap m_nameMap; btHashMap m_uniquePointers; @@ -190,10 +191,10 @@ protected: btAlignedObjectArray m_chunkPtrs; - + protected: - virtual void* findPointer(void* oldPtr) + virtual void* findPointer(void* oldPtr) { void** ptr = m_chunkP.find(oldPtr); if (ptr && *ptr) @@ -201,7 +202,7 @@ protected: return 0; } - + @@ -219,7 +220,7 @@ protected: const int* valuePtr = mTypeLookup.find(key); if (valuePtr) return *valuePtr; - + return -1; } @@ -231,7 +232,7 @@ protected: int littleEndian= 1; littleEndian= ((char*)&littleEndian)[0]; - + m_dna = btAlignedAlloc(dnalen,16); memcpy(m_dna,bdnaOrg,dnalen); @@ -259,16 +260,16 @@ protected: // Parse names if (!littleEndian) *intPtr = btSwapEndian(*intPtr); - + dataLen = *intPtr; - + intPtr++; cp = (char*)intPtr; int i; for ( i=0; im_ptr; } m_uniqueIdGenerator++; - + btPointerUid uid; uid.m_uniqueIds[0] = m_uniqueIdGenerator; uid.m_uniqueIds[1] = m_uniqueIdGenerator; @@ -556,17 +557,17 @@ public: } chunk->m_dna_nr = getReverseType(structType); - + chunk->m_chunkCode = chunkCode; - + void* uniquePtr = getUniquePointer(oldPtr); - + m_chunkP.insert(oldPtr,uniquePtr);//chunk->m_oldPtr); chunk->m_oldPtr = uniquePtr;//oldPtr; - + } - + virtual unsigned char* internalAlloc(size_t size) { unsigned char* ptr = 0; @@ -584,7 +585,7 @@ public: return ptr; } - + virtual btChunk* allocate(size_t size, int numElements) { @@ -592,15 +593,15 @@ public: unsigned char* ptr = internalAlloc(int(size)*numElements+sizeof(btChunk)); unsigned char* data = ptr + sizeof(btChunk); - + btChunk* chunk = (btChunk*)ptr; chunk->m_chunkCode = 0; chunk->m_oldPtr = data; chunk->m_length = int(size)*numElements; chunk->m_number = numElements; - + m_chunkPtrs.push_back(chunk); - + return chunk; } @@ -668,6 +669,180 @@ public: } }; +///In general it is best to use btDefaultSerializer, +///in particular when writing the data to disk or sending it over the network. +///The btInMemorySerializer is experimental and only suitable in a few cases. +///The btInMemorySerializer takes a shortcut and can be useful to create a deep-copy +///of objects. There will be a demo on how to use the btInMemorySerializer. +struct btInMemorySerializer : public btDefaultSerializer +{ + btHashMap m_uid2ChunkPtr; + btHashMap m_orgPtr2UniqueDataPtr; + btHashMap m_names2Ptr; + btHashMap m_skipPointers; + + btBulletSerializedArrays m_arrays; + + + virtual void startSerialization() + { + m_uid2ChunkPtr.clear(); + //todo: m_arrays.clear(); + btDefaultSerializer::startSerialization(); + } + + btChunk* findChunkFromUniquePointer(void* uniquePointer) + { + btChunk** chkPtr = m_uid2ChunkPtr[uniquePointer]; + if (chkPtr) + { + return *chkPtr; + } + return 0; + } + + virtual void registerNameForPointer(const void* ptr, const char* name) + { + btDefaultSerializer::registerNameForPointer(ptr,name); + m_names2Ptr.insert(name,ptr); + } + + virtual void finishSerialization() + { + } + + virtual void* getUniquePointer(void*oldPtr) + { + if (oldPtr==0) + return 0; + + // void* uniquePtr = getUniquePointer(oldPtr); + btChunk* chunk = findChunkFromUniquePointer(oldPtr); + if (chunk) + { + return chunk->m_oldPtr; + } else + { + const char* n = (const char*) oldPtr; + const void** ptr = m_names2Ptr[n]; + if (ptr) + { + return oldPtr; + } else + { + void** ptr2 = m_skipPointers[oldPtr]; + if (ptr2) + { + return 0; + } else + { + //If this assert hit, serialization happened in the wrong order + // 'getUniquePointer' + btAssert(0); + } + + } + return 0; + } + return oldPtr; + } + + virtual void finalizeChunk(btChunk* chunk, const char* structType, int chunkCode,void* oldPtr) + { + if (!(m_serializationFlags&BT_SERIALIZE_NO_DUPLICATE_ASSERT)) + { + btAssert(!findPointer(oldPtr)); + } + + chunk->m_dna_nr = getReverseType(structType); + chunk->m_chunkCode = chunkCode; + //void* uniquePtr = getUniquePointer(oldPtr); + m_chunkP.insert(oldPtr,oldPtr);//chunk->m_oldPtr); + // chunk->m_oldPtr = uniquePtr;//oldPtr; + + void* uid = findPointer(oldPtr); + m_uid2ChunkPtr.insert(uid,chunk); + + switch (chunk->m_chunkCode) + { + case BT_SOFTBODY_CODE: + { + #ifdef BT_USE_DOUBLE_PRECISION + m_arrays.m_softBodyDoubleData.push_back((btSoftBodyDoubleData*) chunk->m_oldPtr); + #else + m_arrays.m_softBodyFloatData.push_back((btSoftBodyFloatData*) chunk->m_oldPtr); + #endif + break; + } + case BT_COLLISIONOBJECT_CODE: + { + #ifdef BT_USE_DOUBLE_PRECISION + m_arrays.m_collisionObjectDataDouble.push_back((btCollisionObjectDoubleData*)chunk->m_oldPtr); + #else//BT_USE_DOUBLE_PRECISION + m_arrays.m_collisionObjectDataFloat.push_back((btCollisionObjectFloatData*)chunk->m_oldPtr); + #endif //BT_USE_DOUBLE_PRECISION + break; + } + case BT_RIGIDBODY_CODE: + { + #ifdef BT_USE_DOUBLE_PRECISION + m_arrays.m_rigidBodyDataDouble.push_back((btRigidBodyDoubleData*)chunk->m_oldPtr); + #else + m_arrays.m_rigidBodyDataFloat.push_back((btRigidBodyFloatData*)chunk->m_oldPtr); + #endif//BT_USE_DOUBLE_PRECISION + break; + }; + case BT_CONSTRAINT_CODE: + { + #ifdef BT_USE_DOUBLE_PRECISION + m_arrays.m_constraintDataDouble.push_back(btTypedConstraintDoubleData*)chunk->m_oldPtr); + #else + m_arrays.m_constraintDataFloat.push_back((btTypedConstraintFloatData*)chunk->m_oldPtr); + #endif + break; + } + case BT_QUANTIZED_BVH_CODE: + { + #ifdef BT_USE_DOUBLE_PRECISION + m_arrays.m_bvhsFloat.push_back((btQuantizedBvhDoubleData*) chunk->m_oldPtr); + #else + m_arrays.m_bvhsFloat.push_back((btQuantizedBvhFloatData*) chunk->m_oldPtr); + #endif + break; + } + + case BT_SHAPE_CODE: + { + btCollisionShapeData* shapeData = (btCollisionShapeData*) chunk->m_oldPtr; + m_arrays.m_colShapeData.push_back(shapeData); + break; + } + case BT_TRIANLGE_INFO_MAP: + case BT_ARRAY_CODE: + case BT_SBMATERIAL_CODE: + case BT_SBNODE_CODE: + case BT_DYNAMICSWORLD_CODE: + case BT_DNA_CODE: + { + break; + } + default: + { + } + }; + } + + int getNumChunks() const + { + return m_uid2ChunkPtr.size(); + } + + const btChunk* getChunk(int chunkIndex) const + { + return *m_uid2ChunkPtr.getAtIndex(chunkIndex); + } + +}; #endif //BT_SERIALIZER_H