Based on feedback from another professional game company, there are several improvements, including some API change...

Some dynamic memory allocations have been replace by pool allocation or stack allocations.
quantized aabb versus quantized aabb overlap check is made branch-free (helps a lot on consoles PS3/XBox 360)
Collision algorithms are now created through a new btDefaultCollisionConfiguration, to decouple dependency (this is the API change):
Example:
	btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
	m_dispatcher = new	btCollisionDispatcher(collisionConfiguration);
This commit is contained in:
ejcoumans
2007-09-08 05:40:01 +00:00
parent 30b1887f40
commit 87df3d0f32
67 changed files with 1116 additions and 972 deletions

View File

@@ -129,6 +129,7 @@ void BasicDemo::displayCallback(void) {
void BasicDemo::initPhysics()
{
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
#ifdef USE_PARALLEL_DISPATCHER
@@ -149,9 +150,9 @@ void BasicDemo::initPhysics()
#endif
m_dispatcher = new SpuGatheringCollisionDispatcher(threadSupport,maxNumOutstandingTasks);
m_dispatcher = new SpuGatheringCollisionDispatcher(threadSupport,maxNumOutstandingTasks,collisionConfiguration);
#else
m_dispatcher = new btCollisionDispatcher(true);
m_dispatcher = new btCollisionDispatcher(collisionConfiguration);
#endif //USE_PARALLEL_DISPATCHER
#define USE_SWEEP_AND_PRUNE 1
@@ -167,18 +168,8 @@ void BasicDemo::initPhysics()
m_overlappingPairCache = new btSimpleBroadphase;
#endif //USE_SWEEP_AND_PRUNE
#ifndef USE_PARALLEL_DISPATCHER
m_sphereSphereCF = new btSphereSphereCollisionAlgorithm::CreateFunc;
m_dispatcher->registerCollisionCreateFunc(SPHERE_SHAPE_PROXYTYPE,SPHERE_SHAPE_PROXYTYPE,m_sphereSphereCF);
m_sphereBoxCF = new btSphereBoxCollisionAlgorithm::CreateFunc;
m_boxSphereCF = new btSphereBoxCollisionAlgorithm::CreateFunc;
m_boxSphereCF->m_swapped = true;
m_dispatcher->registerCollisionCreateFunc(SPHERE_SHAPE_PROXYTYPE,BOX_SHAPE_PROXYTYPE,m_sphereBoxCF);
m_dispatcher->registerCollisionCreateFunc(BOX_SHAPE_PROXYTYPE,SPHERE_SHAPE_PROXYTYPE,m_boxSphereCF);
#endif //USE_PARALLEL_DISPATCHER
btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver;
m_solver = sol;
@@ -267,13 +258,6 @@ void BasicDemo::exitPhysics()
//delete dynamics world
delete m_dynamicsWorld;
//delete collision algorithms creation functions
delete m_sphereSphereCF;
delete m_sphereBoxCF;
delete m_boxSphereCF;
//delete solver
delete m_solver;

View File

@@ -134,8 +134,9 @@ void BspDemo::initPhysics(char* bspfilename)
///Setup a Physics Simulation Environment
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
// btCollisionShape* groundShape = new btBoxShape(btVector3(50,3,50));
btCollisionDispatcher* dispatcher = new btCollisionDispatcher();
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
btVector3 worldMin(-1000,-1000,-1000);
btVector3 worldMax(1000,1000,1000);
btBroadphaseInterface* pairCache = new btAxisSweep3(worldMin,worldMax);

View File

@@ -388,7 +388,8 @@ int maxNumOutstandingTasks = 4;//number of maximum outstanding tasks
dispatcher = new SpuGatheringCollisionDispatcher(threadSupportCollision,maxNumOutstandingTasks);
// dispatcher = new btCollisionDispatcher();
#else
dispatcher = new btCollisionDispatcher();
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
dispatcher = new btCollisionDispatcher(collisionConfiguration);
#endif //USE_PARALLEL_DISPATCHER
#ifdef USE_CUSTOM_NEAR_CALLBACK

View File

@@ -170,7 +170,8 @@ void ColladaDemo::initPhysics(const char* filename)
m_ele = 60;
m_forwardAxis = 1;
btCollisionDispatcher* dispatcher = new btCollisionDispatcher();
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
btVector3 worldMin(-1000,-1000,-1000);
btVector3 worldMax(1000,1000,1000);
btBroadphaseInterface* pairCache = new btAxisSweep3(worldMin,worldMax);

View File

@@ -81,7 +81,8 @@ void CollisionInterfaceDemo::initPhysics()
objects[0].setCollisionShape(boxA);//&hullA;
objects[1].setCollisionShape(boxB);//&hullB;
btCollisionDispatcher* dispatcher = new btCollisionDispatcher;
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
btVector3 worldAabbMin(-1000,-1000,-1000);
btVector3 worldAabbMax(1000,1000,1000);

View File

@@ -217,7 +217,8 @@ void ConcaveDemo::initPhysics()
btCollisionDispatcher* dispatcher = new SpuGatheringCollisionDispatcher(threadSupport,maxNumOutstandingTasks);
#else
btCollisionDispatcher* dispatcher = new btCollisionDispatcher();
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
#endif//USE_PARALLEL_DISPATCHER
@@ -276,7 +277,7 @@ void ConcaveDemo::clientMoveAndDisplay()
trimeshShape->refitTree();
//clear all contact points involving mesh proxy. Note: this is a slow/unoptimized operation.
m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(staticBody->getBroadphaseHandle());
m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(staticBody->getBroadphaseHandle(),getDynamicsWorld()->getDispatcher());
}
m_dynamicsWorld->stepSimulation(dt);

View File

@@ -76,7 +76,8 @@ void drawLimit()
void ConstraintDemo::initPhysics()
{
// btCollisionShape* groundShape = new btBoxShape(btVector3(50,3,50));
btCollisionDispatcher* dispatcher = new btCollisionDispatcher();
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
btVector3 worldMin(-1000,-1000,-1000);
btVector3 worldMax(1000,1000,1000);
btBroadphaseInterface* pairCache = new btAxisSweep3(worldMin,worldMax);

View File

@@ -95,6 +95,8 @@ void ConvexDecompositionDemo::initPhysics(const char* filename)
tcount = wo.loadObj("../../file.obj");
}
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
#ifdef USE_PARALLEL_DISPATCHER
#ifdef USE_WIN32_THREADING
@@ -112,9 +114,9 @@ void ConvexDecompositionDemo::initPhysics(const char* filename)
///you can hook it up to your custom task scheduler by deriving from btThreadSupportInterface
#endif
btCollisionDispatcher* dispatcher = new SpuGatheringCollisionDispatcher(threadSupport,maxNumOutstandingTasks);
btCollisionDispatcher* dispatcher = new SpuGatheringCollisionDispatcher(threadSupport,maxNumOutstandingTasks,collisionConfiguration);
#else
btCollisionDispatcher* dispatcher = new btCollisionDispatcher();
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
#endif//USE_PARALLEL_DISPATCHER

View File

@@ -82,7 +82,8 @@ void DoublePrecisionDemo::initPhysics()
objects[0].setCollisionShape(boxA);//&hullA;
objects[1].setCollisionShape(boxB);//&hullB;
btCollisionDispatcher* dispatcher = new btCollisionDispatcher;
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
btVector3 worldAabbMin(80000,80000,80000);
btVector3 worldAabbMax(120000,120000,120000);

View File

@@ -1643,10 +1643,11 @@ void ConcaveDemo::initGImpactCollision()
void ConcaveDemo::initPhysics()
{
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
//btConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
btCollisionDispatcher* dispatcher = new btCollisionDispatcher();
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
//btOverlappingPairCache* broadphase = new btSimpleBroadphase();
btBroadphaseInterface* broadphase = new btSimpleBroadphase();

View File

@@ -932,7 +932,7 @@ void DemoApplication::clientResetScene()
colObj->activate();
}
//removed cached contact points
m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(colObj->getBroadphaseHandle());
m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(colObj->getBroadphaseHandle(),getDynamicsWorld()->getDispatcher());
btRigidBody* body = btRigidBody::upcast(colObj);
if (body && !body->isStaticObject())

View File

@@ -1,389 +1,391 @@
/*
Bullet Continuous Collision Detection and Physics Library
Ragdoll Demo
Copyright (c) 2007 Starbreeze Studios
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.
Written by: Marten Svanfeldt
*/
#include "btBulletDynamicsCommon.h"
#include "GlutStuff.h"
#include "GL_ShapeDrawer.h"
/*
Bullet Continuous Collision Detection and Physics Library
Ragdoll Demo
Copyright (c) 2007 Starbreeze Studios
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.
Written by: Marten Svanfeldt
*/
#include "btBulletDynamicsCommon.h"
#include "GlutStuff.h"
#include "GL_ShapeDrawer.h"
#include "LinearMath/btIDebugDraw.h"
#include "GLDebugDrawer.h"
#include "RagdollDemo.h"
GLDebugDrawer debugDrawer;
#define M_PI 3.14159265358979323846
#define M_PI_2 1.57079632679489661923
#define M_PI_4 0.785398163397448309616
class RagDoll
{
enum
{
BODYPART_PELVIS = 0,
BODYPART_SPINE,
BODYPART_HEAD,
BODYPART_LEFT_UPPER_LEG,
BODYPART_LEFT_LOWER_LEG,
BODYPART_RIGHT_UPPER_LEG,
BODYPART_RIGHT_LOWER_LEG,
BODYPART_LEFT_UPPER_ARM,
BODYPART_LEFT_LOWER_ARM,
BODYPART_RIGHT_UPPER_ARM,
BODYPART_RIGHT_LOWER_ARM,
BODYPART_COUNT
};
enum
{
JOINT_PELVIS_SPINE = 0,
JOINT_SPINE_HEAD,
JOINT_LEFT_HIP,
JOINT_LEFT_KNEE,
JOINT_RIGHT_HIP,
JOINT_RIGHT_KNEE,
JOINT_LEFT_SHOULDER,
JOINT_LEFT_ELBOW,
JOINT_RIGHT_SHOULDER,
JOINT_RIGHT_ELBOW,
JOINT_COUNT
};
btDynamicsWorld* m_ownerWorld;
btCollisionShape* m_shapes[BODYPART_COUNT];
btRigidBody* m_bodies[BODYPART_COUNT];
btTypedConstraint* m_joints[JOINT_COUNT];
btRigidBody* localCreateRigidBody (btScalar mass, const btTransform& startTransform, btCollisionShape* shape)
{
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0,0,0);
if (isDynamic)
shape->calculateLocalInertia(mass,localInertia);
btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
btRigidBody* body = new btRigidBody(mass,myMotionState,shape,localInertia);
m_ownerWorld->addRigidBody(body);
return body;
}
public:
RagDoll (btDynamicsWorld* ownerWorld, const btVector3& positionOffset)
: m_ownerWorld (ownerWorld)
{
// Setup the geometry
m_shapes[BODYPART_PELVIS] = new btCapsuleShape(btScalar(0.15), btScalar(0.20));
m_shapes[BODYPART_SPINE] = new btCapsuleShape(btScalar(0.15), btScalar(0.28));
m_shapes[BODYPART_HEAD] = new btCapsuleShape(btScalar(0.10), btScalar(0.05));
m_shapes[BODYPART_LEFT_UPPER_LEG] = new btCapsuleShape(btScalar(0.07), btScalar(0.45));
m_shapes[BODYPART_LEFT_LOWER_LEG] = new btCapsuleShape(btScalar(0.05), btScalar(0.37));
m_shapes[BODYPART_RIGHT_UPPER_LEG] = new btCapsuleShape(btScalar(0.07), btScalar(0.45));
m_shapes[BODYPART_RIGHT_LOWER_LEG] = new btCapsuleShape(btScalar(0.05), btScalar(0.37));
m_shapes[BODYPART_LEFT_UPPER_ARM] = new btCapsuleShape(btScalar(0.05), btScalar(0.33));
m_shapes[BODYPART_LEFT_LOWER_ARM] = new btCapsuleShape(btScalar(0.04), btScalar(0.25));
m_shapes[BODYPART_RIGHT_UPPER_ARM] = new btCapsuleShape(btScalar(0.05), btScalar(0.33));
m_shapes[BODYPART_RIGHT_LOWER_ARM] = new btCapsuleShape(btScalar(0.04), btScalar(0.25));
// Setup all the rigid bodies
btTransform offset; offset.setIdentity();
offset.setOrigin(positionOffset);
btTransform transform;
transform.setIdentity();
transform.setOrigin(btVector3(btScalar(0.), btScalar(1.), btScalar(0.)));
m_bodies[BODYPART_PELVIS] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_PELVIS]);
transform.setIdentity();
transform.setOrigin(btVector3(btScalar(0.), btScalar(1.2), btScalar(0.)));
m_bodies[BODYPART_SPINE] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_SPINE]);
transform.setIdentity();
transform.setOrigin(btVector3(btScalar(0.), btScalar(1.6), btScalar(0.)));
m_bodies[BODYPART_HEAD] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_HEAD]);
transform.setIdentity();
transform.setOrigin(btVector3(btScalar(-0.18), btScalar(0.65), btScalar(0.)));
m_bodies[BODYPART_LEFT_UPPER_LEG] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_LEFT_UPPER_LEG]);
transform.setIdentity();
transform.setOrigin(btVector3(btScalar(-0.18), btScalar(0.2), btScalar(0.)));
m_bodies[BODYPART_LEFT_LOWER_LEG] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_LEFT_LOWER_LEG]);
transform.setIdentity();
transform.setOrigin(btVector3(btScalar(0.18), btScalar(0.65), btScalar(0.)));
m_bodies[BODYPART_RIGHT_UPPER_LEG] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_RIGHT_UPPER_LEG]);
transform.setIdentity();
transform.setOrigin(btVector3(btScalar(0.18), btScalar(0.2), btScalar(0.)));
m_bodies[BODYPART_RIGHT_LOWER_LEG] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_RIGHT_LOWER_LEG]);
transform.setIdentity();
transform.setOrigin(btVector3(btScalar(-0.35), btScalar(1.45), btScalar(0.)));
transform.getBasis().setEulerZYX(0,0,M_PI_2);
m_bodies[BODYPART_LEFT_UPPER_ARM] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_LEFT_UPPER_ARM]);
transform.setIdentity();
transform.setOrigin(btVector3(btScalar(-0.7), btScalar(1.45), btScalar(0.)));
transform.getBasis().setEulerZYX(0,0,M_PI_2);
m_bodies[BODYPART_LEFT_LOWER_ARM] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_LEFT_LOWER_ARM]);
transform.setIdentity();
transform.setOrigin(btVector3(btScalar(0.35), btScalar(1.45), btScalar(0.)));
transform.getBasis().setEulerZYX(0,0,-M_PI_2);
m_bodies[BODYPART_RIGHT_UPPER_ARM] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_RIGHT_UPPER_ARM]);
transform.setIdentity();
transform.setOrigin(btVector3(btScalar(0.7), btScalar(1.45), btScalar(0.)));
transform.getBasis().setEulerZYX(0,0,-M_PI_2);
m_bodies[BODYPART_RIGHT_LOWER_ARM] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_RIGHT_LOWER_ARM]);
// Setup some damping on the m_bodies
for (int i = 0; i < BODYPART_COUNT; ++i)
{
m_bodies[i]->setDamping(0.05, 0.85);
m_bodies[i]->setDeactivationTime(0.8);
m_bodies[i]->setSleepingThresholds(1.6, 2.5);
}
// Now setup the constraints
btHingeConstraint* hingeC;
btConeTwistConstraint* coneC;
btTransform localA, localB;
localA.setIdentity(); localB.setIdentity();
localA.getBasis().setEulerZYX(0,M_PI_2,0); localA.setOrigin(btVector3(btScalar(0.), btScalar(0.15), btScalar(0.)));
localB.getBasis().setEulerZYX(0,M_PI_2,0); localB.setOrigin(btVector3(btScalar(0.), btScalar(-0.15), btScalar(0.)));
hingeC = new btHingeConstraint(*m_bodies[BODYPART_PELVIS], *m_bodies[BODYPART_SPINE], localA, localB);
hingeC->setLimit(btScalar(-M_PI_4), btScalar(M_PI_2));
m_joints[JOINT_PELVIS_SPINE] = hingeC;
m_ownerWorld->addConstraint(m_joints[JOINT_PELVIS_SPINE], true);
localA.setIdentity(); localB.setIdentity();
localA.getBasis().setEulerZYX(0,0,M_PI_2); localA.setOrigin(btVector3(btScalar(0.), btScalar(0.30), btScalar(0.)));
localB.getBasis().setEulerZYX(0,0,-M_PI_2); localB.setOrigin(btVector3(btScalar(0.), btScalar(-0.14), btScalar(0.)));
coneC = new btConeTwistConstraint(*m_bodies[BODYPART_SPINE], *m_bodies[BODYPART_HEAD], localA, localB);
coneC->setLimit(M_PI_4, M_PI_4, M_PI_2);
m_joints[JOINT_SPINE_HEAD] = coneC;
m_ownerWorld->addConstraint(m_joints[JOINT_SPINE_HEAD], true);
localA.setIdentity(); localB.setIdentity();
localA.getBasis().setEulerZYX(0,0,-M_PI_4*5); localA.setOrigin(btVector3(btScalar(-0.18), btScalar(-0.10), btScalar(0.)));
localB.getBasis().setEulerZYX(0,0,M_PI_4*5); localB.setOrigin(btVector3(btScalar(0.), btScalar(0.225), btScalar(0.)));
coneC = new btConeTwistConstraint(*m_bodies[BODYPART_PELVIS], *m_bodies[BODYPART_LEFT_UPPER_LEG], localA, localB);
coneC->setLimit(M_PI_4, M_PI_4, 0);
m_joints[JOINT_LEFT_HIP] = coneC;
m_ownerWorld->addConstraint(m_joints[JOINT_LEFT_HIP], true);
localA.setIdentity(); localB.setIdentity();
localA.getBasis().setEulerZYX(0,M_PI_2,0); localA.setOrigin(btVector3(btScalar(0.), btScalar(-0.225), btScalar(0.)));
localB.getBasis().setEulerZYX(0,M_PI_2,0); localB.setOrigin(btVector3(btScalar(0.), btScalar(0.185), btScalar(0.)));
hingeC = new btHingeConstraint(*m_bodies[BODYPART_LEFT_UPPER_LEG], *m_bodies[BODYPART_LEFT_LOWER_LEG], localA, localB);
hingeC->setLimit(btScalar(0), btScalar(M_PI_2));
m_joints[JOINT_LEFT_KNEE] = hingeC;
m_ownerWorld->addConstraint(m_joints[JOINT_LEFT_KNEE], true);
localA.setIdentity(); localB.setIdentity();
localA.getBasis().setEulerZYX(0,0,M_PI_4); localA.setOrigin(btVector3(btScalar(0.18), btScalar(-0.10), btScalar(0.)));
localB.getBasis().setEulerZYX(0,0,-M_PI_4); localB.setOrigin(btVector3(btScalar(0.), btScalar(0.225), btScalar(0.)));
coneC = new btConeTwistConstraint(*m_bodies[BODYPART_PELVIS], *m_bodies[BODYPART_RIGHT_UPPER_LEG], localA, localB);
coneC->setLimit(M_PI_4, M_PI_4, 0);
m_joints[JOINT_RIGHT_HIP] = coneC;
m_ownerWorld->addConstraint(m_joints[JOINT_RIGHT_HIP], true);
localA.setIdentity(); localB.setIdentity();
localA.getBasis().setEulerZYX(0,M_PI_2,0); localA.setOrigin(btVector3(btScalar(0.), btScalar(-0.225), btScalar(0.)));
localB.getBasis().setEulerZYX(0,M_PI_2,0); localB.setOrigin(btVector3(btScalar(0.), btScalar(0.185), btScalar(0.)));
hingeC = new btHingeConstraint(*m_bodies[BODYPART_RIGHT_UPPER_LEG], *m_bodies[BODYPART_RIGHT_LOWER_LEG], localA, localB);
hingeC->setLimit(btScalar(0), btScalar(M_PI_2));
m_joints[JOINT_RIGHT_KNEE] = hingeC;
m_ownerWorld->addConstraint(m_joints[JOINT_RIGHT_KNEE], true);
localA.setIdentity(); localB.setIdentity();
localA.getBasis().setEulerZYX(0,0,M_PI); localA.setOrigin(btVector3(btScalar(-0.2), btScalar(0.15), btScalar(0.)));
localB.getBasis().setEulerZYX(0,0,-M_PI_2); localB.setOrigin(btVector3(btScalar(0.), btScalar(-0.18), btScalar(0.)));
coneC = new btConeTwistConstraint(*m_bodies[BODYPART_SPINE], *m_bodies[BODYPART_LEFT_UPPER_ARM], localA, localB);
coneC->setLimit(M_PI_2, M_PI_2, 0);
m_joints[JOINT_LEFT_SHOULDER] = coneC;
m_ownerWorld->addConstraint(m_joints[JOINT_LEFT_SHOULDER], true);
localA.setIdentity(); localB.setIdentity();
localA.getBasis().setEulerZYX(0,M_PI_2,0); localA.setOrigin(btVector3(btScalar(0.), btScalar(0.18), btScalar(0.)));
localB.getBasis().setEulerZYX(0,M_PI_2,0); localB.setOrigin(btVector3(btScalar(0.), btScalar(-0.14), btScalar(0.)));
hingeC = new btHingeConstraint(*m_bodies[BODYPART_LEFT_UPPER_ARM], *m_bodies[BODYPART_LEFT_LOWER_ARM], localA, localB);
hingeC->setLimit(btScalar(-M_PI_2), btScalar(0));
m_joints[JOINT_LEFT_ELBOW] = hingeC;
m_ownerWorld->addConstraint(m_joints[JOINT_LEFT_ELBOW], true);
localA.setIdentity(); localB.setIdentity();
localA.getBasis().setEulerZYX(0,0,0); localA.setOrigin(btVector3(btScalar(0.2), btScalar(0.15), btScalar(0.)));
localB.getBasis().setEulerZYX(0,0,-M_PI_2); localB.setOrigin(btVector3(btScalar(0.), btScalar(-0.18), btScalar(0.)));
coneC = new btConeTwistConstraint(*m_bodies[BODYPART_SPINE], *m_bodies[BODYPART_RIGHT_UPPER_ARM], localA, localB);
coneC->setLimit(M_PI_2, M_PI_2, 0);
m_joints[JOINT_RIGHT_SHOULDER] = coneC;
m_ownerWorld->addConstraint(m_joints[JOINT_RIGHT_SHOULDER], true);
localA.setIdentity(); localB.setIdentity();
localA.getBasis().setEulerZYX(0,M_PI_2,0); localA.setOrigin(btVector3(btScalar(0.), btScalar(0.18), btScalar(0.)));
localB.getBasis().setEulerZYX(0,M_PI_2,0); localB.setOrigin(btVector3(btScalar(0.), btScalar(-0.14), btScalar(0.)));
hingeC = new btHingeConstraint(*m_bodies[BODYPART_RIGHT_UPPER_ARM], *m_bodies[BODYPART_RIGHT_LOWER_ARM], localA, localB);
hingeC->setLimit(btScalar(-M_PI_2), btScalar(0));
m_joints[JOINT_RIGHT_ELBOW] = hingeC;
m_ownerWorld->addConstraint(m_joints[JOINT_RIGHT_ELBOW], true);
}
~RagDoll ()
{
// Remove all constraints
for (int i = 0; i < JOINT_COUNT; ++i)
{
m_ownerWorld->removeConstraint(m_joints[i]);
delete m_joints[i]; m_joints[i] = 0;
}
// Remove all bodies and shapes
for (int i = 0; i < BODYPART_COUNT; ++i)
{
m_ownerWorld->removeRigidBody(m_bodies[i]);
delete m_bodies[i]->getMotionState();
delete m_bodies[i]; m_bodies[i] = 0;
delete m_shapes[i]; m_shapes[i] = 0;
}
}
};
int main(int argc,char* argv[])
{
RagdollDemo demoApp;
demoApp.initPhysics();
demoApp.setCameraDistance(btScalar(10.));
return glutmain(argc, argv,640,480,"Bullet Physics Demo. http://bullet.sf.net",&demoApp);
}
void RagdollDemo::initPhysics()
{
// Setup the basic world
btCollisionDispatcher* dispatcher = new btCollisionDispatcher;
btPoint3 worldAabbMin(-10000,-10000,-10000);
btPoint3 worldAabbMax(10000,10000,10000);
btBroadphaseInterface* overlappingPairCache = new btAxisSweep3 (worldAabbMin, worldAabbMax);
btConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,overlappingPairCache,solver);
#include "GLDebugDrawer.h"
#include "RagdollDemo.h"
GLDebugDrawer debugDrawer;
#define M_PI 3.14159265358979323846
#define M_PI_2 1.57079632679489661923
#define M_PI_4 0.785398163397448309616
class RagDoll
{
enum
{
BODYPART_PELVIS = 0,
BODYPART_SPINE,
BODYPART_HEAD,
BODYPART_LEFT_UPPER_LEG,
BODYPART_LEFT_LOWER_LEG,
BODYPART_RIGHT_UPPER_LEG,
BODYPART_RIGHT_LOWER_LEG,
BODYPART_LEFT_UPPER_ARM,
BODYPART_LEFT_LOWER_ARM,
BODYPART_RIGHT_UPPER_ARM,
BODYPART_RIGHT_LOWER_ARM,
BODYPART_COUNT
};
enum
{
JOINT_PELVIS_SPINE = 0,
JOINT_SPINE_HEAD,
JOINT_LEFT_HIP,
JOINT_LEFT_KNEE,
JOINT_RIGHT_HIP,
JOINT_RIGHT_KNEE,
JOINT_LEFT_SHOULDER,
JOINT_LEFT_ELBOW,
JOINT_RIGHT_SHOULDER,
JOINT_RIGHT_ELBOW,
JOINT_COUNT
};
btDynamicsWorld* m_ownerWorld;
btCollisionShape* m_shapes[BODYPART_COUNT];
btRigidBody* m_bodies[BODYPART_COUNT];
btTypedConstraint* m_joints[JOINT_COUNT];
btRigidBody* localCreateRigidBody (btScalar mass, const btTransform& startTransform, btCollisionShape* shape)
{
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0,0,0);
if (isDynamic)
shape->calculateLocalInertia(mass,localInertia);
btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
btRigidBody* body = new btRigidBody(mass,myMotionState,shape,localInertia);
m_ownerWorld->addRigidBody(body);
return body;
}
public:
RagDoll (btDynamicsWorld* ownerWorld, const btVector3& positionOffset)
: m_ownerWorld (ownerWorld)
{
// Setup the geometry
m_shapes[BODYPART_PELVIS] = new btCapsuleShape(btScalar(0.15), btScalar(0.20));
m_shapes[BODYPART_SPINE] = new btCapsuleShape(btScalar(0.15), btScalar(0.28));
m_shapes[BODYPART_HEAD] = new btCapsuleShape(btScalar(0.10), btScalar(0.05));
m_shapes[BODYPART_LEFT_UPPER_LEG] = new btCapsuleShape(btScalar(0.07), btScalar(0.45));
m_shapes[BODYPART_LEFT_LOWER_LEG] = new btCapsuleShape(btScalar(0.05), btScalar(0.37));
m_shapes[BODYPART_RIGHT_UPPER_LEG] = new btCapsuleShape(btScalar(0.07), btScalar(0.45));
m_shapes[BODYPART_RIGHT_LOWER_LEG] = new btCapsuleShape(btScalar(0.05), btScalar(0.37));
m_shapes[BODYPART_LEFT_UPPER_ARM] = new btCapsuleShape(btScalar(0.05), btScalar(0.33));
m_shapes[BODYPART_LEFT_LOWER_ARM] = new btCapsuleShape(btScalar(0.04), btScalar(0.25));
m_shapes[BODYPART_RIGHT_UPPER_ARM] = new btCapsuleShape(btScalar(0.05), btScalar(0.33));
m_shapes[BODYPART_RIGHT_LOWER_ARM] = new btCapsuleShape(btScalar(0.04), btScalar(0.25));
// Setup all the rigid bodies
btTransform offset; offset.setIdentity();
offset.setOrigin(positionOffset);
btTransform transform;
transform.setIdentity();
transform.setOrigin(btVector3(btScalar(0.), btScalar(1.), btScalar(0.)));
m_bodies[BODYPART_PELVIS] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_PELVIS]);
transform.setIdentity();
transform.setOrigin(btVector3(btScalar(0.), btScalar(1.2), btScalar(0.)));
m_bodies[BODYPART_SPINE] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_SPINE]);
transform.setIdentity();
transform.setOrigin(btVector3(btScalar(0.), btScalar(1.6), btScalar(0.)));
m_bodies[BODYPART_HEAD] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_HEAD]);
transform.setIdentity();
transform.setOrigin(btVector3(btScalar(-0.18), btScalar(0.65), btScalar(0.)));
m_bodies[BODYPART_LEFT_UPPER_LEG] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_LEFT_UPPER_LEG]);
transform.setIdentity();
transform.setOrigin(btVector3(btScalar(-0.18), btScalar(0.2), btScalar(0.)));
m_bodies[BODYPART_LEFT_LOWER_LEG] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_LEFT_LOWER_LEG]);
transform.setIdentity();
transform.setOrigin(btVector3(btScalar(0.18), btScalar(0.65), btScalar(0.)));
m_bodies[BODYPART_RIGHT_UPPER_LEG] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_RIGHT_UPPER_LEG]);
transform.setIdentity();
transform.setOrigin(btVector3(btScalar(0.18), btScalar(0.2), btScalar(0.)));
m_bodies[BODYPART_RIGHT_LOWER_LEG] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_RIGHT_LOWER_LEG]);
transform.setIdentity();
transform.setOrigin(btVector3(btScalar(-0.35), btScalar(1.45), btScalar(0.)));
transform.getBasis().setEulerZYX(0,0,M_PI_2);
m_bodies[BODYPART_LEFT_UPPER_ARM] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_LEFT_UPPER_ARM]);
transform.setIdentity();
transform.setOrigin(btVector3(btScalar(-0.7), btScalar(1.45), btScalar(0.)));
transform.getBasis().setEulerZYX(0,0,M_PI_2);
m_bodies[BODYPART_LEFT_LOWER_ARM] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_LEFT_LOWER_ARM]);
transform.setIdentity();
transform.setOrigin(btVector3(btScalar(0.35), btScalar(1.45), btScalar(0.)));
transform.getBasis().setEulerZYX(0,0,-M_PI_2);
m_bodies[BODYPART_RIGHT_UPPER_ARM] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_RIGHT_UPPER_ARM]);
transform.setIdentity();
transform.setOrigin(btVector3(btScalar(0.7), btScalar(1.45), btScalar(0.)));
transform.getBasis().setEulerZYX(0,0,-M_PI_2);
m_bodies[BODYPART_RIGHT_LOWER_ARM] = localCreateRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_RIGHT_LOWER_ARM]);
// Setup some damping on the m_bodies
for (int i = 0; i < BODYPART_COUNT; ++i)
{
m_bodies[i]->setDamping(0.05, 0.85);
m_bodies[i]->setDeactivationTime(0.8);
m_bodies[i]->setSleepingThresholds(1.6, 2.5);
}
// Now setup the constraints
btHingeConstraint* hingeC;
btConeTwistConstraint* coneC;
btTransform localA, localB;
localA.setIdentity(); localB.setIdentity();
localA.getBasis().setEulerZYX(0,M_PI_2,0); localA.setOrigin(btVector3(btScalar(0.), btScalar(0.15), btScalar(0.)));
localB.getBasis().setEulerZYX(0,M_PI_2,0); localB.setOrigin(btVector3(btScalar(0.), btScalar(-0.15), btScalar(0.)));
hingeC = new btHingeConstraint(*m_bodies[BODYPART_PELVIS], *m_bodies[BODYPART_SPINE], localA, localB);
hingeC->setLimit(btScalar(-M_PI_4), btScalar(M_PI_2));
m_joints[JOINT_PELVIS_SPINE] = hingeC;
m_ownerWorld->addConstraint(m_joints[JOINT_PELVIS_SPINE], true);
localA.setIdentity(); localB.setIdentity();
localA.getBasis().setEulerZYX(0,0,M_PI_2); localA.setOrigin(btVector3(btScalar(0.), btScalar(0.30), btScalar(0.)));
localB.getBasis().setEulerZYX(0,0,-M_PI_2); localB.setOrigin(btVector3(btScalar(0.), btScalar(-0.14), btScalar(0.)));
coneC = new btConeTwistConstraint(*m_bodies[BODYPART_SPINE], *m_bodies[BODYPART_HEAD], localA, localB);
coneC->setLimit(M_PI_4, M_PI_4, M_PI_2);
m_joints[JOINT_SPINE_HEAD] = coneC;
m_ownerWorld->addConstraint(m_joints[JOINT_SPINE_HEAD], true);
localA.setIdentity(); localB.setIdentity();
localA.getBasis().setEulerZYX(0,0,-M_PI_4*5); localA.setOrigin(btVector3(btScalar(-0.18), btScalar(-0.10), btScalar(0.)));
localB.getBasis().setEulerZYX(0,0,M_PI_4*5); localB.setOrigin(btVector3(btScalar(0.), btScalar(0.225), btScalar(0.)));
coneC = new btConeTwistConstraint(*m_bodies[BODYPART_PELVIS], *m_bodies[BODYPART_LEFT_UPPER_LEG], localA, localB);
coneC->setLimit(M_PI_4, M_PI_4, 0);
m_joints[JOINT_LEFT_HIP] = coneC;
m_ownerWorld->addConstraint(m_joints[JOINT_LEFT_HIP], true);
localA.setIdentity(); localB.setIdentity();
localA.getBasis().setEulerZYX(0,M_PI_2,0); localA.setOrigin(btVector3(btScalar(0.), btScalar(-0.225), btScalar(0.)));
localB.getBasis().setEulerZYX(0,M_PI_2,0); localB.setOrigin(btVector3(btScalar(0.), btScalar(0.185), btScalar(0.)));
hingeC = new btHingeConstraint(*m_bodies[BODYPART_LEFT_UPPER_LEG], *m_bodies[BODYPART_LEFT_LOWER_LEG], localA, localB);
hingeC->setLimit(btScalar(0), btScalar(M_PI_2));
m_joints[JOINT_LEFT_KNEE] = hingeC;
m_ownerWorld->addConstraint(m_joints[JOINT_LEFT_KNEE], true);
localA.setIdentity(); localB.setIdentity();
localA.getBasis().setEulerZYX(0,0,M_PI_4); localA.setOrigin(btVector3(btScalar(0.18), btScalar(-0.10), btScalar(0.)));
localB.getBasis().setEulerZYX(0,0,-M_PI_4); localB.setOrigin(btVector3(btScalar(0.), btScalar(0.225), btScalar(0.)));
coneC = new btConeTwistConstraint(*m_bodies[BODYPART_PELVIS], *m_bodies[BODYPART_RIGHT_UPPER_LEG], localA, localB);
coneC->setLimit(M_PI_4, M_PI_4, 0);
m_joints[JOINT_RIGHT_HIP] = coneC;
m_ownerWorld->addConstraint(m_joints[JOINT_RIGHT_HIP], true);
localA.setIdentity(); localB.setIdentity();
localA.getBasis().setEulerZYX(0,M_PI_2,0); localA.setOrigin(btVector3(btScalar(0.), btScalar(-0.225), btScalar(0.)));
localB.getBasis().setEulerZYX(0,M_PI_2,0); localB.setOrigin(btVector3(btScalar(0.), btScalar(0.185), btScalar(0.)));
hingeC = new btHingeConstraint(*m_bodies[BODYPART_RIGHT_UPPER_LEG], *m_bodies[BODYPART_RIGHT_LOWER_LEG], localA, localB);
hingeC->setLimit(btScalar(0), btScalar(M_PI_2));
m_joints[JOINT_RIGHT_KNEE] = hingeC;
m_ownerWorld->addConstraint(m_joints[JOINT_RIGHT_KNEE], true);
localA.setIdentity(); localB.setIdentity();
localA.getBasis().setEulerZYX(0,0,M_PI); localA.setOrigin(btVector3(btScalar(-0.2), btScalar(0.15), btScalar(0.)));
localB.getBasis().setEulerZYX(0,0,-M_PI_2); localB.setOrigin(btVector3(btScalar(0.), btScalar(-0.18), btScalar(0.)));
coneC = new btConeTwistConstraint(*m_bodies[BODYPART_SPINE], *m_bodies[BODYPART_LEFT_UPPER_ARM], localA, localB);
coneC->setLimit(M_PI_2, M_PI_2, 0);
m_joints[JOINT_LEFT_SHOULDER] = coneC;
m_ownerWorld->addConstraint(m_joints[JOINT_LEFT_SHOULDER], true);
localA.setIdentity(); localB.setIdentity();
localA.getBasis().setEulerZYX(0,M_PI_2,0); localA.setOrigin(btVector3(btScalar(0.), btScalar(0.18), btScalar(0.)));
localB.getBasis().setEulerZYX(0,M_PI_2,0); localB.setOrigin(btVector3(btScalar(0.), btScalar(-0.14), btScalar(0.)));
hingeC = new btHingeConstraint(*m_bodies[BODYPART_LEFT_UPPER_ARM], *m_bodies[BODYPART_LEFT_LOWER_ARM], localA, localB);
hingeC->setLimit(btScalar(-M_PI_2), btScalar(0));
m_joints[JOINT_LEFT_ELBOW] = hingeC;
m_ownerWorld->addConstraint(m_joints[JOINT_LEFT_ELBOW], true);
localA.setIdentity(); localB.setIdentity();
localA.getBasis().setEulerZYX(0,0,0); localA.setOrigin(btVector3(btScalar(0.2), btScalar(0.15), btScalar(0.)));
localB.getBasis().setEulerZYX(0,0,-M_PI_2); localB.setOrigin(btVector3(btScalar(0.), btScalar(-0.18), btScalar(0.)));
coneC = new btConeTwistConstraint(*m_bodies[BODYPART_SPINE], *m_bodies[BODYPART_RIGHT_UPPER_ARM], localA, localB);
coneC->setLimit(M_PI_2, M_PI_2, 0);
m_joints[JOINT_RIGHT_SHOULDER] = coneC;
m_ownerWorld->addConstraint(m_joints[JOINT_RIGHT_SHOULDER], true);
localA.setIdentity(); localB.setIdentity();
localA.getBasis().setEulerZYX(0,M_PI_2,0); localA.setOrigin(btVector3(btScalar(0.), btScalar(0.18), btScalar(0.)));
localB.getBasis().setEulerZYX(0,M_PI_2,0); localB.setOrigin(btVector3(btScalar(0.), btScalar(-0.14), btScalar(0.)));
hingeC = new btHingeConstraint(*m_bodies[BODYPART_RIGHT_UPPER_ARM], *m_bodies[BODYPART_RIGHT_LOWER_ARM], localA, localB);
hingeC->setLimit(btScalar(-M_PI_2), btScalar(0));
m_joints[JOINT_RIGHT_ELBOW] = hingeC;
m_ownerWorld->addConstraint(m_joints[JOINT_RIGHT_ELBOW], true);
}
~RagDoll ()
{
// Remove all constraints
for (int i = 0; i < JOINT_COUNT; ++i)
{
m_ownerWorld->removeConstraint(m_joints[i]);
delete m_joints[i]; m_joints[i] = 0;
}
// Remove all bodies and shapes
for (int i = 0; i < BODYPART_COUNT; ++i)
{
m_ownerWorld->removeRigidBody(m_bodies[i]);
delete m_bodies[i]->getMotionState();
delete m_bodies[i]; m_bodies[i] = 0;
delete m_shapes[i]; m_shapes[i] = 0;
}
}
};
int main(int argc,char* argv[])
{
RagdollDemo demoApp;
demoApp.initPhysics();
demoApp.setCameraDistance(btScalar(10.));
return glutmain(argc, argv,640,480,"Bullet Physics Demo. http://bullet.sf.net",&demoApp);
}
void RagdollDemo::initPhysics()
{
// Setup the basic world
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
btPoint3 worldAabbMin(-10000,-10000,-10000);
btPoint3 worldAabbMax(10000,10000,10000);
btBroadphaseInterface* overlappingPairCache = new btAxisSweep3 (worldAabbMin, worldAabbMax);
btConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,overlappingPairCache,solver);
m_dynamicsWorld->setDebugDrawer(&debugDrawer);
// Setup a big ground box
{
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(200.),btScalar(10.),btScalar(200.)));
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0,-10,0));
localCreateRigidBody(btScalar(0.),groundTransform,groundShape);
}
// Spawn one ragdoll
spawnRagdoll();
clientResetScene();
}
void RagdollDemo::spawnRagdoll(bool random)
{
RagDoll* ragDoll = new RagDoll (m_dynamicsWorld, btVector3 (0,1,0));
m_ragdolls.push_back(ragDoll);
}
void RagdollDemo::clientMoveAndDisplay()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//simple dynamics world doesn't handle fixed-time-stepping
float ms = m_clock.getTimeMicroseconds();
m_clock.reset();
float minFPS = 1000000.f/60.f;
if (ms > minFPS)
ms = minFPS;
if (m_dynamicsWorld)
m_dynamicsWorld->stepSimulation(ms / 1000000.f);
renderme();
glFlush();
glutSwapBuffers();
}
void RagdollDemo::displayCallback()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (m_dynamicsWorld)
m_dynamicsWorld->updateAabbs();
renderme();
glFlush();
glutSwapBuffers();
}
void RagdollDemo::keyboardCallback(unsigned char key, int x, int y)
{
switch (key)
{
case 'e':
spawnRagdoll(true);
break;
default:
DemoApplication::keyboardCallback(key, x, y);
}
}
// Setup a big ground box
{
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(200.),btScalar(10.),btScalar(200.)));
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0,-10,0));
localCreateRigidBody(btScalar(0.),groundTransform,groundShape);
}
// Spawn one ragdoll
spawnRagdoll();
clientResetScene();
}
void RagdollDemo::spawnRagdoll(bool random)
{
RagDoll* ragDoll = new RagDoll (m_dynamicsWorld, btVector3 (0,1,0));
m_ragdolls.push_back(ragDoll);
}
void RagdollDemo::clientMoveAndDisplay()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//simple dynamics world doesn't handle fixed-time-stepping
float ms = m_clock.getTimeMicroseconds();
m_clock.reset();
float minFPS = 1000000.f/60.f;
if (ms > minFPS)
ms = minFPS;
if (m_dynamicsWorld)
m_dynamicsWorld->stepSimulation(ms / 1000000.f);
renderme();
glFlush();
glutSwapBuffers();
}
void RagdollDemo::displayCallback()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (m_dynamicsWorld)
m_dynamicsWorld->updateAabbs();
renderme();
glFlush();
glutSwapBuffers();
}
void RagdollDemo::keyboardCallback(unsigned char key, int x, int y)
{
switch (key)
{
case 'e':
spawnRagdoll(true);
break;
default:
DemoApplication::keyboardCallback(key, x, y);
}
}

View File

@@ -104,8 +104,8 @@ void UserCollisionAlgorithm::initPhysics()
btCollisionShape* trimeshShape = new btBvhTriangleMeshShape(trimesh,useQuantizedBvhTree);
//ConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
btCollisionDispatcher* dispatcher = new btCollisionDispatcher();
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
btVector3 maxAabb(10000,10000,10000);
btBroadphaseInterface* broadphase = new btAxisSweep3(-maxAabb,maxAabb);//SimpleBroadphase();

View File

@@ -118,7 +118,8 @@ void VehicleDemo::setupPhysics()
#endif
btCollisionShape* groundShape = new btBoxShape(btVector3(50,3,50));
btCollisionDispatcher* dispatcher = new btCollisionDispatcher();
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
btVector3 worldMin(-1000,-1000,-1000);
btVector3 worldMax(1000,1000,1000);
btBroadphaseInterface* pairCache = new btAxisSweep3(worldMin,worldMax);
@@ -490,7 +491,7 @@ void VehicleDemo::clientResetScene()
m_carChassis->setCenterOfMassTransform(btTransform::getIdentity());
m_carChassis->setLinearVelocity(btVector3(0,0,0));
m_carChassis->setAngularVelocity(btVector3(0,0,0));
m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(m_carChassis->getBroadphaseHandle());
m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(m_carChassis->getBroadphaseHandle(),getDynamicsWorld()->getDispatcher());
if (m_vehicle)
{
m_vehicle->resetSuspension();