From f3424f491c4b76a55dc8fd7d5c2460110e6097a5 Mon Sep 17 00:00:00 2001 From: ejcoumans Date: Thu, 1 Nov 2007 05:50:50 +0000 Subject: [PATCH] cleanup memory in CcdPhysicsDemo, RagdollDemo, ConcaveDemo, BspDemo (work in progress) --- Demos/BspDemo/BspDemo.cpp | 51 +++++- Demos/BspDemo/BspDemo.h | 24 +++ Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp | 147 ++++++++++-------- Demos/CcdPhysicsDemo/CcdPhysicsDemo.h | 31 ++++ Demos/ConcaveDemo/ConcaveDemo.h | 30 ++++ Demos/ConcaveDemo/ConcavePhysicsDemo.cpp | 93 +++++++++-- .../ConvexDecompositionDemo.cpp | 81 ++++++++-- .../ConvexDecompositionDemo.h | 32 +++- Demos/RagdollDemo/RagdollDemo.cpp | 70 ++++++++- Demos/RagdollDemo/RagdollDemo.h | 25 +++ .../btBvhTriangleMeshShape.cpp | 2 + 11 files changed, 479 insertions(+), 107 deletions(-) diff --git a/Demos/BspDemo/BspDemo.cpp b/Demos/BspDemo/BspDemo.cpp index f6012eae8..74e4ca806 100644 --- a/Demos/BspDemo/BspDemo.cpp +++ b/Demos/BspDemo/BspDemo.cpp @@ -47,11 +47,11 @@ subject to the following restrictions: ///BspToBulletConverter extends the BspConverter to convert to Bullet datastructures class BspToBulletConverter : public BspConverter { - DemoApplication* m_demoApp; + BspDemo* m_demoApp; public: - BspToBulletConverter(DemoApplication* demoApp) + BspToBulletConverter(BspDemo* demoApp) :m_demoApp(demoApp) { } @@ -69,7 +69,9 @@ public: startTransform.setIdentity(); startTransform.setOrigin(btVector3(0,0,-10.f)); //this create an internal copy of the vertices + btCollisionShape* shape = new btConvexHullShape(&(vertices[0].getX()),vertices.size()); + m_demoApp->m_collisionShapes.push_back(shape); //btRigidBody* body = m_demoApp->localCreateRigidBody(mass, startTransform,shape); m_demoApp->localCreateRigidBody(mass, startTransform,shape); @@ -91,7 +93,42 @@ public: BspDemo::~BspDemo() { + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;jsetGravity(-m_cameraUp * 10); diff --git a/Demos/BspDemo/BspDemo.h b/Demos/BspDemo/BspDemo.h index eaf12ac56..d53e75614 100644 --- a/Demos/BspDemo/BspDemo.h +++ b/Demos/BspDemo/BspDemo.h @@ -16,12 +16,36 @@ subject to the following restrictions: #define BSP_DEMO_H #include "DemoApplication.h" +#include "LinearMath/btAlignedObjectArray.h" + +class btBroadphaseInterface; +class btCollisionShape; +class btOverlappingPairCache; +class btCollisionDispatcher; +class btConstraintSolver; +struct btCollisionAlgorithmCreateFunc; +class btDefaultCollisionConfiguration; + ///BspDemo shows the convex collision detection, by converting a Quake BSP file into convex objects and allowing interaction with boxes. class BspDemo : public DemoApplication { public: + //keep the collision shapes, for deletion/cleanup + btAlignedObjectArray m_collisionShapes; + + btBroadphaseInterface* m_broadphase; + + btCollisionDispatcher* m_dispatcher; + + btConstraintSolver* m_solver; + + btDefaultCollisionConfiguration* m_collisionConfiguration; + + + + virtual ~BspDemo(); void initPhysics(char* bspfilename); diff --git a/Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp b/Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp index da0a6f050..35d532a05 100644 --- a/Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp +++ b/Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp @@ -114,9 +114,7 @@ int shapeIndex[maxNumObjects]; #define EXTRA_HEIGHT -10.f //GL_LineSegmentShape shapeE(btPoint3(-50,0,0), // btPoint3(50,0,0)); -static const int numShapes = 4; -btCollisionShape* shapePtr[numShapes] = {0,0,0,0}; void CcdPhysicsDemo::createStack( btCollisionShape* boxShape, float halfCubeSize, int size, float zPos ) { @@ -236,11 +234,6 @@ void CcdPhysicsDemo::clientMoveAndDisplay() if (m_dynamicsWorld) { - //swap solver -#ifdef COMPARE_WITH_QUICKSTEP - m_dynamicsWorld->setConstraintSolver( new OdeConstraintSolver()); -#endif //COMPARE_WITH_QUICKSTEP - //#define FIXED_STEP 1 #ifdef FIXED_STEP m_dynamicsWorld->stepSimulation(1.0f/60.f,0); @@ -330,38 +323,22 @@ float myFrictionModel( btRigidBody& body1, btRigidBody& body2, btManifoldPoint& void CcdPhysicsDemo::initPhysics() { - - shapePtr[0] = - ///Please don't make the box sizes larger then 1000: the collision detection will be inaccurate. - ///See http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=346 - //#define USE_GROUND_PLANE 1 #ifdef USE_GROUND_PLANE - new btStaticPlaneShape(btVector3(0,1,0),0.5); + m_collisionShapes.push_back(new btStaticPlaneShape(btVector3(0,1,0),0.5)); #else - new btBoxShape (btVector3(200,CUBE_HALF_EXTENTS,200)); + + ///Please don't make the box sizes larger then 1000: the collision detection will be inaccurate. + ///See http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=346 + m_collisionShapes.push_back(new btBoxShape (btVector3(200,CUBE_HALF_EXTENTS,200))); #endif - shapePtr[1] = #ifdef DO_BENCHMARK_PYRAMIDS - new btBoxShape (btVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS)); + m_collisionShapes.push_back(new btBoxShape (btVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS))); #else - new btCylinderShape (btVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS)); + m_collisionShapes.push_back(new btCylinderShape (btVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS))); #endif - - shapePtr[2] = - //new btSphereShape (CUBE_HALF_EXTENTS); - //new btCapsuleShape(0.5*CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS); - //new btCylinderShape (btVector3(1-gCollisionMargin,CUBE_HALF_EXTENTS-gCollisionMargin,1-gCollisionMargin)); - //new btConeShapeX(CUBE_HALF_EXTENTS,2.f*CUBE_HALF_EXTENTS); - - new btSphereShape (CUBE_HALF_EXTENTS); - - //new btBU_Simplex1to4(btPoint3(-1,-1,-1),btPoint3(1,-1,-1),btPoint3(-1,1,-1),btPoint3(0,0,1)); - - //new btEmptyShape(); - - shapePtr[3] = new btBoxShape (btVector3(0.4,1,0.8)); + #ifdef DO_BENCHMARK_PYRAMIDS @@ -372,8 +349,8 @@ void CcdPhysicsDemo::initPhysics() m_azi = 90.f; #endif //DO_BENCHMARK_PYRAMIDS - btCollisionDispatcher* dispatcher=0; - btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration(); + m_dispatcher=0; + m_collisionConfiguration = new btDefaultCollisionConfiguration(); #ifdef USE_PARALLEL_DISPATCHER int maxNumOutstandingTasks = 4; @@ -413,41 +390,34 @@ int maxNumOutstandingTasks = 4; #endif - dispatcher = new SpuGatheringCollisionDispatcher(threadSupportCollision,maxNumOutstandingTasks,collisionConfiguration); -// dispatcher = new btCollisionDispatcher(collisionConfiguration); + m_dispatcher = new SpuGatheringCollisionDispatcher(threadSupportCollision,maxNumOutstandingTasks,m_collisionConfiguration); +// m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); #else - dispatcher = new btCollisionDispatcher(collisionConfiguration); + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); #endif //USE_PARALLEL_DISPATCHER #ifdef USE_CUSTOM_NEAR_CALLBACK //this is optional - dispatcher->setNearCallback(customNearCallback); + m_dispatcher->setNearCallback(customNearCallback); #endif btVector3 worldAabbMin(-1000,-1000,-1000); btVector3 worldAabbMax(1000,1000,1000); - btBroadphaseInterface* broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax,maxProxies); + m_broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax,maxProxies); /// For large worlds or over 16384 objects, use the bt32BitAxisSweep3 broadphase -// btBroadphaseInterface* broadphase = new bt32BitAxisSweep3(worldAabbMin,worldAabbMax,maxProxies); +// m_broadphase = new bt32BitAxisSweep3(worldAabbMin,worldAabbMax,maxProxies); /// When trying to debug broadphase issues, try to use the btSimpleBroadphase -// btBroadphaseInterface* broadphase = new btSimpleBroadphase; +// m_broadphase = new btSimpleBroadphase; -#ifdef REGISTER_CUSTOM_COLLISION_ALGORITHM - dispatcher->registerCollisionCreateFunc(SPHERE_SHAPE_PROXYTYPE,SPHERE_SHAPE_PROXYTYPE,new btSphereSphereCollisionAlgorithm::CreateFunc); //box-box is in Extras/AlternativeCollisionAlgorithms:it requires inclusion of those files #ifdef REGISTER_BOX_BOX - dispatcher->registerCollisionCreateFunc(BOX_SHAPE_PROXYTYPE,BOX_SHAPE_PROXYTYPE,new BoxBoxCollisionAlgorithm::CreateFunc); + m_dispatcher->registerCollisionCreateFunc(BOX_SHAPE_PROXYTYPE,BOX_SHAPE_PROXYTYPE,new BoxBoxCollisionAlgorithm::CreateFunc); #endif //REGISTER_BOX_BOX - dispatcher->registerCollisionCreateFunc(SPHERE_SHAPE_PROXYTYPE,TRIANGLE_SHAPE_PROXYTYPE,new btSphereTriangleCollisionAlgorithm::CreateFunc); - btSphereTriangleCollisionAlgorithm::CreateFunc* triangleSphereCF = new btSphereTriangleCollisionAlgorithm::CreateFunc; - triangleSphereCF->m_swapped = true; - dispatcher->registerCollisionCreateFunc(TRIANGLE_SHAPE_PROXYTYPE,SPHERE_SHAPE_PROXYTYPE,triangleSphereCF); -#endif //REGISTER_CUSTOM_COLLISION_ALGORITHM #ifdef COMPARE_WITH_QUICKSTEP - btConstraintSolver* solver = new OdeConstraintSolver(); + m_solver = new OdeConstraintSolver(); #else @@ -459,11 +429,11 @@ int maxNumOutstandingTasks = 4; createSolverLocalStoreMemory, maxNumOutstandingTasks)); - btConstraintSolver* solver = new btParallelSequentialImpulseSolver(threadSupportSolver,maxNumOutstandingTasks); + m_solver = new btParallelSequentialImpulseSolver(threadSupportSolver,maxNumOutstandingTasks); #else - btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver; + m_solver = new btSequentialImpulseConstraintSolver; //default solverMode is SOLVER_RANDMIZE_ORDER. Warmstarting seems not to improve convergence, see - //solver->setSolverMode(btSequentialImpulseConstraintSolver::SOLVER_USE_WARMSTARTING | btSequentialImpulseConstraintSolver::SOLVER_RANDMIZE_ORDER); + //m_solver->setSolverMode(btSequentialImpulseConstraintSolver::SOLVER_USE_WARMSTARTING | btSequentialImpulseConstraintSolver::SOLVER_RANDMIZE_ORDER); #endif //USE_PARALLEL_SOLVER @@ -471,10 +441,10 @@ int maxNumOutstandingTasks = 4; #ifdef USER_DEFINED_FRICTION_MODEL //user defined friction model is not supported in 'cache friendly' solver yet, so switch to old solver - solver->setSolverMode(btSequentialImpulseConstraintSolver::SOLVER_RANDMIZE_ORDER); + m_solver->setSolverMode(btSequentialImpulseConstraintSolver::SOLVER_RANDMIZE_ORDER); #endif //USER_DEFINED_FRICTION_MODEL - btDiscreteDynamicsWorld* world = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration); + btDiscreteDynamicsWorld* world = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); m_dynamicsWorld = world; #ifdef DO_BENCHMARK_PYRAMIDS @@ -488,10 +458,10 @@ int maxNumOutstandingTasks = 4; #ifdef USER_DEFINED_FRICTION_MODEL { - //solver->setContactSolverFunc(ContactSolverFunc func,USER_CONTACT_SOLVER_TYPE1,DEFAULT_CONTACT_SOLVER_TYPE); - solver->SetFrictionSolverFunc(myFrictionModel,USER_CONTACT_SOLVER_TYPE1,DEFAULT_CONTACT_SOLVER_TYPE); - solver->SetFrictionSolverFunc(myFrictionModel,DEFAULT_CONTACT_SOLVER_TYPE,USER_CONTACT_SOLVER_TYPE1); - solver->SetFrictionSolverFunc(myFrictionModel,USER_CONTACT_SOLVER_TYPE1,USER_CONTACT_SOLVER_TYPE1); + //m_solver->setContactSolverFunc(ContactSolverFunc func,USER_CONTACT_SOLVER_TYPE1,DEFAULT_CONTACT_SOLVER_TYPE); + m_solver->SetFrictionSolverFunc(myFrictionModel,USER_CONTACT_SOLVER_TYPE1,DEFAULT_CONTACT_SOLVER_TYPE); + m_solver->SetFrictionSolverFunc(myFrictionModel,DEFAULT_CONTACT_SOLVER_TYPE,USER_CONTACT_SOLVER_TYPE1); + m_solver->SetFrictionSolverFunc(myFrictionModel,USER_CONTACT_SOLVER_TYPE1,USER_CONTACT_SOLVER_TYPE1); //m_physicsEnvironmentPtr->setNumIterations(2); } #endif //USER_DEFINED_FRICTION_MODEL @@ -517,8 +487,8 @@ int maxNumOutstandingTasks = 4; if (useCompound) { btCompoundShape* compoundShape = new btCompoundShape(); - btCollisionShape* oldShape = shapePtr[1]; - shapePtr[1] = compoundShape; + btCollisionShape* oldShape = m_collisionShapes[1]; + m_collisionShapes[1] = compoundShape; btVector3 sphereOffset(0,0,2); comOffset.setIdentity(); @@ -538,7 +508,7 @@ int maxNumOutstandingTasks = 4; for (i=0;isetMargin(gCollisionMargin); bool isDyna = i>0; @@ -610,7 +580,7 @@ int maxNumOutstandingTasks = 4; - localCreateRigidBody(0.f,trans,shapePtr[shapeIndex[0]]); + localCreateRigidBody(0.f,trans,m_collisionShapes[shapeIndex[0]]); int numWalls = 15; int wallHeight = 15; @@ -620,11 +590,11 @@ int maxNumOutstandingTasks = 4; for (int i=0;igetNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;j m_collisionShapes; + + btBroadphaseInterface* m_broadphase; + + btCollisionDispatcher* m_dispatcher; + + btConstraintSolver* m_solver; + + btCollisionAlgorithmCreateFunc* m_boxBoxCF; + + btDefaultCollisionConfiguration* m_collisionConfiguration; + + public: void initPhysics(); + void exitPhysics(); + + virtual ~CcdPhysicsDemo() + { + exitPhysics(); + } + virtual void clientMoveAndDisplay(); virtual void displayCallback(); diff --git a/Demos/ConcaveDemo/ConcaveDemo.h b/Demos/ConcaveDemo/ConcaveDemo.h index 32faa4731..00be1139f 100644 --- a/Demos/ConcaveDemo/ConcaveDemo.h +++ b/Demos/ConcaveDemo/ConcaveDemo.h @@ -16,12 +16,35 @@ subject to the following restrictions: #define CONCAVE_DEMO_H #include "DemoApplication.h" +#include "LinearMath/btAlignedObjectArray.h" + +class btBroadphaseInterface; +class btCollisionShape; +class btOverlappingPairCache; +class btCollisionDispatcher; +class btConstraintSolver; +struct btCollisionAlgorithmCreateFunc; +class btDefaultCollisionConfiguration; +class btTriangleIndexVertexArray; ///ConcaveDemo shows usage of static concave triangle meshes ///It also shows per-triangle material (friction/restitution) through CustomMaterialCombinerCallback class ConcaveDemo : public DemoApplication { + //keep the collision shapes, for deletion/cleanup + btAlignedObjectArray m_collisionShapes; + + btTriangleIndexVertexArray* m_indexVertexArrays; + + btBroadphaseInterface* m_broadphase; + + btCollisionDispatcher* m_dispatcher; + + btConstraintSolver* m_solver; + + btDefaultCollisionConfiguration* m_collisionConfiguration; + bool m_animatedMesh; public: @@ -32,6 +55,13 @@ class ConcaveDemo : public DemoApplication } void initPhysics(); + void exitPhysics(); + + virtual ~ConcaveDemo() + { + exitPhysics(); + } + virtual void clientMoveAndDisplay(); virtual void displayCallback(); diff --git a/Demos/ConcaveDemo/ConcavePhysicsDemo.cpp b/Demos/ConcaveDemo/ConcavePhysicsDemo.cpp index f3831a5fc..940fb0856 100644 --- a/Demos/ConcaveDemo/ConcavePhysicsDemo.cpp +++ b/Demos/ConcaveDemo/ConcavePhysicsDemo.cpp @@ -142,6 +142,8 @@ void ConcaveDemo::initPhysics() gContactAddedCallback = CustomMaterialCombinerCallback; +#define USE_TRIMESH_SHAPE 1 +#ifdef USE_TRIMESH_SHAPE int vertStride = sizeof(btVector3); int indexStride = 3*sizeof(int); @@ -171,8 +173,8 @@ void ConcaveDemo::initPhysics() gIndices[index++] = (j+1)*NUM_VERTS_X+i; } } - - btTriangleIndexVertexArray* indexVertexArrays = new btTriangleIndexVertexArray(totalTriangles, + + m_indexVertexArrays = new btTriangleIndexVertexArray(totalTriangles, gIndices, indexStride, totalVerts,(btScalar*) &gVertices[0].x(),vertStride); @@ -182,7 +184,9 @@ void ConcaveDemo::initPhysics() //comment out the next line to read the BVH from disk (first run the demo once to create the BVH) #define SERIALIZE_TO_DISK 1 #ifdef SERIALIZE_TO_DISK - trimeshShape = new btBvhTriangleMeshShape(indexVertexArrays,useQuantizedAabbCompression); + trimeshShape = new btBvhTriangleMeshShape(m_indexVertexArrays,useQuantizedAabbCompression); + m_collisionShapes.push_back(trimeshShape); + ///we can serialize the BVH data void* buffer = 0; @@ -193,10 +197,13 @@ void ConcaveDemo::initPhysics() FILE* file = fopen("bvh.bin","wb"); fwrite(buffer,1,numBytes,file); fclose(file); + btAlignedFree(buffer); + + #else - trimeshShape = new btBvhTriangleMeshShape(indexVertexArrays,useQuantizedAabbCompression,false); + trimeshShape = new btBvhTriangleMeshShape(m_indexVertexArrays,useQuantizedAabbCompression,false); char* fileName = "bvh.bin"; @@ -225,9 +232,15 @@ void ConcaveDemo::initPhysics() #endif -// btCollisionShape* groundShape = new btBoxShape(btVector3(50,3,50)); + btCollisionShape* groundShape = trimeshShape; + +#else + btCollisionShape* groundShape = new btBoxShape(btVector3(50,3,50)); + m_collisionShapes.push_back(groundShape); -btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration(); +#endif //USE_TRIMESH_SHAPE + + m_collisionConfiguration = new btDefaultCollisionConfiguration(); #ifdef USE_PARALLEL_DISPATCHER @@ -247,17 +260,17 @@ btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollision ///you can hook it up to your custom task scheduler by deriving from btThreadSupportInterface #endif - btCollisionDispatcher* dispatcher = new SpuGatheringCollisionDispatcher(threadSupport,maxNumOutstandingTasks,collisionConfiguration); + m_dispatcher = new SpuGatheringCollisionDispatcher(threadSupport,maxNumOutstandingTasks,m_collisionConfiguration); #else - btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration); + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); #endif//USE_PARALLEL_DISPATCHER btVector3 worldMin(-1000,-1000,-1000); btVector3 worldMax(1000,1000,1000); - btBroadphaseInterface* pairCache = new btAxisSweep3(worldMin,worldMax); - btConstraintSolver* constraintSolver = new btSequentialImpulseConstraintSolver(); - m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration); + m_broadphase = new btAxisSweep3(worldMin,worldMax); + m_solver = new btSequentialImpulseConstraintSolver(); + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); #ifdef USE_PARALLEL_DISPATCHER m_dynamicsWorld->getDispatchInfo().m_enableSPU=true; #endif //USE_PARALLEL_DISPATCHER @@ -267,10 +280,12 @@ btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollision startTransform.setIdentity(); startTransform.setOrigin(btVector3(0,-2,0)); + btCollisionShape* colShape = new btBoxShape(btVector3(1,1,1)); + m_collisionShapes.push_back(colShape); + { for (int i=0;i<10;i++) { - btCollisionShape* colShape = new btBoxShape(btVector3(1,1,1)); //btCollisionShape* colShape = new btCapsuleShape(0.5,2.0);//boxShape = new btSphereShape(1.f); startTransform.setOrigin(btVector3(2*i,10,1)); localCreateRigidBody(1, startTransform,colShape); @@ -278,7 +293,7 @@ btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollision } startTransform.setIdentity(); - staticBody = localCreateRigidBody(mass, startTransform,trimeshShape); + staticBody = localCreateRigidBody(mass, startTransform,groundShape); staticBody->setCollisionFlags(staticBody->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT); @@ -332,3 +347,55 @@ void ConcaveDemo::displayCallback(void) { } + +void ConcaveDemo::exitPhysics() +{ + + + + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;jgetDispatchInfo().m_enableSPU = true; @@ -121,7 +116,9 @@ void ConvexDecompositionDemo::initPhysics(const char* filename) startTransform.setIdentity(); startTransform.setOrigin(btVector3(0,-4.5,0)); - localCreateRigidBody(0.f,startTransform,new btBoxShape(btVector3(30,2,30))); + btCollisionShape* boxShape = new btBoxShape(btVector3(30,2,30)); + m_collisionShapes.push_back(boxShape); + localCreateRigidBody(0.f,startTransform,boxShape); class MyConvexDecomposition : public ConvexDecomposition::ConvexDecompInterface { @@ -259,6 +256,8 @@ void ConvexDecompositionDemo::initPhysics(const char* filename) #endif convexShape->setMargin(0.01); + + m_convexDemo->m_collisionShapes.push_back(convexShape); btTransform trans; @@ -278,7 +277,7 @@ void ConvexDecompositionDemo::initPhysics(const char* filename) }; - if (tcount) + if (0)//tcount) { btTriangleMesh* trimesh = new btTriangleMesh(); @@ -302,6 +301,8 @@ void ConvexDecompositionDemo::initPhysics(const char* filename) } btCollisionShape* convexShape = new btConvexTriangleMeshShape(trimesh); + m_collisionShapes.push_back(convexShape); + float mass = 1.f; btTransform startTransform; @@ -395,3 +396,53 @@ void ConvexDecompositionDemo::displayCallback(void) { glutSwapBuffers(); } + + + +void ConvexDecompositionDemo::exitPhysics() +{ + + + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;j m_collisionShapes; + + btBroadphaseInterface* m_broadphase; + + btCollisionDispatcher* m_dispatcher; + + btConstraintSolver* m_solver; + + btDefaultCollisionConfiguration* m_collisionConfiguration; + + void initPhysics(const char* filename); + void exitPhysics(); + + virtual ~ConvexDecompositionDemo() + { + exitPhysics(); + } + virtual void clientMoveAndDisplay(); virtual void displayCallback(); diff --git a/Demos/RagdollDemo/RagdollDemo.cpp b/Demos/RagdollDemo/RagdollDemo.cpp index 503953d5d..ed9ae59f0 100644 --- a/Demos/RagdollDemo/RagdollDemo.cpp +++ b/Demos/RagdollDemo/RagdollDemo.cpp @@ -276,7 +276,7 @@ public: m_ownerWorld->addConstraint(m_joints[JOINT_RIGHT_ELBOW], true); } - ~RagDoll () + virtual ~RagDoll () { int i; @@ -309,22 +309,23 @@ void RagdollDemo::initPhysics() setCameraDistance(btScalar(5.)); - btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration(); + m_collisionConfiguration = new btDefaultCollisionConfiguration(); - btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration); + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); btPoint3 worldAabbMin(-10000,-10000,-10000); btPoint3 worldAabbMax(10000,10000,10000); - btBroadphaseInterface* overlappingPairCache = new btAxisSweep3 (worldAabbMin, worldAabbMax); + m_broadphase = new btAxisSweep3 (worldAabbMin, worldAabbMax); - btConstraintSolver* solver = new btSequentialImpulseConstraintSolver; + m_solver = new btSequentialImpulseConstraintSolver; - m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,overlappingPairCache,solver,collisionConfiguration); + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); // Setup a big ground box { btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(200.),btScalar(10.),btScalar(200.))); + m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0,-10,0)); @@ -390,3 +391,60 @@ void RagdollDemo::keyboardCallback(unsigned char key, int x, int y) } + + + +void RagdollDemo::exitPhysics() +{ + + int i; + + for (i=0;igetNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;j m_ragdolls; + //keep the collision shapes, for deletion/cleanup + btAlignedObjectArray m_collisionShapes; + + btBroadphaseInterface* m_broadphase; + + btCollisionDispatcher* m_dispatcher; + + btConstraintSolver* m_solver; + + btDefaultCollisionConfiguration* m_collisionConfiguration; + public: void initPhysics(); + void exitPhysics(); + + virtual ~RagdollDemo() + { + exitPhysics(); + } + void spawnRagdoll(bool random = false); virtual void clientMoveAndDisplay(); diff --git a/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp b/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp index 6d9035a91..eea263fe5 100644 --- a/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp +++ b/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp @@ -87,6 +87,7 @@ btBvhTriangleMeshShape::~btBvhTriangleMeshShape() { if (m_ownsBvh) { + m_bvh->~btOptimizedBvh(); btAlignedFree(m_bvh); } } @@ -186,6 +187,7 @@ void btBvhTriangleMeshShape::setLocalScaling(const btVector3& scaling) btTriangleMeshShape::setLocalScaling(scaling); if (m_ownsBvh) { + m_bvh->~btOptimizedBvh(); btAlignedFree(m_bvh); } ///m_localAabbMin/m_localAabbMax is already re-calculated in btTriangleMeshShape. We could just scale aabb, but this needs some more work