re-organized memory (stack and pool) allocators. this lets the user pass in their own memory allocators.

This commit is contained in:
ejcoumans
2007-10-20 02:23:39 +00:00
parent 1e4e52306f
commit e7caaa28d3
37 changed files with 287 additions and 232 deletions

View File

@@ -187,9 +187,9 @@ void BasicDemo::initPhysics()
#ifdef USE_SIMPLE_DYNAMICS_WORLD #ifdef USE_SIMPLE_DYNAMICS_WORLD
//btSimpleDynamicsWorld doesn't support 'cache friendly' optimization, so disable this //btSimpleDynamicsWorld doesn't support 'cache friendly' optimization, so disable this
sol->setSolverMode(btSequentialImpulseConstraintSolver::SOLVER_RANDMIZE_ORDER); sol->setSolverMode(btSequentialImpulseConstraintSolver::SOLVER_RANDMIZE_ORDER);
m_dynamicsWorld = new btSimpleDynamicsWorld(m_dispatcher,m_overlappingPairCache,m_solver); m_dynamicsWorld = new btSimpleDynamicsWorld(m_dispatcher,m_overlappingPairCache,m_solver,collisionConfiguration);
#else #else
m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_overlappingPairCache,m_solver); m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_overlappingPairCache,m_solver,collisionConfiguration);
#endif //USE_SIMPLE_DYNAMICS_WORLD #endif //USE_SIMPLE_DYNAMICS_WORLD
m_dynamicsWorld->getDispatchInfo().m_enableSPU = true; m_dynamicsWorld->getDispatchInfo().m_enableSPU = true;

View File

@@ -144,7 +144,7 @@ void BspDemo::initPhysics(char* bspfilename)
//btOverlappingPairCache* broadphase = new btSimpleBroadphase(); //btOverlappingPairCache* broadphase = new btSimpleBroadphase();
btConstraintSolver* constraintSolver = new btSequentialImpulseConstraintSolver(); btConstraintSolver* constraintSolver = new btSequentialImpulseConstraintSolver();
//ConstraintSolver* solver = new OdeConstraintSolver; //ConstraintSolver* solver = new OdeConstraintSolver;
m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver); m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration);
m_dynamicsWorld->setGravity(-m_cameraUp * 10); m_dynamicsWorld->setGravity(-m_cameraUp * 10);
m_dynamicsWorld->setDebugDrawer(&debugDrawer); m_dynamicsWorld->setDebugDrawer(&debugDrawer);

View File

@@ -477,7 +477,7 @@ int maxNumOutstandingTasks = 4;
solver->setSolverMode(btSequentialImpulseConstraintSolver::SOLVER_RANDMIZE_ORDER); solver->setSolverMode(btSequentialImpulseConstraintSolver::SOLVER_RANDMIZE_ORDER);
#endif //USER_DEFINED_FRICTION_MODEL #endif //USER_DEFINED_FRICTION_MODEL
btDiscreteDynamicsWorld* world = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver); btDiscreteDynamicsWorld* world = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration);
m_dynamicsWorld = world; m_dynamicsWorld = world;
#ifdef DO_BENCHMARK_PYRAMIDS #ifdef DO_BENCHMARK_PYRAMIDS

View File

@@ -178,7 +178,7 @@ void ColladaDemo::initPhysics(const char* filename)
btVector3 worldMax(1000,1000,1000); btVector3 worldMax(1000,1000,1000);
btBroadphaseInterface* pairCache = new btAxisSweep3(worldMin,worldMax); btBroadphaseInterface* pairCache = new btAxisSweep3(worldMin,worldMax);
btConstraintSolver* constraintSolver = new btSequentialImpulseConstraintSolver(); btConstraintSolver* constraintSolver = new btSequentialImpulseConstraintSolver();
m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver); m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration);
//m_dynamicsWorld = new btSimpleDynamicsWorld(); //m_dynamicsWorld = new btSimpleDynamicsWorld();

View File

@@ -91,7 +91,7 @@ void CollisionInterfaceDemo::initPhysics()
//SimpleBroadphase is a brute force alternative, performing N^2 aabb overlap tests //SimpleBroadphase is a brute force alternative, performing N^2 aabb overlap tests
//SimpleBroadphase* broadphase = new btSimpleBroadphase; //SimpleBroadphase* broadphase = new btSimpleBroadphase;
collisionWorld = new btCollisionWorld(dispatcher,broadphase); collisionWorld = new btCollisionWorld(dispatcher,broadphase,collisionConfiguration);
collisionWorld->addCollisionObject(&objects[0]); collisionWorld->addCollisionObject(&objects[0]);
collisionWorld->addCollisionObject(&objects[1]); collisionWorld->addCollisionObject(&objects[1]);

View File

@@ -270,7 +270,7 @@ btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollision
btVector3 worldMax(1000,1000,1000); btVector3 worldMax(1000,1000,1000);
btBroadphaseInterface* pairCache = new btAxisSweep3(worldMin,worldMax); btBroadphaseInterface* pairCache = new btAxisSweep3(worldMin,worldMax);
btConstraintSolver* constraintSolver = new btSequentialImpulseConstraintSolver(); btConstraintSolver* constraintSolver = new btSequentialImpulseConstraintSolver();
m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver); m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration);
#ifdef USE_PARALLEL_DISPATCHER #ifdef USE_PARALLEL_DISPATCHER
m_dynamicsWorld->getDispatchInfo().m_enableSPU=true; m_dynamicsWorld->getDispatchInfo().m_enableSPU=true;
#endif //USE_PARALLEL_DISPATCHER #endif //USE_PARALLEL_DISPATCHER

View File

@@ -84,7 +84,7 @@ void ConstraintDemo::initPhysics()
//btBroadphaseInterface* broadphase = new btSimpleBroadphase(); //btBroadphaseInterface* broadphase = new btSimpleBroadphase();
btConstraintSolver* constraintSolver = new btSequentialImpulseConstraintSolver(); btConstraintSolver* constraintSolver = new btSequentialImpulseConstraintSolver();
//ConstraintSolver* solver = new OdeConstraintSolver; //ConstraintSolver* solver = new OdeConstraintSolver;
m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver); m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration);
//m_dynamicsWorld->setGravity(btVector3(0,0,0)); //m_dynamicsWorld->setGravity(btVector3(0,0,0));

View File

@@ -128,7 +128,7 @@ void ConvexDecompositionDemo::initPhysics(const char* filename)
//btBroadphaseInterface* broadphase = new btSimpleBroadphase(); //btBroadphaseInterface* broadphase = new btSimpleBroadphase();
btConstraintSolver* solver = new btSequentialImpulseConstraintSolver(); btConstraintSolver* solver = new btSequentialImpulseConstraintSolver();
m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver); m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration);
#ifdef USE_PARALLEL_DISPATCHER #ifdef USE_PARALLEL_DISPATCHER
m_dynamicsWorld->getDispatchInfo().m_enableSPU = true; m_dynamicsWorld->getDispatchInfo().m_enableSPU = true;

View File

@@ -89,7 +89,7 @@ void DoublePrecisionDemo::initPhysics()
btAxisSweep3* broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax); btAxisSweep3* broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax);
collisionWorld = new btCollisionWorld(dispatcher,broadphase); collisionWorld = new btCollisionWorld(dispatcher,broadphase,collisionConfiguration);
collisionWorld->addCollisionObject(&objects[0]); collisionWorld->addCollisionObject(&objects[0]);
collisionWorld->addCollisionObject(&objects[1]); collisionWorld->addCollisionObject(&objects[1]);

View File

@@ -1,153 +1,153 @@
/* /*
Bullet Continuous Collision Detection and Physics Library Bullet Continuous Collision Detection and Physics Library
Ragdoll Demo Ragdoll Demo
Copyright (c) 2007 Starbreeze Studios Copyright (c) 2007 Starbreeze Studios
This software is provided 'as-is', without any express or implied warranty. 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. 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, Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely, including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions: 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. 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. 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. 3. This notice may not be removed or altered from any source distribution.
Originally Written by: Marten Svanfeldt Originally Written by: Marten Svanfeldt
ReWritten by: Francisco Le<4C>n ReWritten by: Francisco Le<4C>n
*/ */
//#define USE_ODE_QUICKSTEP 1 //#define USE_ODE_QUICKSTEP 1
#include "btBulletDynamicsCommon.h" #include "btBulletDynamicsCommon.h"
#include "GlutStuff.h" #include "GlutStuff.h"
#include "GL_ShapeDrawer.h" #include "GL_ShapeDrawer.h"
#include "LinearMath/btIDebugDraw.h" #include "LinearMath/btIDebugDraw.h"
#include "GLDebugDrawer.h" #include "GLDebugDrawer.h"
#include "GenericJointDemo.h" #include "GenericJointDemo.h"
#ifdef USE_ODE_QUICKSTEP #ifdef USE_ODE_QUICKSTEP
#include "OdeConstraintSolver.h" #include "OdeConstraintSolver.h"
#endif #endif
GLDebugDrawer debugDrawer; GLDebugDrawer debugDrawer;
int main(int argc,char* argv[]) int main(int argc,char* argv[])
{ {
GenericJointDemo demoApp; GenericJointDemo demoApp;
// demoApp.configDebugDrawer(&debugDrawer); // demoApp.configDebugDrawer(&debugDrawer);
demoApp.initPhysics(); demoApp.initPhysics();
demoApp.setCameraDistance(btScalar(10.)); demoApp.setCameraDistance(btScalar(10.));
#ifdef USE_ODE_QUICKSTEP #ifdef USE_ODE_QUICKSTEP
return glutmain(argc, argv,640,480,"Joint 6DOF - ODE QuickStep Solver",&demoApp); return glutmain(argc, argv,640,480,"Joint 6DOF - ODE QuickStep Solver",&demoApp);
#else #else
return glutmain(argc, argv,640,480,"Joint 6DOF - Sequencial Impulse Solver",&demoApp); return glutmain(argc, argv,640,480,"Joint 6DOF - Sequencial Impulse Solver",&demoApp);
#endif #endif
}
void GenericJointDemo::initPhysics() }
{
// Setup the basic world
void GenericJointDemo::initPhysics()
{
// Setup the basic world
btDefaultCollisionConfiguration * collision_config = new btDefaultCollisionConfiguration(); btDefaultCollisionConfiguration * collision_config = new btDefaultCollisionConfiguration();
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collision_config); btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collision_config);
btPoint3 worldAabbMin(-10000,-10000,-10000); btPoint3 worldAabbMin(-10000,-10000,-10000);
btPoint3 worldAabbMax(10000,10000,10000); btPoint3 worldAabbMax(10000,10000,10000);
btBroadphaseInterface* overlappingPairCache = new btAxisSweep3 (worldAabbMin, worldAabbMax); btBroadphaseInterface* overlappingPairCache = new btAxisSweep3 (worldAabbMin, worldAabbMax);
#ifdef USE_ODE_QUICKSTEP #ifdef USE_ODE_QUICKSTEP
btConstraintSolver* constraintSolver = new OdeConstraintSolver(); btConstraintSolver* constraintSolver = new OdeConstraintSolver();
#else #else
btConstraintSolver* constraintSolver = new btSequentialImpulseConstraintSolver; btConstraintSolver* constraintSolver = new btSequentialImpulseConstraintSolver;
#endif #endif
m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,overlappingPairCache,constraintSolver);
m_dynamicsWorld->setGravity(btVector3(0,-30,0));
m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,overlappingPairCache,constraintSolver,collision_config);
m_dynamicsWorld->setGravity(btVector3(0,-30,0));
m_dynamicsWorld->setDebugDrawer(&debugDrawer); m_dynamicsWorld->setDebugDrawer(&debugDrawer);
// Setup a big ground box // Setup a big ground box
{ {
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(200.),btScalar(10.),btScalar(200.))); btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(200.),btScalar(10.),btScalar(200.)));
btTransform groundTransform; btTransform groundTransform;
groundTransform.setIdentity(); groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0,-15,0)); groundTransform.setOrigin(btVector3(0,-15,0));
localCreateRigidBody(btScalar(0.),groundTransform,groundShape); localCreateRigidBody(btScalar(0.),groundTransform,groundShape);
} }
// Spawn one ragdoll // Spawn one ragdoll
spawnRagdoll(); spawnRagdoll();
clientResetScene(); clientResetScene();
} }
void GenericJointDemo::spawnRagdoll(bool random) void GenericJointDemo::spawnRagdoll(bool random)
{ {
RagDoll* ragDoll = new RagDoll (m_dynamicsWorld, btVector3 (0,0,10),5.f); RagDoll* ragDoll = new RagDoll (m_dynamicsWorld, btVector3 (0,0,10),5.f);
m_ragdolls.push_back(ragDoll); m_ragdolls.push_back(ragDoll);
} }
void GenericJointDemo::clientMoveAndDisplay() void GenericJointDemo::clientMoveAndDisplay()
{ {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//simple dynamics world doesn't handle fixed-time-stepping //simple dynamics world doesn't handle fixed-time-stepping
float ms = m_clock.getTimeMicroseconds(); float ms = m_clock.getTimeMicroseconds();
m_clock.reset(); m_clock.reset();
float minFPS = 1000000.f/60.f; float minFPS = 1000000.f/60.f;
if (ms > minFPS) if (ms > minFPS)
ms = minFPS; ms = minFPS;
if (m_dynamicsWorld) if (m_dynamicsWorld)
m_dynamicsWorld->stepSimulation(ms / 1000000.f); m_dynamicsWorld->stepSimulation(ms / 1000000.f);
renderme(); renderme();
glFlush(); glFlush();
glutSwapBuffers(); glutSwapBuffers();
} }
void GenericJointDemo::displayCallback() void GenericJointDemo::displayCallback()
{ {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (m_dynamicsWorld) if (m_dynamicsWorld)
m_dynamicsWorld->updateAabbs(); m_dynamicsWorld->updateAabbs();
renderme(); renderme();
glFlush(); glFlush();
glutSwapBuffers(); glutSwapBuffers();
} }
void GenericJointDemo::keyboardCallback(unsigned char key, int x, int y) void GenericJointDemo::keyboardCallback(unsigned char key, int x, int y)
{ {
switch (key) switch (key)
{ {
case 'e': case 'e':
spawnRagdoll(true); spawnRagdoll(true);
break; break;
default: default:
DemoApplication::keyboardCallback(key, x, y); DemoApplication::keyboardCallback(key, x, y);
} }
} }

View File

@@ -415,7 +415,7 @@ void GimpactConcaveDemo::initPhysics()
m_constraintSolver = new btSequentialImpulseConstraintSolver(); m_constraintSolver = new btSequentialImpulseConstraintSolver();
m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_constraintSolver); m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_constraintSolver,m_collisionConfiguration);
m_dynamicsWorld->setDebugDrawer(&debugDrawer); m_dynamicsWorld->setDebugDrawer(&debugDrawer);
//create trimesh model and shape //create trimesh model and shape

View File

@@ -1652,7 +1652,7 @@ void ConcaveDemo::initPhysics()
btBroadphaseInterface* broadphase = new btSimpleBroadphase(); btBroadphaseInterface* broadphase = new btSimpleBroadphase();
btConstraintSolver* constraintSolver = new btSequentialImpulseConstraintSolver(); btConstraintSolver* constraintSolver = new btSequentialImpulseConstraintSolver();
m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,constraintSolver); m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,constraintSolver,collisionConfiguration);
//create trimesh model and shape //create trimesh model and shape

View File

@@ -40,6 +40,12 @@ void GLDebugDrawer::setDebugMode(int debugMode)
} }
void GLDebugDrawer::draw3dText(const btVector3& location,const char* textString)
{
glRasterPos3f(location.x(), location.y(), location.z());
BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),textString);
}
void GLDebugDrawer::reportErrorWarning(const char* warningString) void GLDebugDrawer::reportErrorWarning(const char* warningString)
{ {
printf(warningString); printf(warningString);

View File

@@ -20,6 +20,8 @@ public:
virtual void reportErrorWarning(const char* warningString); virtual void reportErrorWarning(const char* warningString);
virtual void draw3dText(const btVector3& location,const char* textString);
virtual void setDebugMode(int debugMode); virtual void setDebugMode(int debugMode);
virtual int getDebugMode() const { return m_debugMode;} virtual int getDebugMode() const { return m_debugMode;}

View File

@@ -328,7 +328,7 @@ void RagdollDemo::initPhysics()
btConstraintSolver* solver = new btSequentialImpulseConstraintSolver; btConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,overlappingPairCache,solver); m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,overlappingPairCache,solver,collisionConfiguration);
m_dynamicsWorld->setDebugDrawer(&debugDrawer); m_dynamicsWorld->setDebugDrawer(&debugDrawer);

View File

@@ -112,7 +112,7 @@ void UserCollisionAlgorithm::initPhysics()
dispatcher->registerCollisionCreateFunc(GIMPACT_SHAPE_PROXYTYPE,GIMPACT_SHAPE_PROXYTYPE,new btSphereSphereCollisionAlgorithm::CreateFunc); dispatcher->registerCollisionCreateFunc(GIMPACT_SHAPE_PROXYTYPE,GIMPACT_SHAPE_PROXYTYPE,new btSphereSphereCollisionAlgorithm::CreateFunc);
btConstraintSolver* constraintSolver = new btSequentialImpulseConstraintSolver(); btConstraintSolver* constraintSolver = new btSequentialImpulseConstraintSolver();
m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,constraintSolver); m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,constraintSolver,collisionConfiguration);
float mass = 0.f; float mass = 0.f;
btTransform startTransform; btTransform startTransform;

View File

@@ -124,7 +124,7 @@ void VehicleDemo::setupPhysics()
btVector3 worldMax(1000,1000,1000); btVector3 worldMax(1000,1000,1000);
btBroadphaseInterface* pairCache = new btAxisSweep3(worldMin,worldMax); btBroadphaseInterface* pairCache = new btAxisSweep3(worldMin,worldMax);
btConstraintSolver* constraintSolver = new btSequentialImpulseConstraintSolver(); btConstraintSolver* constraintSolver = new btSequentialImpulseConstraintSolver();
m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver); m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration);
#ifdef FORCE_ZAXIS_UP #ifdef FORCE_ZAXIS_UP
m_dynamicsWorld->setGravity(btVector3(0,0,-10)); m_dynamicsWorld->setGravity(btVector3(0,0,-10));
#endif #endif

View File

@@ -17,6 +17,9 @@ subject to the following restrictions:
#define BT_COLLISION_CONFIGURATION #define BT_COLLISION_CONFIGURATION
struct btCollisionAlgorithmCreateFunc; struct btCollisionAlgorithmCreateFunc;
class btStackAlloc;
class btPoolAllocator;
///btCollisionConfiguration allows to configure Bullet collision detection ///btCollisionConfiguration allows to configure Bullet collision detection
///stack allocator size, default collision algorithms and persistent manifold pool size ///stack allocator size, default collision algorithms and persistent manifold pool size
///todo: describe the meaning ///todo: describe the meaning
@@ -29,14 +32,12 @@ public:
{ {
} }
///pool size for the persistent contact manifold ///memory pools
virtual int getPersistentManifoldPoolSize() = 0; virtual btPoolAllocator* getPersistentManifoldPool() = 0;
virtual int getStackAllocatorSize() = 0; virtual btPoolAllocator* getCollisionAlgorithmPool() = 0;
virtual int getCollisionAlgorithmPoolSize() = 0; virtual btStackAlloc* getStackAllocator() = 0;
virtual int getCollisionAlgorithmMaxElementSize() = 0;
virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1) =0; virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1) =0;

View File

@@ -41,9 +41,9 @@ btCollisionDispatcher::btCollisionDispatcher (btCollisionConfiguration* collisio
setNearCallback(defaultNearCallback); setNearCallback(defaultNearCallback);
m_collisionAlgorithmPoolAllocator = new btPoolAllocator(m_collisionConfiguration->getCollisionAlgorithmMaxElementSize(),m_collisionConfiguration->getCollisionAlgorithmPoolSize()); m_collisionAlgorithmPoolAllocator = collisionConfiguration->getCollisionAlgorithmPool();
m_persistentManifoldPoolAllocator = new btPoolAllocator(sizeof(btPersistentManifold),m_collisionConfiguration->getPersistentManifoldPoolSize()); m_persistentManifoldPoolAllocator = collisionConfiguration->getPersistentManifoldPool();
for (i=0;i<MAX_BROADPHASE_COLLISION_TYPES;i++) for (i=0;i<MAX_BROADPHASE_COLLISION_TYPES;i++)
{ {
@@ -65,8 +65,6 @@ void btCollisionDispatcher::registerCollisionCreateFunc(int proxyType0, int prox
btCollisionDispatcher::~btCollisionDispatcher() btCollisionDispatcher::~btCollisionDispatcher()
{ {
delete m_collisionAlgorithmPoolAllocator;
delete m_persistentManifoldPoolAllocator;
} }
btPersistentManifold* btCollisionDispatcher::getNewManifold(void* b0,void* b1) btPersistentManifold* btCollisionDispatcher::getNewManifold(void* b0,void* b1)

View File

@@ -124,6 +124,20 @@ public:
virtual void freeCollisionAlgorithm(void* ptr); virtual void freeCollisionAlgorithm(void* ptr);
btCollisionConfiguration* getCollisionConfiguration()
{
return m_collisionConfiguration;
}
const btCollisionConfiguration* getCollisionConfiguration() const
{
return m_collisionConfiguration;
}
void setCollisionConfiguration(btCollisionConfiguration* config)
{
m_collisionConfiguration = config;
}
}; };

View File

@@ -35,24 +35,22 @@ subject to the following restrictions:
//When the user doesn't provide dispatcher or broadphase, create basic versions (and delete them in destructor) //When the user doesn't provide dispatcher or broadphase, create basic versions (and delete them in destructor)
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" #include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h" #include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h"
#include "BulletCollision/CollisionDispatch/btCollisionConfiguration.h"
btCollisionWorld::btCollisionWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache, btCollisionConfiguration* collisionConfiguration)
btCollisionWorld::btCollisionWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache, int stackSize)
:m_dispatcher1(dispatcher), :m_dispatcher1(dispatcher),
m_broadphasePairCache(pairCache), m_broadphasePairCache(pairCache),
m_ownsDispatcher(false), m_ownsDispatcher(false),
m_ownsBroadphasePairCache(false) m_ownsBroadphasePairCache(false)
{ {
m_stackAlloc = new btStackAlloc(stackSize); m_stackAlloc = collisionConfiguration->getStackAllocator();
m_dispatchInfo.m_stackAllocator = m_stackAlloc; m_dispatchInfo.m_stackAllocator = m_stackAlloc;
} }
btCollisionWorld::~btCollisionWorld() btCollisionWorld::~btCollisionWorld()
{ {
m_stackAlloc->destroy();
delete m_stackAlloc;
//clean up remaining objects //clean up remaining objects
int i; int i;

View File

@@ -98,7 +98,7 @@ protected:
public: public:
//this constructor doesn't own the dispatcher and paircache/broadphase //this constructor doesn't own the dispatcher and paircache/broadphase
btCollisionWorld(btDispatcher* dispatcher,btBroadphaseInterface* broadphasePairCache, int stackSize = 2*1024*1024); btCollisionWorld(btDispatcher* dispatcher,btBroadphaseInterface* broadphasePairCache, btCollisionConfiguration* collisionConfiguration);
virtual ~btCollisionWorld(); virtual ~btCollisionWorld();

View File

@@ -24,15 +24,16 @@ subject to the following restrictions:
#include "BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h" #include "BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h" #include "BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h"
#include "LinearMath/btStackAlloc.h"
#include "LinearMath/btPoolAllocator.h"
#define DEFAULT_MAX_OVERLAPPING_PAIRS 65535 #define DEFAULT_MAX_OVERLAPPING_PAIRS 65535
#define DEFAULT_STACK_ALLOCATOR_SIZE (5*1024*1024) #define DEFAULT_STACK_ALLOCATOR_SIZE (5*1024*1024)
btDefaultCollisionConfiguration::btDefaultCollisionConfiguration() btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(btStackAlloc* stackAlloc,btPoolAllocator* persistentManifoldPool,btPoolAllocator* collisionAlgorithmPool)
:m_persistentManifoldPoolSize(DEFAULT_MAX_OVERLAPPING_PAIRS),
m_stackAllocatorSize(DEFAULT_STACK_ALLOCATOR_SIZE),
m_collisionAlgorithmPoolSize(DEFAULT_MAX_OVERLAPPING_PAIRS),
m_collisionAlgorithmMaxElementSize(0)
{ {
//default CreationFunctions, filling the m_doubleDispatch table //default CreationFunctions, filling the m_doubleDispatch table
@@ -58,14 +59,62 @@ m_collisionAlgorithmMaxElementSize(0)
int maxSize3 = sizeof(btCompoundCollisionAlgorithm); int maxSize3 = sizeof(btCompoundCollisionAlgorithm);
int maxSize4 = sizeof(btEmptyAlgorithm); int maxSize4 = sizeof(btEmptyAlgorithm);
m_collisionAlgorithmMaxElementSize = btMax(maxSize,maxSize2); int collisionAlgorithmMaxElementSize = btMax(maxSize,maxSize2);
m_collisionAlgorithmMaxElementSize = btMax(m_collisionAlgorithmMaxElementSize,maxSize3); collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize3);
m_collisionAlgorithmMaxElementSize = btMax(m_collisionAlgorithmMaxElementSize,maxSize4); collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize4);
if (stackAlloc)
{
m_ownsStackAllocator = false;
this->m_stackAlloc = stackAlloc;
} else
{
m_ownsStackAllocator = true;
void* mem = btAlignedAlloc(sizeof(btStackAlloc),16);
m_stackAlloc = new(mem)btStackAlloc(DEFAULT_STACK_ALLOCATOR_SIZE);
}
if (persistentManifoldPool)
{
m_ownsPersistentManifoldPool = false;
m_persistentManifoldPool = persistentManifoldPool;
} else
{
m_ownsPersistentManifoldPool = true;
void* mem = btAlignedAlloc(sizeof(btPoolAllocator),16);
m_persistentManifoldPool = new (mem) btPoolAllocator(sizeof(btPersistentManifold),DEFAULT_MAX_OVERLAPPING_PAIRS);
}
if (collisionAlgorithmPool)
{
m_ownsCollisionAlgorithmPool = false;
m_collisionAlgorithmPool = collisionAlgorithmPool;
} else
{
m_ownsCollisionAlgorithmPool = true;
void* mem = btAlignedAlloc(sizeof(btPoolAllocator),16);
m_collisionAlgorithmPool = new(mem) btPoolAllocator(collisionAlgorithmMaxElementSize,DEFAULT_MAX_OVERLAPPING_PAIRS);
}
} }
btDefaultCollisionConfiguration::~btDefaultCollisionConfiguration() btDefaultCollisionConfiguration::~btDefaultCollisionConfiguration()
{ {
if (m_ownsStackAllocator)
{
m_stackAlloc->destroy();
btAlignedFree(m_stackAlloc);
}
if (m_ownsCollisionAlgorithmPool)
{
btAlignedFree(m_collisionAlgorithmPool);
}
if (m_ownsPersistentManifoldPool)
{
btAlignedFree(m_persistentManifoldPool);
}
delete m_convexConvexCreateFunc; delete m_convexConvexCreateFunc;
delete m_convexConcaveCreateFunc; delete m_convexConcaveCreateFunc;
delete m_swappedConvexConcaveCreateFunc; delete m_swappedConvexConcaveCreateFunc;
@@ -79,28 +128,6 @@ btDefaultCollisionConfiguration::~btDefaultCollisionConfiguration()
delete m_triangleSphereCF; delete m_triangleSphereCF;
}
///pool size for the persistent contact manifold
int btDefaultCollisionConfiguration::getPersistentManifoldPoolSize()
{
return m_persistentManifoldPoolSize;
}
int btDefaultCollisionConfiguration::getStackAllocatorSize()
{
return m_stackAllocatorSize;
}
int btDefaultCollisionConfiguration::getCollisionAlgorithmPoolSize()
{
return m_collisionAlgorithmPoolSize;
}
int btDefaultCollisionConfiguration::getCollisionAlgorithmMaxElementSize()
{
return m_collisionAlgorithmMaxElementSize;
} }

View File

@@ -19,19 +19,23 @@ subject to the following restrictions:
#include "btCollisionConfiguration.h" #include "btCollisionConfiguration.h"
///btCollisionConfiguration allows to configure Bullet collision detection ///btCollisionConfiguration allows to configure Bullet collision detection
///stack allocator size, default collision algorithms and persistent manifold pool size ///stack allocator, pool memory allocators
///todo: describe the meaning ///todo: describe the meaning
class btDefaultCollisionConfiguration : public btCollisionConfiguration class btDefaultCollisionConfiguration : public btCollisionConfiguration
{ {
int m_persistentManifoldPoolSize; int m_persistentManifoldPoolSize;
int m_stackAllocatorSize; btStackAlloc* m_stackAlloc;
bool m_ownsStackAllocator;
int m_collisionAlgorithmPoolSize; btPoolAllocator* m_persistentManifoldPool;
bool m_ownsPersistentManifoldPool;
int m_collisionAlgorithmMaxElementSize; btPoolAllocator* m_collisionAlgorithmPool;
bool m_ownsCollisionAlgorithmPool;
//default CreationFunctions, filling the m_doubleDispatch table //default CreationFunctions, filling the m_doubleDispatch table
btCollisionAlgorithmCreateFunc* m_convexConvexCreateFunc; btCollisionAlgorithmCreateFunc* m_convexConvexCreateFunc;
btCollisionAlgorithmCreateFunc* m_convexConcaveCreateFunc; btCollisionAlgorithmCreateFunc* m_convexConcaveCreateFunc;
@@ -47,35 +51,30 @@ class btDefaultCollisionConfiguration : public btCollisionConfiguration
public: public:
btDefaultCollisionConfiguration(); btDefaultCollisionConfiguration(btStackAlloc* stackAlloc=0,btPoolAllocator* persistentManifoldPool=0,btPoolAllocator* collisionAlgorithmPool=0);
virtual ~btDefaultCollisionConfiguration(); virtual ~btDefaultCollisionConfiguration();
///pool size for the persistent contact manifold ///memory pools
virtual int getPersistentManifoldPoolSize(); virtual btPoolAllocator* getPersistentManifoldPool()
{
return m_persistentManifoldPool;
}
virtual int getStackAllocatorSize(); virtual btPoolAllocator* getCollisionAlgorithmPool()
{
return m_collisionAlgorithmPool;
}
virtual int getCollisionAlgorithmPoolSize(); virtual btStackAlloc* getStackAllocator()
{
return m_stackAlloc;
}
virtual int getCollisionAlgorithmMaxElementSize();
btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1); btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1);
void setStackAllocatorSize(int size)
{
m_stackAllocatorSize = size;
}
void setPersistentManifoldPoolSize(int size)
{
m_persistentManifoldPoolSize = size;
}
void setCollisionAlgorithmPoolSize(int size)
{
m_collisionAlgorithmPoolSize = size;
}
}; };
#endif //BT_DEFAULT_COLLISION_CONFIGURATION #endif //BT_DEFAULT_COLLISION_CONFIGURATION

View File

@@ -25,17 +25,17 @@ void btSimulationIslandManager::initUnionFind(int n)
} }
void btSimulationIslandManager::findUnions(btDispatcher* dispatcher) void btSimulationIslandManager::findUnions(btDispatcher* dispatcher,btCollisionWorld* colWorld)
{ {
{ {
for (int i=0;i<dispatcher->getNumManifolds();i++) btBroadphasePair* pairPtr = colWorld->getPairCache()->getOverlappingPairArrayPtr();
{
const btPersistentManifold* manifold = dispatcher->getManifoldByIndexInternal(i);
//static objects (invmass btScalar(0.)) don't merge !
const btCollisionObject* colObj0 = static_cast<const btCollisionObject*>(manifold->getBody0()); for (int i=0;i<colWorld->getPairCache()->getNumOverlappingPairs();i++)
const btCollisionObject* colObj1 = static_cast<const btCollisionObject*>(manifold->getBody1()); {
const btBroadphasePair& collisionPair = pairPtr[i];
btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject;
if (((colObj0) && ((colObj0)->mergesSimulationIslands())) && if (((colObj0) && ((colObj0)->mergesSimulationIslands())) &&
((colObj1) && ((colObj1)->mergesSimulationIslands()))) ((colObj1) && ((colObj1)->mergesSimulationIslands())))
@@ -71,7 +71,7 @@ void btSimulationIslandManager::updateActivationState(btCollisionWorld* colWorld
} }
// do the union find // do the union find
findUnions(dispatcher); findUnions(dispatcher,colWorld);
@@ -259,11 +259,11 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
{ {
//kinematic objects don't merge islands, but wake up all connected objects //kinematic objects don't merge islands, but wake up all connected objects
if (colObj0->isStaticOrKinematicObject() && colObj0->getActivationState() != ISLAND_SLEEPING) if (colObj0->isKinematicObject() && colObj0->getActivationState() != ISLAND_SLEEPING)
{ {
colObj1->activate(); colObj1->activate();
} }
if (colObj1->isStaticOrKinematicObject() && colObj1->getActivationState() != ISLAND_SLEEPING) if (colObj1->isKinematicObject() && colObj1->getActivationState() != ISLAND_SLEEPING)
{ {
colObj0->activate(); colObj0->activate();
} }
@@ -300,6 +300,7 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
btAlignedObjectArray<btCollisionObject*> islandBodies; btAlignedObjectArray<btCollisionObject*> islandBodies;
// printf("Start Islands\n");
//traverse the simulation islands, and call the solver, unless all objects are sleeping/deactivated //traverse the simulation islands, and call the solver, unless all objects are sleeping/deactivated
for ( startIslandIndex=0;startIslandIndex<numElem;startIslandIndex = endIslandIndex) for ( startIslandIndex=0;startIslandIndex<numElem;startIslandIndex = endIslandIndex)
@@ -343,6 +344,7 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
if (!islandSleeping) if (!islandSleeping)
{ {
callback->ProcessIsland(&islandBodies[0],islandBodies.size(),startManifold,numIslandManifolds, islandId); callback->ProcessIsland(&islandBodies[0],islandBodies.size(),startManifold,numIslandManifolds, islandId);
// printf("Island callback of size:%d bodies, %d manifolds\n",islandBodies.size(),numIslandManifolds);
} }
if (numIslandManifolds) if (numIslandManifolds)

View File

@@ -42,7 +42,7 @@ public:
virtual void storeIslandActivationState(btCollisionWorld* world); virtual void storeIslandActivationState(btCollisionWorld* world);
void findUnions(btDispatcher* dispatcher); void findUnions(btDispatcher* dispatcher,btCollisionWorld* colWorld);

View File

@@ -117,6 +117,7 @@ public:
m_pointCache[index] = m_pointCache[lastUsedIndex]; m_pointCache[index] = m_pointCache[lastUsedIndex];
//get rid of duplicated userPersistentData pointer //get rid of duplicated userPersistentData pointer
m_pointCache[lastUsedIndex].m_userPersistentData = 0; m_pointCache[lastUsedIndex].m_userPersistentData = 0;
m_pointCache[lastUsedIndex].m_lifeTime = 0;
} }
btAssert(m_pointCache[lastUsedIndex].m_userPersistentData==0); btAssert(m_pointCache[lastUsedIndex].m_userPersistentData==0);

View File

@@ -447,6 +447,7 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
END_PROFILE("refreshManifolds"); END_PROFILE("refreshManifolds");
#endif //FORCE_REFESH_CONTACT_MANIFOLDS #endif //FORCE_REFESH_CONTACT_MANIFOLDS
btVector3 color(0,1,0);
BEGIN_PROFILE("gatherSolverData"); BEGIN_PROFILE("gatherSolverData");
@@ -559,6 +560,9 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
{ {
btManifoldPoint& cp = manifold->getContactPoint(j); btManifoldPoint& cp = manifold->getContactPoint(j);
if (debugDrawer)
debugDrawer->drawContactPoint(cp.m_positionWorldOnB,cp.m_normalWorldOnB,cp.getDistance(),cp.getLifeTime(),color);
if (cp.getDistance() <= btScalar(0.)) if (cp.getDistance() <= btScalar(0.))
@@ -938,6 +942,7 @@ btScalar btSequentialImpulseConstraintSolver::solveGroup(btCollisionObject** bod
solveFriction((btRigidBody*)manifold->getBody0(), solveFriction((btRigidBody*)manifold->getBody0(),
(btRigidBody*)manifold->getBody1(),manifold->getContactPoint(gOrder[j].m_pointIndex),info,iteration,debugDrawer); (btRigidBody*)manifold->getBody1(),manifold->getContactPoint(gOrder[j].m_pointIndex),info,iteration,debugDrawer);
} }
} }
} }

View File

@@ -70,7 +70,7 @@ plDynamicsWorldHandle plCreateDynamicsWorld(plPhysicsSdkHandle physicsSdkHandle)
btBroadphaseInterface* pairCache = new btAxisSweep3(physicsSdk->m_worldAabbMin,physicsSdk->m_worldAabbMax); btBroadphaseInterface* pairCache = new btAxisSweep3(physicsSdk->m_worldAabbMin,physicsSdk->m_worldAabbMax);
btConstraintSolver* constraintSolver = new btSequentialImpulseConstraintSolver(); btConstraintSolver* constraintSolver = new btSequentialImpulseConstraintSolver();
return (plDynamicsWorldHandle) new btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver); return (plDynamicsWorldHandle) new btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration);
} }
void plDeleteDynamicsWorld(plDynamicsWorldHandle world) void plDeleteDynamicsWorld(plDynamicsWorldHandle world)
{ {

View File

@@ -33,8 +33,8 @@ subject to the following restrictions:
#include <stdio.h> #include <stdio.h>
btContinuousDynamicsWorld::btContinuousDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver) btContinuousDynamicsWorld::btContinuousDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration)
:btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver) :btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration)
{ {
} }

View File

@@ -28,7 +28,7 @@ class btContinuousDynamicsWorld : public btDiscreteDynamicsWorld
public: public:
btContinuousDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver); btContinuousDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration);
virtual ~btContinuousDynamicsWorld(); virtual ~btContinuousDynamicsWorld();
///time stepping with calculation of time of impact for selected fast moving objects ///time stepping with calculation of time of impact for selected fast moving objects

View File

@@ -57,8 +57,8 @@ subject to the following restrictions:
btDiscreteDynamicsWorld::btDiscreteDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver) btDiscreteDynamicsWorld::btDiscreteDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration)
:btDynamicsWorld(dispatcher,pairCache), :btDynamicsWorld(dispatcher,pairCache,collisionConfiguration),
m_constraintSolver(constraintSolver? constraintSolver: new btSequentialImpulseConstraintSolver), m_constraintSolver(constraintSolver? constraintSolver: new btSequentialImpulseConstraintSolver),
m_debugDrawer(0), m_debugDrawer(0),
m_gravity(0,-10,0), m_gravity(0,-10,0),

View File

@@ -86,7 +86,7 @@ public:
///this btDiscreteDynamicsWorld constructor gets created objects from the user, and will not delete those ///this btDiscreteDynamicsWorld constructor gets created objects from the user, and will not delete those
btDiscreteDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver); btDiscreteDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration);
virtual ~btDiscreteDynamicsWorld(); virtual ~btDiscreteDynamicsWorld();

View File

@@ -28,8 +28,8 @@ class btDynamicsWorld : public btCollisionWorld
public: public:
btDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* broadphase) btDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* broadphase,btCollisionConfiguration* collisionConfiguration)
:btCollisionWorld(dispatcher,broadphase) :btCollisionWorld(dispatcher,broadphase,collisionConfiguration)
{ {
} }

View File

@@ -32,8 +32,8 @@ extern "C" void btBulletDynamicsProbe () {}
btSimpleDynamicsWorld::btSimpleDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver) btSimpleDynamicsWorld::btSimpleDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration)
:btDynamicsWorld(dispatcher,pairCache), :btDynamicsWorld(dispatcher,pairCache,collisionConfiguration),
m_constraintSolver(constraintSolver), m_constraintSolver(constraintSolver),
m_ownsConstraintSolver(false), m_ownsConstraintSolver(false),
m_debugDrawer(0), m_debugDrawer(0),

View File

@@ -48,7 +48,7 @@ public:
///this btSimpleDynamicsWorld constructor creates dispatcher, broadphase pairCache and constraintSolver ///this btSimpleDynamicsWorld constructor creates dispatcher, broadphase pairCache and constraintSolver
btSimpleDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver); btSimpleDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration);
virtual ~btSimpleDynamicsWorld(); virtual ~btSimpleDynamicsWorld();

View File

@@ -60,6 +60,8 @@ class btIDebugDraw
virtual void reportErrorWarning(const char* warningString) = 0; virtual void reportErrorWarning(const char* warningString) = 0;
virtual void draw3dText(const btVector3& location,const char* textString) = 0;
virtual void setDebugMode(int debugMode) =0; virtual void setDebugMode(int debugMode) =0;
virtual int getDebugMode() const = 0; virtual int getDebugMode() const = 0;