Add first version of btBulletXmlWorldImporter, still incomplete but it can read some files Fix false assert in btSequentialImpulseConstraintSolver
289 lines
8.1 KiB
C++
289 lines
8.1 KiB
C++
/*
|
|
Bullet Continuous Collision Detection and Physics Library
|
|
Copyright (c) 2003-2012 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 "btBulletWorldImporter.h"
|
|
#include "../BulletFileLoader/btBulletFile.h"
|
|
|
|
#include "btBulletDynamicsCommon.h"
|
|
#include "BulletCollision/Gimpact/btGImpactShape.h"
|
|
|
|
|
|
|
|
//#define USE_INTERNAL_EDGE_UTILITY
|
|
#ifdef USE_INTERNAL_EDGE_UTILITY
|
|
#include "BulletCollision/CollisionDispatch/btInternalEdgeUtility.h"
|
|
#endif //USE_INTERNAL_EDGE_UTILITY
|
|
|
|
btBulletWorldImporter::btBulletWorldImporter(btDynamicsWorld* world)
|
|
:btWorldImporter(world)
|
|
{
|
|
}
|
|
|
|
btBulletWorldImporter::~btBulletWorldImporter()
|
|
{
|
|
}
|
|
|
|
|
|
bool btBulletWorldImporter::loadFile( const char* fileName)
|
|
{
|
|
bParse::btBulletFile* bulletFile2 = new bParse::btBulletFile(fileName);
|
|
|
|
bool result = loadFileFromMemory(bulletFile2);
|
|
|
|
delete bulletFile2;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool btBulletWorldImporter::loadFileFromMemory( char* memoryBuffer, int len)
|
|
{
|
|
bParse::btBulletFile* bulletFile2 = new bParse::btBulletFile(memoryBuffer,len);
|
|
|
|
bool result = loadFileFromMemory(bulletFile2);
|
|
|
|
delete bulletFile2;
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
|
|
bool btBulletWorldImporter::loadFileFromMemory( bParse::btBulletFile* bulletFile2)
|
|
{
|
|
bool ok = (bulletFile2->getFlags()& bParse::FD_OK)!=0;
|
|
|
|
if (ok)
|
|
bulletFile2->parse(m_verboseMode);
|
|
else
|
|
return false;
|
|
|
|
if (m_verboseMode & bParse::FD_VERBOSE_DUMP_CHUNKS)
|
|
{
|
|
bulletFile2->dumpChunks(bulletFile2->getFileDNA());
|
|
}
|
|
|
|
return convertAllObjects(bulletFile2);
|
|
|
|
}
|
|
|
|
bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile2)
|
|
{
|
|
|
|
m_shapeMap.clear();
|
|
m_bodyMap.clear();
|
|
|
|
int i;
|
|
|
|
for (i=0;i<bulletFile2->m_bvhs.size();i++)
|
|
{
|
|
btOptimizedBvh* bvh = createOptimizedBvh();
|
|
|
|
if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
|
|
{
|
|
btQuantizedBvhDoubleData* bvhData = (btQuantizedBvhDoubleData*)bulletFile2->m_bvhs[i];
|
|
bvh->deSerializeDouble(*bvhData);
|
|
} else
|
|
{
|
|
btQuantizedBvhFloatData* bvhData = (btQuantizedBvhFloatData*)bulletFile2->m_bvhs[i];
|
|
bvh->deSerializeFloat(*bvhData);
|
|
}
|
|
m_bvhMap.insert(bulletFile2->m_bvhs[i],bvh);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (i=0;i<bulletFile2->m_collisionShapes.size();i++)
|
|
{
|
|
btCollisionShapeData* shapeData = (btCollisionShapeData*)bulletFile2->m_collisionShapes[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;i<bulletFile2->m_rigidBodies.size();i++)
|
|
{
|
|
if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
|
|
{
|
|
btRigidBodyDoubleData* colObjData = (btRigidBodyDoubleData*)bulletFile2->m_rigidBodies[i];
|
|
btScalar mass = btScalar(colObjData->m_inverseMass? 1.f/colObjData->m_inverseMass : 0.f);
|
|
btVector3 localInertia;
|
|
localInertia.setZero();
|
|
btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionObjectData.m_collisionShape);
|
|
if (shapePtr && *shapePtr)
|
|
{
|
|
btTransform startTransform;
|
|
colObjData->m_collisionObjectData.m_worldTransform.m_origin.m_floats[3] = 0.f;
|
|
startTransform.deSerializeDouble(colObjData->m_collisionObjectData.m_worldTransform);
|
|
|
|
// startTransform.setBasis(btMatrix3x3::getIdentity());
|
|
btCollisionShape* shape = (btCollisionShape*)*shapePtr;
|
|
if (shape->isNonMoving())
|
|
{
|
|
mass = 0.f;
|
|
}
|
|
|
|
if (mass)
|
|
{
|
|
shape->calculateLocalInertia(mass,localInertia);
|
|
}
|
|
bool isDynamic = mass!=0.f;
|
|
|
|
btRigidBody* body = createRigidBody(isDynamic,mass,startTransform,shape,colObjData->m_collisionObjectData.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");
|
|
}
|
|
|
|
} else
|
|
{
|
|
btRigidBodyFloatData* colObjData = (btRigidBodyFloatData*)bulletFile2->m_rigidBodies[i];
|
|
convertRigidBody(colObjData);
|
|
}
|
|
}
|
|
|
|
for (i=0;i<bulletFile2->m_collisionObjects.size();i++)
|
|
{
|
|
if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
|
|
{
|
|
btCollisionObjectDoubleData* colObjData = (btCollisionObjectDoubleData*)bulletFile2->m_collisionObjects[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");
|
|
}
|
|
|
|
} else
|
|
{
|
|
btCollisionObjectFloatData* colObjData = (btCollisionObjectFloatData*)bulletFile2->m_collisionObjects[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");
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
for (i=0;i<bulletFile2->m_constraints.size();i++)
|
|
{
|
|
btTypedConstraintData* constraintData = (btTypedConstraintData*)bulletFile2->m_constraints[i];
|
|
btCollisionObject** colAptr = m_bodyMap.find(constraintData->m_rbA);
|
|
btCollisionObject** colBptr = m_bodyMap.find(constraintData->m_rbB);
|
|
|
|
btRigidBody* rbA = 0;
|
|
btRigidBody* rbB = 0;
|
|
|
|
if (colAptr)
|
|
{
|
|
rbA = btRigidBody::upcast(*colAptr);
|
|
if (!rbA)
|
|
rbA = &getFixedBody();
|
|
}
|
|
if (colBptr)
|
|
{
|
|
rbB = btRigidBody::upcast(*colBptr);
|
|
if (!rbB)
|
|
rbB = &getFixedBody();
|
|
}
|
|
if (!rbA && !rbB)
|
|
continue;
|
|
|
|
bool isDoublePrecisionData = bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION;
|
|
convertConstraint(constraintData, rbA,rbB,isDoublePrecisionData, bulletFile2->getVersion());
|
|
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|