another large series of changes, related to the refactoring.

CompoundShapes are tricky to manage with respect to persistent contact points and swapped order of btCollisionObjects,
During dispatch, finding an algorith etc. order can be swapped.
fixed several other issues, related to SimpleBroadphase (removing a proxy was not working)
This commit is contained in:
ejcoumans
2006-10-06 05:22:13 +00:00
parent 97b287a6bc
commit bf847b839a
54 changed files with 1852 additions and 1946 deletions

View File

@@ -134,6 +134,7 @@ void BspDemo::initPhysics(char* bspfilename)
///Setup a Physics Simulation Environment ///Setup a Physics Simulation Environment
m_dynamicsWorld = new btDiscreteDynamicsWorld(); m_dynamicsWorld = new btDiscreteDynamicsWorld();
m_dynamicsWorld->setGravity(-m_cameraUp);
#ifdef QUAKE_BSP_IMPORTING #ifdef QUAKE_BSP_IMPORTING

View File

@@ -14,7 +14,8 @@ subject to the following restrictions:
*/ */
//#define USER_DEFINED_FRICTION_MODEL 1 //#define USER_DEFINED_FRICTION_MODEL 1
//#define PRINT_CONTACT_STATISTICS 1 #define PRINT_CONTACT_STATISTICS 1
//#define USE_KINEMATIC_GROUND 1
#define REGISTER_CUSTOM_COLLISION_ALGORITHM 1 #define REGISTER_CUSTOM_COLLISION_ALGORITHM 1
#include "btBulletDynamicsCommon.h" #include "btBulletDynamicsCommon.h"
@@ -121,6 +122,14 @@ void CcdPhysicsDemo::clientMoveAndDisplay()
{ {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
#ifdef USE_KINEMATIC_GROUND
//btQuaternion kinRotation(btVector3(0,0,1),0.);
btVector3 kinTranslation(0,0,0.01);
//kinematic object
m_dynamicsWorld->getCollisionObjectArray()[0]->m_worldTransform.getOrigin() += kinTranslation;
#endif //USE_KINEMATIC_GROUND
if (m_dynamicsWorld) if (m_dynamicsWorld)
m_dynamicsWorld->stepSimulation(deltaTime); m_dynamicsWorld->stepSimulation(deltaTime);
@@ -243,7 +252,7 @@ void CcdPhysicsDemo::initPhysics()
btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver; btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver); m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver);
//setGravity(btVector3(0,0,1)); m_dynamicsWorld->setGravity(btVector3(0,-10,0));
m_dynamicsWorld->setDebugDrawer(&debugDrawer); m_dynamicsWorld->setDebugDrawer(&debugDrawer);
@@ -328,6 +337,14 @@ void CcdPhysicsDemo::initPhysics()
mass = 0.f; mass = 0.f;
btRigidBody* body = localCreateRigidBody(mass,trans,shape); btRigidBody* body = localCreateRigidBody(mass,trans,shape);
#ifdef USE_KINEMATIC_GROUND
if (mass == 0.f)
{
body->m_collisionFlags = btCollisionObject::CF_KINEMATIC_OJBECT;
body->SetActivationState(DISABLE_DEACTIVATION);
body->setLinearVelocity(btVector3(0,0,1));
}
#endif //USE_KINEMATIC_GROUND
// Only do CCD if motion in one timestep (1.f/60.f) exceeds CUBE_HALF_EXTENTS // Only do CCD if motion in one timestep (1.f/60.f) exceeds CUBE_HALF_EXTENTS

View File

@@ -100,7 +100,7 @@ class MyColladaConverter : public ColladaConverter
virtual void setGravity(const btVector3& grav) virtual void setGravity(const btVector3& grav)
{ {
m_demoApp->setGravity(grav); m_demoApp->getDynamicsWorld()->setGravity(grav);
} }
virtual void setCameraInfo(const btVector3& camUp,int forwardAxis) virtual void setCameraInfo(const btVector3& camUp,int forwardAxis)
{ {

View File

@@ -60,12 +60,12 @@ bool CustomMaterialCombinerCallback(btManifoldPoint& cp, const btCollisionObject
float restitution0 = colObj0->getRestitution(); float restitution0 = colObj0->getRestitution();
float restitution1 = colObj1->getRestitution(); float restitution1 = colObj1->getRestitution();
if (colObj0->m_collisionFlags & btCollisionObject::customMaterialCallback) if (colObj0->m_collisionFlags & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK)
{ {
friction0 = 1.0;//partId0,index0 friction0 = 1.0;//partId0,index0
restitution0 = 0.f; restitution0 = 0.f;
} }
if (colObj1->m_collisionFlags & btCollisionObject::customMaterialCallback) if (colObj1->m_collisionFlags & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK)
{ {
if (index1&1) if (index1&1)
{ {
@@ -161,10 +161,10 @@ void ConcaveDemo::initPhysics()
btRigidBody* staticBody = localCreateRigidBody(mass, startTransform,trimeshShape); btRigidBody* staticBody = localCreateRigidBody(mass, startTransform,trimeshShape);
staticBody->m_collisionFlags |=btCollisionObject::isStatic; staticBody->m_collisionFlags |=btCollisionObject::CF_STATIC_OBJECT;
//enable custom material callback //enable custom material callback
staticBody->m_collisionFlags |= btCollisionObject::customMaterialCallback; staticBody->m_collisionFlags |= btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK;
{ {
for (int i=0;i<10;i++) for (int i=0;i<10;i++)

View File

@@ -24,8 +24,8 @@ subject to the following restrictions:
#include "GL_ShapeDrawer.h" #include "GL_ShapeDrawer.h"
#include "LinearMath/btQuickprof.h" #include "LinearMath/btQuickprof.h"
#include "BMF_Api.h" #include "BMF_Api.h"
#include "BulletDynamics/Dynamics/btMassProps.h"
extern bool gDisableDeactivation;
int numObjects = 0; int numObjects = 0;
const int maxNumObjects = 16384; const int maxNumObjects = 16384;
btTransform startTransforms[maxNumObjects]; btTransform startTransforms[maxNumObjects];
@@ -37,7 +37,6 @@ DemoApplication::DemoApplication()
: :
m_dynamicsWorld(0), m_dynamicsWorld(0),
m_pickConstraint(0), m_pickConstraint(0),
m_gravity(0,-10,0),
m_cameraDistance(15.0), m_cameraDistance(15.0),
m_debugMode(0), m_debugMode(0),
m_ele(0.f), m_ele(0.f),
@@ -58,6 +57,7 @@ m_gravity(0,-10,0),
} }
DemoApplication::~DemoApplication() DemoApplication::~DemoApplication()
{ {
@@ -290,10 +290,18 @@ void DemoApplication::keyboardCallback(unsigned char key, int x, int y)
m_debugMode = m_debugMode & (~btIDebugDraw::DBG_NoDeactivation); m_debugMode = m_debugMode & (~btIDebugDraw::DBG_NoDeactivation);
else else
m_debugMode |= btIDebugDraw::DBG_NoDeactivation; m_debugMode |= btIDebugDraw::DBG_NoDeactivation;
if (m_debugMode | btIDebugDraw::DBG_NoDeactivation)
{
gDisableDeactivation = true;
} else
{
gDisableDeactivation = false;
}
break; break;
case 'o' : case 'o' :
{ {
m_stepping = !m_stepping; m_stepping = !m_stepping;
@@ -346,6 +354,29 @@ void DemoApplication::specialKeyboard(int key, int x, int y)
{ {
switch (key) switch (key)
{ {
case GLUT_KEY_F1:
{
break;
}
case GLUT_KEY_F2:
{
break;
}
case GLUT_KEY_END:
{
int numObj = getDynamicsWorld()->getNumCollisionObjects();
if (numObj)
{
btCollisionObject* obj = getDynamicsWorld()->getCollisionObjectArray()[numObj-1];
getDynamicsWorld()->removeCollisionObject(obj);
}
break;
}
case GLUT_KEY_LEFT : stepLeft(); break; case GLUT_KEY_LEFT : stepLeft(); break;
case GLUT_KEY_RIGHT : stepRight(); break; case GLUT_KEY_RIGHT : stepRight(); break;
case GLUT_KEY_UP : stepFront(); break; case GLUT_KEY_UP : stepFront(); break;
@@ -522,7 +553,8 @@ void DemoApplication::mouseFunc(int button, int state, int x, int y)
btRigidBody* body = btRigidBody::upcast(rayCallback.m_collisionObject); btRigidBody* body = btRigidBody::upcast(rayCallback.m_collisionObject);
if (body) if (body)
{ {
if (!body->IsStatic()) //other exclusions?
if (!(body->isStaticObject() || body->isKinematicObject()))
{ {
pickedBody = body; pickedBody = body;
pickedBody->SetActivationState(DISABLE_DEACTIVATION); pickedBody->SetActivationState(DISABLE_DEACTIVATION);
@@ -616,26 +648,7 @@ btRigidBody* DemoApplication::localCreateRigidBody(float mass, const btTransform
btRigidBody* body = new btRigidBody(mass,startTransform,shape,localInertia); btRigidBody* body = new btRigidBody(mass,startTransform,shape,localInertia);
//filtering allows to excluded collision pairs, early in the collision pipeline (broadphase) m_dynamicsWorld->addRigidBody(body);
bool useFiltering = true;
if (useFiltering)
{
short collisionFilterGroup = isDynamic?
btBroadphaseProxy::DefaultFilter :
btBroadphaseProxy::StaticFilter;
short collisionFilterMask = isDynamic?
btBroadphaseProxy::AllFilter :
btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter;
m_dynamicsWorld->addCollisionObject(body,collisionFilterGroup,collisionFilterMask);
} else
{
//no collision filtering, so always create an overlapping pair, even between static-static etc.
m_dynamicsWorld->addCollisionObject(body);
}
//Bullet uses per-object gravity
body->setGravity(m_gravity);
return body; return body;
} }

View File

@@ -56,8 +56,6 @@ class DemoApplication
///constraint for mouse picking ///constraint for mouse picking
btTypedConstraint* m_pickConstraint; btTypedConstraint* m_pickConstraint;
btVector3 m_gravity;
float m_cameraDistance; float m_cameraDistance;
int m_debugMode; int m_debugMode;
@@ -141,10 +139,7 @@ public:
///Demo functions ///Demo functions
void shootBox(const btVector3& destination); void shootBox(const btVector3& destination);
void setGravity(const btVector3& grav)
{
m_gravity = grav;
}
btVector3 getRayTo(int x,int y); btVector3 getRayTo(int x,int y);
btRigidBody* localCreateRigidBody(float mass, const btTransform& startTransform,btCollisionShape* shape); btRigidBody* localCreateRigidBody(float mass, const btTransform& startTransform,btCollisionShape* shape);

View File

@@ -136,7 +136,7 @@ void UserCollisionAlgorithm::initPhysics()
btRigidBody* staticBody= localCreateRigidBody(mass, startTransform,trimeshShape); btRigidBody* staticBody= localCreateRigidBody(mass, startTransform,trimeshShape);
//enable custom material callback //enable custom material callback
staticBody->m_collisionFlags |= btCollisionObject::customMaterialCallback; staticBody->m_collisionFlags |= btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK;
{ {
for (int i=0;i<10;i++) for (int i=0;i<10;i++)

View File

@@ -18,6 +18,9 @@ subject to the following restrictions:
struct btBroadphaseProxy; struct btBroadphaseProxy;
class btDispatcher; class btDispatcher;
class btManifoldResult;
struct btCollisionObject;
struct btDispatcherInfo;
struct btCollisionAlgorithmConstructionInfo struct btCollisionAlgorithmConstructionInfo
{ {
@@ -57,9 +60,9 @@ public:
virtual ~btCollisionAlgorithm() {}; virtual ~btCollisionAlgorithm() {};
virtual void processCollision (btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,const struct btDispatcherInfo& dispatchInfo) = 0; virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) = 0;
virtual float calculateTimeOfImpact(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,const struct btDispatcherInfo& dispatchInfo) = 0; virtual float calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) = 0;
}; };

View File

@@ -20,7 +20,6 @@ class btCollisionAlgorithm;
struct btBroadphaseProxy; struct btBroadphaseProxy;
class btRigidBody; class btRigidBody;
struct btCollisionObject; struct btCollisionObject;
class btManifoldResult;
class btOverlappingPairCache; class btOverlappingPairCache;
enum btCollisionDispatcherId enum btCollisionDispatcherId
@@ -66,7 +65,7 @@ class btDispatcher
public: public:
virtual ~btDispatcher() ; virtual ~btDispatcher() ;
virtual btCollisionAlgorithm* findAlgorithm(btBroadphaseProxy& proxy0,btBroadphaseProxy& proxy1) = 0; virtual btCollisionAlgorithm* findAlgorithm(btCollisionObject* body0,btCollisionObject* body1) = 0;
// //
// asume dispatchers to have unique id's in the range [0..max dispacher] // asume dispatchers to have unique id's in the range [0..max dispacher]
@@ -79,13 +78,9 @@ public:
virtual void clearManifold(btPersistentManifold* manifold)=0; virtual void clearManifold(btPersistentManifold* manifold)=0;
virtual bool needsCollision(btBroadphaseProxy& proxy0,btBroadphaseProxy& proxy1) = 0; virtual bool needsCollision(btCollisionObject* body0,btCollisionObject* body1) = 0;
virtual bool needsResponse(const btCollisionObject& colObj0,const btCollisionObject& colObj1)=0; virtual bool needsResponse(btCollisionObject* body0,btCollisionObject* body1)=0;
virtual btManifoldResult* getNewManifoldResult(btCollisionObject* obj0,btCollisionObject* obj1,btPersistentManifold* manifold) =0;
virtual void releaseManifoldResult(btManifoldResult*)=0;
virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,btDispatcherInfo& dispatchInfo)=0; virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,btDispatcherInfo& dispatchInfo)=0;

View File

@@ -75,7 +75,7 @@ void btOverlappingPairCache::addOverlappingPair(btBroadphaseProxy* proxy0,btBroa
//don't add overlap with own //don't add overlap with own
assert(proxy0 != proxy1); assert(proxy0 != proxy1);
if (!needsCollision(proxy0,proxy1)) if (!needsBroadphaseCollision(proxy0,proxy1))
return; return;
@@ -92,7 +92,7 @@ void btOverlappingPairCache::addOverlappingPair(btBroadphaseProxy* proxy0,btBroa
///Also we can use a 2D bitmap, which can be useful for a future GPU implementation ///Also we can use a 2D bitmap, which can be useful for a future GPU implementation
btBroadphasePair* btOverlappingPairCache::findPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) btBroadphasePair* btOverlappingPairCache::findPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
{ {
if (!needsCollision(proxy0,proxy1)) if (!needsBroadphaseCollision(proxy0,proxy1))
return 0; return 0;
btBroadphasePair tmpPair(*proxy0,*proxy1); btBroadphasePair tmpPair(*proxy0,*proxy1);

View File

@@ -64,7 +64,7 @@ class btOverlappingPairCache : public btBroadphaseInterface
void removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy); void removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy);
inline bool needsCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const inline bool needsBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const
{ {
bool collides = proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask; bool collides = proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask;
collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask); collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);

View File

@@ -134,25 +134,7 @@ void btSimpleBroadphase::destroyProxy(btBroadphaseProxy* proxyOrg)
assert (index < m_maxProxies); assert (index < m_maxProxies);
m_freeProxies[--m_firstFreeProxy] = index; m_freeProxies[--m_firstFreeProxy] = index;
//removeOverlappingPairsContainingProxy(proxyOrg); removeOverlappingPairsContainingProxy(proxyOrg);
assert(0);
//then remove non-overlapping ones
/*for (i=0;i<GetNumOverlappingPairs();i++)
{
btBroadphasePair& pair = GetOverlappingPair(i);
btSimpleBroadphaseProxy* proxy0 = getSimpleProxyFromProxy(pair.m_pProxy0);
btSimpleBroadphaseProxy* proxy1 = getSimpleProxyFromProxy(pair.m_pProxy1);
if ((proxy0==proxyOrg) || (proxy1==proxyOrg))
{
removeOverlappingPair(pair);
}
}
*/
for (i=0;i<m_numProxies;i++) for (i=0;i<m_numProxies;i++)
{ {

View File

@@ -20,7 +20,8 @@ subject to the following restrictions:
typedef std::vector<struct btCollisionObject*> btCollisionObjectArray; typedef std::vector<struct btCollisionObject*> btCollisionObjectArray;
class btCollisionAlgorithm; class btCollisionAlgorithm;
struct btBroadphaseProxy; struct btCollisionObject;
struct btCollisionAlgorithmConstructionInfo; struct btCollisionAlgorithmConstructionInfo;
@@ -34,7 +35,7 @@ struct btCollisionAlgorithmCreateFunc
} }
virtual ~btCollisionAlgorithmCreateFunc(){}; virtual ~btCollisionAlgorithmCreateFunc(){};
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
{ {
return 0; return 0;
} }

View File

@@ -29,13 +29,13 @@ subject to the following restrictions:
int gNumManifold = 0; int gNumManifold = 0;
#include <stdio.h>
btCollisionDispatcher::btCollisionDispatcher (): btCollisionDispatcher::btCollisionDispatcher ():
m_useIslands(true), m_useIslands(true),
m_defaultManifoldResult(0,0,0),
m_count(0) m_count(0)
{ {
int i; int i;
@@ -121,18 +121,17 @@ void btCollisionDispatcher::releaseManifold(btPersistentManifold* manifold)
btCollisionAlgorithm* btCollisionDispatcher::findAlgorithm(btBroadphaseProxy& proxy0,btBroadphaseProxy& proxy1) btCollisionAlgorithm* btCollisionDispatcher::findAlgorithm(btCollisionObject* body0,btCollisionObject* body1)
{ {
#define USE_DISPATCH_REGISTRY_ARRAY 1 #define USE_DISPATCH_REGISTRY_ARRAY 1
#ifdef USE_DISPATCH_REGISTRY_ARRAY #ifdef USE_DISPATCH_REGISTRY_ARRAY
btCollisionObject* body0 = (btCollisionObject*)proxy0.m_clientObject;
btCollisionObject* body1 = (btCollisionObject*)proxy1.m_clientObject;
btCollisionAlgorithmConstructionInfo ci; btCollisionAlgorithmConstructionInfo ci;
ci.m_dispatcher = this; ci.m_dispatcher = this;
btCollisionAlgorithm* algo = m_doubleDispatch[body0->m_collisionShape->getShapeType()][body1->m_collisionShape->getShapeType()] btCollisionAlgorithm* algo = m_doubleDispatch[body0->m_collisionShape->getShapeType()][body1->m_collisionShape->getShapeType()]
->CreateCollisionAlgorithm(ci,&proxy0,&proxy1); ->CreateCollisionAlgorithm(ci,body0,body1);
#else #else
btCollisionAlgorithm* algo = internalFindAlgorithm(proxy0,proxy1); btCollisionAlgorithm* algo = internalFindAlgorithm(body0,body1);
#endif //USE_DISPATCH_REGISTRY_ARRAY #endif //USE_DISPATCH_REGISTRY_ARRAY
return algo; return algo;
} }
@@ -173,38 +172,36 @@ btCollisionAlgorithmCreateFunc* btCollisionDispatcher::internalFindCreateFunc(in
btCollisionAlgorithm* btCollisionDispatcher::internalFindAlgorithm(btBroadphaseProxy& proxy0,btBroadphaseProxy& proxy1) btCollisionAlgorithm* btCollisionDispatcher::internalFindAlgorithm(btCollisionObject* body0,btCollisionObject* body1)
{ {
m_count++; m_count++;
btCollisionObject* body0 = (btCollisionObject*)proxy0.m_clientObject;
btCollisionObject* body1 = (btCollisionObject*)proxy1.m_clientObject;
btCollisionAlgorithmConstructionInfo ci; btCollisionAlgorithmConstructionInfo ci;
ci.m_dispatcher = this; ci.m_dispatcher = this;
if (body0->m_collisionShape->isConvex() && body1->m_collisionShape->isConvex() ) if (body0->m_collisionShape->isConvex() && body1->m_collisionShape->isConvex() )
{ {
return new btConvexConvexAlgorithm(0,ci,&proxy0,&proxy1); return new btConvexConvexAlgorithm(0,ci,body0,body1);
} }
if (body0->m_collisionShape->isConvex() && body1->m_collisionShape->isConcave()) if (body0->m_collisionShape->isConvex() && body1->m_collisionShape->isConcave())
{ {
return new btConvexConcaveCollisionAlgorithm(ci,&proxy0,&proxy1); return new btConvexConcaveCollisionAlgorithm(ci,body0,body1,false);
} }
if (body1->m_collisionShape->isConvex() && body0->m_collisionShape->isConcave()) if (body1->m_collisionShape->isConvex() && body0->m_collisionShape->isConcave())
{ {
return new btConvexConcaveCollisionAlgorithm(ci,&proxy1,&proxy0); return new btConvexConcaveCollisionAlgorithm(ci,body0,body1,true);
} }
if (body0->m_collisionShape->isCompound()) if (body0->m_collisionShape->isCompound())
{ {
return new btCompoundCollisionAlgorithm(ci,&proxy0,&proxy1); return new btCompoundCollisionAlgorithm(ci,body0,body1,false);
} else } else
{ {
if (body1->m_collisionShape->isCompound()) if (body1->m_collisionShape->isCompound())
{ {
return new btCompoundCollisionAlgorithm(ci,&proxy1,&proxy0); return new btCompoundCollisionAlgorithm(ci,body0,body1,true);
} }
} }
@@ -213,33 +210,29 @@ btCollisionAlgorithm* btCollisionDispatcher::internalFindAlgorithm(btBroadphaseP
} }
bool btCollisionDispatcher::needsResponse(const btCollisionObject& colObj0,const btCollisionObject& colObj1) bool btCollisionDispatcher::needsResponse(btCollisionObject* body0,btCollisionObject* body1)
{ {
//here you can do filtering //here you can do filtering
bool hasResponse = bool hasResponse =
(!(colObj0.m_collisionFlags & btCollisionObject::noContactResponse)) && (body0->hasContactResponse() && body1->hasContactResponse());
(!(colObj1.m_collisionFlags & btCollisionObject::noContactResponse));
hasResponse = hasResponse && hasResponse = hasResponse &&
(colObj0.IsActive() || colObj1.IsActive()); (body0->IsActive() || body1->IsActive());
return hasResponse; return hasResponse;
} }
bool btCollisionDispatcher::needsCollision(btBroadphaseProxy& proxy0,btBroadphaseProxy& proxy1) bool btCollisionDispatcher::needsCollision(btCollisionObject* body0,btCollisionObject* body1)
{ {
btCollisionObject* body0 = (btCollisionObject*)proxy0.m_clientObject;
btCollisionObject* body1 = (btCollisionObject*)proxy1.m_clientObject;
assert(body0); assert(body0);
assert(body1); assert(body1);
bool needsCollision = true; bool needsCollision = true;
if ((body0->m_collisionFlags & btCollisionObject::isStatic) && //broadphase filtering already deals with this
(body1->m_collisionFlags & btCollisionObject::isStatic)) if ((body0->isStaticObject() || body0->isKinematicObject()) &&
needsCollision = false; (body1->isStaticObject() || body1->isKinematicObject()))
{
printf("warning btCollisionDispatcher::needsCollision: static-static collision!\n");
}
if ((!body0->IsActive()) && (!body1->IsActive())) if ((!body0->IsActive()) && (!body1->IsActive()))
needsCollision = false; needsCollision = false;
@@ -248,22 +241,8 @@ bool btCollisionDispatcher::needsCollision(btBroadphaseProxy& proxy0,btBroadphas
} }
///allows the user to get contact point callbacks
btManifoldResult* btCollisionDispatcher::getNewManifoldResult(btCollisionObject* obj0,btCollisionObject* obj1,btPersistentManifold* manifold)
{
//in-place, this prevents parallel dispatching, but just adding a list would fix that.
btManifoldResult* manifoldResult = new (&m_defaultManifoldResult) btManifoldResult(obj0,obj1,manifold);
return manifoldResult;
}
///allows the user to get contact point callbacks
void btCollisionDispatcher::releaseManifoldResult(btManifoldResult*)
{
}
class btCollisionPairCallback : public btOverlapCallback class btCollisionPairCallback : public btOverlapCallback
{ {
@@ -281,48 +260,35 @@ public:
virtual bool processOverlap(btBroadphasePair& pair) virtual bool processOverlap(btBroadphasePair& pair)
{ {
if (m_dispatcherId>= 0) btCollisionObject* body0 = (btCollisionObject*)pair.m_pProxy0->m_clientObject;
btCollisionObject* body1 = (btCollisionObject*)pair.m_pProxy1->m_clientObject;
if (!m_dispatcher->needsCollision(body0,body1))
return false;
//dispatcher will keep algorithms persistent in the collision pair
if (!pair.m_algorithms[m_dispatcherId])
{ {
//dispatcher will keep algorithms persistent in the collision pair pair.m_algorithms[m_dispatcherId] = m_dispatcher->findAlgorithm(
if (!pair.m_algorithms[m_dispatcherId]) body0,
{ body1);
pair.m_algorithms[m_dispatcherId] = m_dispatcher->findAlgorithm( }
*pair.m_pProxy0,
*pair.m_pProxy1);
}
if (pair.m_algorithms[m_dispatcherId]) if (pair.m_algorithms[m_dispatcherId])
{
if (m_dispatchInfo.m_dispatchFunc == btDispatcherInfo::DISPATCH_DISCRETE)
{
pair.m_algorithms[m_dispatcherId]->processCollision(pair.m_pProxy0,pair.m_pProxy1,m_dispatchInfo);
} else
{
float toi = pair.m_algorithms[m_dispatcherId]->calculateTimeOfImpact(pair.m_pProxy0,pair.m_pProxy1,m_dispatchInfo);
if (m_dispatchInfo.m_timeOfImpact > toi)
m_dispatchInfo.m_timeOfImpact = toi;
}
}
} else
{ {
//non-persistent algorithm dispatcher btManifoldResult* resultOut = m_dispatcher->internalGetNewManifoldResult(body0,body1);
btCollisionAlgorithm* algo = m_dispatcher->findAlgorithm( if (m_dispatchInfo.m_dispatchFunc == btDispatcherInfo::DISPATCH_DISCRETE)
*pair.m_pProxy0,
*pair.m_pProxy1);
if (algo)
{ {
if (m_dispatchInfo.m_dispatchFunc == btDispatcherInfo::DISPATCH_DISCRETE)
{ pair.m_algorithms[m_dispatcherId]->processCollision(body0,body1,m_dispatchInfo,resultOut);
algo->processCollision(pair.m_pProxy0,pair.m_pProxy1,m_dispatchInfo); } else
} else {
{ float toi = pair.m_algorithms[m_dispatcherId]->calculateTimeOfImpact(body0,body1,m_dispatchInfo,resultOut);
float toi = algo->calculateTimeOfImpact(pair.m_pProxy0,pair.m_pProxy1,m_dispatchInfo); if (m_dispatchInfo.m_timeOfImpact > toi)
if (m_dispatchInfo.m_timeOfImpact > toi) m_dispatchInfo.m_timeOfImpact = toi;
m_dispatchInfo.m_timeOfImpact = toi;
}
} }
m_dispatcher->internalReleaseManifoldResult(resultOut);
} }
return false; return false;

View File

@@ -56,8 +56,24 @@ class btCollisionDispatcher : public btDispatcher
btCollisionAlgorithmCreateFunc* m_swappedCompoundCreateFunc; btCollisionAlgorithmCreateFunc* m_swappedCompoundCreateFunc;
btCollisionAlgorithmCreateFunc* m_emptyCreateFunc; btCollisionAlgorithmCreateFunc* m_emptyCreateFunc;
public: public:
///allows the user to get contact point callbacks
inline btManifoldResult* internalGetNewManifoldResult(btCollisionObject* obj0,btCollisionObject* obj1)
{
//in-place, this prevents parallel dispatching, but just adding a list would fix that.
btManifoldResult* manifoldResult = new (&m_defaultManifoldResult) btManifoldResult(obj0,obj1);
return manifoldResult;
}
///allows the user to get contact point callbacks
inline void internalReleaseManifoldResult(btManifoldResult*)
{
}
///registerCollisionCreateFunc allows registration of custom/alternative collision create functions ///registerCollisionCreateFunc allows registration of custom/alternative collision create functions
void registerCollisionCreateFunc(int proxyType0,int proxyType1, btCollisionAlgorithmCreateFunc* createFunc); void registerCollisionCreateFunc(int proxyType0,int proxyType1, btCollisionAlgorithmCreateFunc* createFunc);
@@ -91,22 +107,16 @@ public:
virtual void releaseManifold(btPersistentManifold* manifold); virtual void releaseManifold(btPersistentManifold* manifold);
///allows the user to get contact point callbacks
virtual btManifoldResult* getNewManifoldResult(btCollisionObject* obj0,btCollisionObject* obj1,btPersistentManifold* manifold);
///allows the user to get contact point callbacks
virtual void releaseManifoldResult(btManifoldResult*);
virtual void clearManifold(btPersistentManifold* manifold); virtual void clearManifold(btPersistentManifold* manifold);
btCollisionAlgorithm* findAlgorithm(btBroadphaseProxy& proxy0,btBroadphaseProxy& proxy1); btCollisionAlgorithm* findAlgorithm(btCollisionObject* body0,btCollisionObject* body1);
btCollisionAlgorithm* internalFindAlgorithm(btBroadphaseProxy& proxy0,btBroadphaseProxy& proxy1); btCollisionAlgorithm* internalFindAlgorithm(btCollisionObject* body0,btCollisionObject* body1);
virtual bool needsCollision(btBroadphaseProxy& proxy0,btBroadphaseProxy& proxy1); virtual bool needsCollision(btCollisionObject* body0,btCollisionObject* body1);
virtual bool needsResponse(const btCollisionObject& colObj0,const btCollisionObject& colObj1); virtual bool needsResponse(btCollisionObject* body0,btCollisionObject* body1);
virtual int getUniqueId() { return RIGIDBODY_DISPATCHER;} virtual int getUniqueId() { return RIGIDBODY_DISPATCHER;}

View File

@@ -42,15 +42,11 @@ void btCollisionObject::ForceActivationState(int newState)
void btCollisionObject::activate() void btCollisionObject::activate()
{ {
if (!(m_collisionFlags & isStatic)) if (!(m_collisionFlags & (CF_STATIC_OBJECT|CF_KINEMATIC_OJBECT)))
{ {
SetActivationState(1); SetActivationState(ACTIVE_TAG);
m_deactivationTime = 0.f; m_deactivationTime = 0.f;
} }
} }
bool btCollisionObject::mergesSimulationIslands() const
{
//static objects, and object without contact response don't merge islands
return ( !(m_collisionFlags & (isStatic | noContactResponse)));
}

View File

@@ -43,9 +43,10 @@ struct btCollisionObject
enum CollisionFlags enum CollisionFlags
{ {
isStatic = 1, CF_STATIC_OBJECT= 1,
noContactResponse = 2, CF_KINEMATIC_OJBECT= 2,
customMaterialCallback = 4,//this allows per-triangle material (friction/restitution) CF_NO_CONTACT_RESPONSE = 4,
CF_CUSTOM_MATERIAL_CALLBACK = 8,//this allows per-triangle material (friction/restitution)
}; };
@@ -75,14 +76,24 @@ struct btCollisionObject
/// Don't do continuous collision detection if square motion (in one step) is less then m_ccdSquareMotionTreshold /// Don't do continuous collision detection if square motion (in one step) is less then m_ccdSquareMotionTreshold
float m_ccdSquareMotionTreshold; float m_ccdSquareMotionTreshold;
bool mergesSimulationIslands() const; inline bool mergesSimulationIslands() const
{
inline bool IsStatic() const { //static objects, kinematic and object without contact response don't merge islands
return m_collisionFlags & isStatic; return !(m_collisionFlags & (CF_STATIC_OBJECT | CF_KINEMATIC_OJBECT | CF_NO_CONTACT_RESPONSE) );
} }
inline bool HasContactResponse() {
return !(m_collisionFlags & noContactResponse); inline bool isStaticObject() const {
return m_collisionFlags & CF_STATIC_OBJECT;
}
inline bool isKinematicObject() const
{
return m_collisionFlags & CF_KINEMATIC_OJBECT;
}
inline bool hasContactResponse() const {
return !(m_collisionFlags & CF_NO_CONTACT_RESPONSE);
} }

View File

@@ -206,7 +206,6 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
if (castResult.m_fraction < resultCallback.m_closestHitFraction) if (castResult.m_fraction < resultCallback.m_closestHitFraction)
{ {
btCollisionWorld::LocalRayResult localRayResult btCollisionWorld::LocalRayResult localRayResult
( (
collisionObject, collisionObject,

View File

@@ -18,31 +18,24 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btCompoundShape.h" #include "BulletCollision/CollisionShapes/btCompoundShape.h"
btCompoundCollisionAlgorithm::btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) btCompoundCollisionAlgorithm::btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped)
:m_dispatcher(ci.m_dispatcher), :m_isSwapped(isSwapped)
m_compoundProxy(*proxy0),
m_otherProxy(*proxy1)
{ {
btCollisionObject* colObj = static_cast<btCollisionObject*>(m_compoundProxy.m_clientObject); btCollisionObject* colObj = m_isSwapped? body1 : body0;
btCollisionObject* otherObj = m_isSwapped? body0 : body1;
assert (colObj->m_collisionShape->isCompound()); assert (colObj->m_collisionShape->isCompound());
btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->m_collisionShape); btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->m_collisionShape);
int numChildren = compoundShape->getNumChildShapes(); int numChildren = compoundShape->getNumChildShapes();
m_childProxies.resize( numChildren );
int i; int i;
for (i=0;i<numChildren;i++)
{
m_childProxies[i] = btBroadphaseProxy(*proxy0);
}
m_childCollisionAlgorithms.resize(numChildren); m_childCollisionAlgorithms.resize(numChildren);
for (i=0;i<numChildren;i++) for (i=0;i<numChildren;i++)
{ {
btCollisionShape* childShape = compoundShape->getChildShape(i); btCollisionShape* childShape = compoundShape->getChildShape(i);
btCollisionObject* colObj = static_cast<btCollisionObject*>(m_childProxies[i].m_clientObject);
btCollisionShape* orgShape = colObj->m_collisionShape; btCollisionShape* orgShape = colObj->m_collisionShape;
colObj->m_collisionShape = childShape; colObj->m_collisionShape = childShape;
m_childCollisionAlgorithms[i] = m_dispatcher->findAlgorithm(m_childProxies[i],m_otherProxy); m_childCollisionAlgorithms[i] = ci.m_dispatcher->findAlgorithm(colObj,otherObj);
colObj->m_collisionShape =orgShape; colObj->m_collisionShape =orgShape;
} }
} }
@@ -58,11 +51,12 @@ btCompoundCollisionAlgorithm::~btCompoundCollisionAlgorithm()
} }
} }
void btCompoundCollisionAlgorithm::processCollision (btBroadphaseProxy* ,btBroadphaseProxy* ,const btDispatcherInfo& dispatchInfo) void btCompoundCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{ {
btCollisionObject* colObj = static_cast<btCollisionObject*>(m_compoundProxy.m_clientObject); btCollisionObject* colObj = m_isSwapped? body1 : body0;
assert (colObj->m_collisionShape->isCompound()); btCollisionObject* otherObj = m_isSwapped? body0 : body1;
assert (colObj->m_collisionShape->isCompound());
btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->m_collisionShape); btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->m_collisionShape);
//We will use the OptimizedBVH, AABB tree to cull potential child-overlaps //We will use the OptimizedBVH, AABB tree to cull potential child-overlaps
@@ -72,14 +66,12 @@ void btCompoundCollisionAlgorithm::processCollision (btBroadphaseProxy* ,btBroad
//then use each overlapping node AABB against Tree0 //then use each overlapping node AABB against Tree0
//and vise versa. //and vise versa.
int numChildren = m_childCollisionAlgorithms.size(); int numChildren = m_childCollisionAlgorithms.size();
int i; int i;
for (i=0;i<numChildren;i++) for (i=0;i<numChildren;i++)
{ {
//temporarily exchange parent btCollisionShape with childShape, and recurse //temporarily exchange parent btCollisionShape with childShape, and recurse
btCollisionShape* childShape = compoundShape->getChildShape(i); btCollisionShape* childShape = compoundShape->getChildShape(i);
btCollisionObject* colObj = static_cast<btCollisionObject*>(m_childProxies[i].m_clientObject);
//backup //backup
btTransform orgTrans = colObj->m_worldTransform; btTransform orgTrans = colObj->m_worldTransform;
@@ -88,18 +80,21 @@ void btCompoundCollisionAlgorithm::processCollision (btBroadphaseProxy* ,btBroad
btTransform childTrans = compoundShape->getChildTransform(i); btTransform childTrans = compoundShape->getChildTransform(i);
btTransform newChildWorldTrans = orgTrans*childTrans ; btTransform newChildWorldTrans = orgTrans*childTrans ;
colObj->m_worldTransform = newChildWorldTrans; colObj->m_worldTransform = newChildWorldTrans;
//the contactpoint is still projected back using the original inverted worldtrans
colObj->m_collisionShape = childShape; colObj->m_collisionShape = childShape;
m_childCollisionAlgorithms[i]->processCollision(&m_childProxies[i],&m_otherProxy,dispatchInfo); m_childCollisionAlgorithms[i]->processCollision(colObj,otherObj,dispatchInfo,resultOut);
//revert back //revert back
colObj->m_collisionShape =orgShape; colObj->m_collisionShape =orgShape;
colObj->m_worldTransform = orgTrans; colObj->m_worldTransform = orgTrans;
} }
} }
float btCompoundCollisionAlgorithm::calculateTimeOfImpact(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,const btDispatcherInfo& dispatchInfo) float btCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{ {
btCollisionObject* colObj = static_cast<btCollisionObject*>(m_compoundProxy.m_clientObject);
btCollisionObject* colObj = m_isSwapped? body1 : body0;
btCollisionObject* otherObj = m_isSwapped? body0 : body1;
assert (colObj->m_collisionShape->isCompound()); assert (colObj->m_collisionShape->isCompound());
btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->m_collisionShape); btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->m_collisionShape);
@@ -119,7 +114,6 @@ float btCompoundCollisionAlgorithm::calculateTimeOfImpact(btBroadphaseProxy* pro
{ {
//temporarily exchange parent btCollisionShape with childShape, and recurse //temporarily exchange parent btCollisionShape with childShape, and recurse
btCollisionShape* childShape = compoundShape->getChildShape(i); btCollisionShape* childShape = compoundShape->getChildShape(i);
btCollisionObject* colObj = static_cast<btCollisionObject*>(m_childProxies[i].m_clientObject);
//backup //backup
btTransform orgTrans = colObj->m_worldTransform; btTransform orgTrans = colObj->m_worldTransform;
@@ -130,7 +124,7 @@ float btCompoundCollisionAlgorithm::calculateTimeOfImpact(btBroadphaseProxy* pro
colObj->m_worldTransform = newChildWorldTrans; colObj->m_worldTransform = newChildWorldTrans;
colObj->m_collisionShape = childShape; colObj->m_collisionShape = childShape;
float frac = m_childCollisionAlgorithms[i]->calculateTimeOfImpact(&m_childProxies[i],&m_otherProxy,dispatchInfo); float frac = m_childCollisionAlgorithms[i]->calculateTimeOfImpact(colObj,otherObj,dispatchInfo,resultOut);
if (frac<hitFraction) if (frac<hitFraction)
{ {
hitFraction = frac; hitFraction = frac;

View File

@@ -30,40 +30,32 @@ class btDispatcher;
/// Place holder, not fully implemented yet /// Place holder, not fully implemented yet
class btCompoundCollisionAlgorithm : public btCollisionAlgorithm class btCompoundCollisionAlgorithm : public btCollisionAlgorithm
{ {
btDispatcher* m_dispatcher;
btBroadphaseProxy m_compoundProxy;
btBroadphaseProxy m_otherProxy;
std::vector<btBroadphaseProxy> m_childProxies;
std::vector<btCollisionAlgorithm*> m_childCollisionAlgorithms; std::vector<btCollisionAlgorithm*> m_childCollisionAlgorithms;
bool m_isSwapped;
btBroadphaseProxy m_compound;
btBroadphaseProxy m_other;
public: public:
btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped);
virtual ~btCompoundCollisionAlgorithm(); virtual ~btCompoundCollisionAlgorithm();
virtual void processCollision (btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,const btDispatcherInfo& dispatchInfo); virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
float calculateTimeOfImpact(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,const btDispatcherInfo& dispatchInfo); float calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
struct CreateFunc :public btCollisionAlgorithmCreateFunc struct CreateFunc :public btCollisionAlgorithmCreateFunc
{ {
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
{ {
return new btCompoundCollisionAlgorithm(ci,proxy0,proxy1); return new btCompoundCollisionAlgorithm(ci,body0,body1,false);
} }
}; };
struct SwappedCreateFunc :public btCollisionAlgorithmCreateFunc struct SwappedCreateFunc :public btCollisionAlgorithmCreateFunc
{ {
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
{ {
return new btCompoundCollisionAlgorithm(ci,proxy1,proxy0); return new btCompoundCollisionAlgorithm(ci,body0,body1,true);
} }
}; };

View File

@@ -27,10 +27,10 @@ subject to the following restrictions:
#include "LinearMath/btIDebugDraw.h" #include "LinearMath/btIDebugDraw.h"
#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" #include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
btConvexConcaveCollisionAlgorithm::btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) btConvexConcaveCollisionAlgorithm::btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1,bool isSwapped)
: btCollisionAlgorithm(ci),m_convex(*proxy0),m_concave(*proxy1), : btCollisionAlgorithm(ci),
m_btConvexTriangleCallback(ci.m_dispatcher,proxy0,proxy1) m_isSwapped(isSwapped),
m_btConvexTriangleCallback(ci.m_dispatcher,body0,body1,isSwapped)
{ {
} }
@@ -40,15 +40,17 @@ btConvexConcaveCollisionAlgorithm::~btConvexConcaveCollisionAlgorithm()
btConvexTriangleCallback::btConvexTriangleCallback(btDispatcher* dispatcher,btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1): btConvexTriangleCallback::btConvexTriangleCallback(btDispatcher* dispatcher,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped):
m_convexProxy(proxy0),m_triangleProxy(*proxy1),m_dispatcher(dispatcher), m_dispatcher(dispatcher),
m_dispatchInfoPtr(0) m_dispatchInfoPtr(0)
{ {
m_convexBody = isSwapped? body1:body0;
m_triBody = isSwapped? body0:body1;
// //
// create the manifold from the dispatcher 'manifold pool' // create the manifold from the dispatcher 'manifold pool'
// //
m_manifoldPtr = m_dispatcher->getNewManifold(proxy0->m_clientObject,proxy1->m_clientObject); m_manifoldPtr = m_dispatcher->getNewManifold(m_convexBody,m_triBody);
clearCache(); clearCache();
} }
@@ -80,7 +82,7 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i
btCollisionAlgorithmConstructionInfo ci; btCollisionAlgorithmConstructionInfo ci;
ci.m_dispatcher = m_dispatcher; ci.m_dispatcher = m_dispatcher;
btCollisionObject* ob = static_cast<btCollisionObject*>(m_triangleProxy.m_clientObject); btCollisionObject* ob = static_cast<btCollisionObject*>(m_triBody);
@@ -102,9 +104,9 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i
} }
btCollisionObject* colObj = static_cast<btCollisionObject*>(m_convexProxy->m_clientObject); //btCollisionObject* colObj = static_cast<btCollisionObject*>(m_convexProxy->m_clientObject);
if (colObj->m_collisionShape->isConvex()) if (m_convexBody->m_collisionShape->isConvex())
{ {
btTriangleShape tm(triangle[0],triangle[1],triangle[2]); btTriangleShape tm(triangle[0],triangle[1],triangle[2]);
tm.setMargin(m_collisionMarginTriangle); tm.setMargin(m_collisionMarginTriangle);
@@ -114,9 +116,9 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i
ob->m_collisionShape = &tm; ob->m_collisionShape = &tm;
///this should use the btDispatcher, so the actual registered algorithm is used ///this should use the btDispatcher, so the actual registered algorithm is used
btConvexConvexAlgorithm cvxcvxalgo(m_manifoldPtr,ci,m_convexProxy,&m_triangleProxy); btConvexConvexAlgorithm cvxcvxalgo(m_manifoldPtr,ci,m_convexBody,m_triBody);
cvxcvxalgo.setShapeIdentifiers(-1,-1,partId,triangleIndex); cvxcvxalgo.setShapeIdentifiers(-1,-1,partId,triangleIndex);
cvxcvxalgo.processCollision(m_convexProxy,&m_triangleProxy,*m_dispatchInfoPtr); cvxcvxalgo.processCollision(m_convexBody,m_triBody,*m_dispatchInfoPtr,m_resultOut);
ob->m_collisionShape = tmpShape; ob->m_collisionShape = tmpShape;
} }
@@ -127,25 +129,19 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i
void btConvexTriangleCallback::setTimeStepAndCounters(float collisionMarginTriangle,const btDispatcherInfo& dispatchInfo) void btConvexTriangleCallback::setTimeStepAndCounters(float collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{ {
m_dispatchInfoPtr = &dispatchInfo; m_dispatchInfoPtr = &dispatchInfo;
m_collisionMarginTriangle = collisionMarginTriangle; m_collisionMarginTriangle = collisionMarginTriangle;
m_resultOut = resultOut;
//recalc aabbs //recalc aabbs
btCollisionObject* convexBody = (btCollisionObject* )m_convexProxy->m_clientObject;
btCollisionObject* triBody = (btCollisionObject* )m_triangleProxy.m_clientObject;
btTransform convexInTriangleSpace; btTransform convexInTriangleSpace;
convexInTriangleSpace = triBody->m_worldTransform.inverse() * convexBody->m_worldTransform; convexInTriangleSpace = m_triBody->m_worldTransform.inverse() * m_convexBody->m_worldTransform;
btCollisionShape* convexShape = static_cast<btCollisionShape*>(m_convexBody->m_collisionShape);
btCollisionShape* convexShape = static_cast<btCollisionShape*>(convexBody->m_collisionShape);
//CollisionShape* triangleShape = static_cast<btCollisionShape*>(triBody->m_collisionShape); //CollisionShape* triangleShape = static_cast<btCollisionShape*>(triBody->m_collisionShape);
convexShape->getAabb(convexInTriangleSpace,m_aabbMin,m_aabbMax); convexShape->getAabb(convexInTriangleSpace,m_aabbMin,m_aabbMax);
float extraMargin = collisionMarginTriangle;
float extraMargin = collisionMarginTriangle;//CONVEX_DISTANCE_MARGIN;//+0.1f;
btVector3 extra(extraMargin,extraMargin,extraMargin); btVector3 extra(extraMargin,extraMargin,extraMargin);
m_aabbMax += extra; m_aabbMax += extra;
@@ -159,34 +155,31 @@ void btConvexConcaveCollisionAlgorithm::clearCache()
} }
void btConvexConcaveCollisionAlgorithm::processCollision (btBroadphaseProxy* ,btBroadphaseProxy* ,const btDispatcherInfo& dispatchInfo) void btConvexConcaveCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{ {
btCollisionObject* convexBody = static_cast<btCollisionObject* >(m_convex.m_clientObject);
btCollisionObject* triBody = static_cast<btCollisionObject* >(m_concave.m_clientObject); btCollisionObject* convexBody = m_isSwapped ? body1 : body0;
btCollisionObject* triBody = m_isSwapped ? body0 : body1;
if (triBody->m_collisionShape->isConcave()) if (triBody->m_collisionShape->isConcave())
{ {
if (!m_dispatcher->needsCollision(m_convex,m_concave))
return;
btCollisionObject* triOb = triBody;
btCollisionObject* triOb = static_cast<btCollisionObject*>(m_concave.m_clientObject);
ConcaveShape* concaveShape = static_cast<ConcaveShape*>( triOb->m_collisionShape); ConcaveShape* concaveShape = static_cast<ConcaveShape*>( triOb->m_collisionShape);
if (convexBody->m_collisionShape->isConvex()) if (convexBody->m_collisionShape->isConvex())
{ {
float collisionMarginTriangle = concaveShape->getMargin(); float collisionMarginTriangle = concaveShape->getMargin();
m_btConvexTriangleCallback.setTimeStepAndCounters(collisionMarginTriangle,dispatchInfo); resultOut->setPersistentManifold(m_btConvexTriangleCallback.m_manifoldPtr);
m_btConvexTriangleCallback.setTimeStepAndCounters(collisionMarginTriangle,dispatchInfo,resultOut);
//Disable persistency. previously, some older algorithm calculated all contacts in one go, so you can clear it here. //Disable persistency. previously, some older algorithm calculated all contacts in one go, so you can clear it here.
//m_dispatcher->clearManifold(m_btConvexTriangleCallback.m_manifoldPtr); //m_dispatcher->clearManifold(m_btConvexTriangleCallback.m_manifoldPtr);
m_btConvexTriangleCallback.m_manifoldPtr->setBodies(convexBody,triBody);
m_btConvexTriangleCallback.m_manifoldPtr->setBodies(m_convex.m_clientObject,m_concave.m_clientObject);
concaveShape->processAllTriangles( &m_btConvexTriangleCallback,m_btConvexTriangleCallback.getAabbMin(),m_btConvexTriangleCallback.getAabbMax()); concaveShape->processAllTriangles( &m_btConvexTriangleCallback,m_btConvexTriangleCallback.getAabbMin(),m_btConvexTriangleCallback.getAabbMax());
@@ -198,12 +191,14 @@ void btConvexConcaveCollisionAlgorithm::processCollision (btBroadphaseProxy* ,bt
} }
float btConvexConcaveCollisionAlgorithm::calculateTimeOfImpact(btBroadphaseProxy* ,btBroadphaseProxy* ,const btDispatcherInfo& dispatchInfo) float btConvexConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{ {
btCollisionObject* convexbody = m_isSwapped ? body1 : body0;
btCollisionObject* triBody = m_isSwapped ? body0 : body1;
//quick approximation using raycast, todo: hook up to the continuous collision detection (one of the btConvexCast) //quick approximation using raycast, todo: hook up to the continuous collision detection (one of the btConvexCast)
btCollisionObject* convexbody = (btCollisionObject* )m_convex.m_clientObject;
btCollisionObject* triBody = static_cast<btCollisionObject* >(m_concave.m_clientObject);
//only perform CCD above a certain treshold, this prevents blocking on the long run //only perform CCD above a certain treshold, this prevents blocking on the long run
//because object in a blocked ccd state (hitfraction<1) get their linear velocity halved each frame... //because object in a blocked ccd state (hitfraction<1) get their linear velocity halved each frame...
@@ -217,9 +212,9 @@ float btConvexConcaveCollisionAlgorithm::calculateTimeOfImpact(btBroadphaseProxy
//btVector3 to = convexbody->m_interpolationWorldTransform.getOrigin(); //btVector3 to = convexbody->m_interpolationWorldTransform.getOrigin();
//todo: only do if the motion exceeds the 'radius' //todo: only do if the motion exceeds the 'radius'
btTransform worldToLocalTrimesh = triBody->m_worldTransform.inverse(); btTransform triInv = triBody->m_worldTransform.inverse();
btTransform convexFromLocal = worldToLocalTrimesh * convexbody->m_worldTransform; btTransform convexFromLocal = triInv * convexbody->m_worldTransform;
btTransform convexToLocal = worldToLocalTrimesh * convexbody->m_interpolationWorldTransform; btTransform convexToLocal = triInv * convexbody->m_interpolationWorldTransform;
struct LocalTriangleSphereCastCallback : public btTriangleCallback struct LocalTriangleSphereCastCallback : public btTriangleCallback
{ {
@@ -285,7 +280,7 @@ float btConvexConcaveCollisionAlgorithm::calculateTimeOfImpact(btBroadphaseProxy
raycastCallback.m_hitFraction = convexbody->m_hitFraction; raycastCallback.m_hitFraction = convexbody->m_hitFraction;
btCollisionObject* concavebody = (btCollisionObject* )m_concave.m_clientObject; btCollisionObject* concavebody = triBody;
ConcaveShape* triangleMesh = (ConcaveShape*) concavebody->m_collisionShape; ConcaveShape* triangleMesh = (ConcaveShape*) concavebody->m_collisionShape;

View File

@@ -28,12 +28,14 @@ class btDispatcher;
///For each triangle in the concave mesh that overlaps with the AABB of a convex (m_convexProxy), processTriangle is called. ///For each triangle in the concave mesh that overlaps with the AABB of a convex (m_convexProxy), processTriangle is called.
class btConvexTriangleCallback : public btTriangleCallback class btConvexTriangleCallback : public btTriangleCallback
{ {
btBroadphaseProxy* m_convexProxy; btCollisionObject* m_convexBody;
btBroadphaseProxy m_triangleProxy; btCollisionObject* m_triBody;
btVector3 m_aabbMin; btVector3 m_aabbMin;
btVector3 m_aabbMax ; btVector3 m_aabbMax ;
btManifoldResult* m_resultOut;
btDispatcher* m_dispatcher; btDispatcher* m_dispatcher;
const btDispatcherInfo* m_dispatchInfoPtr; const btDispatcherInfo* m_dispatchInfoPtr;
float m_collisionMarginTriangle; float m_collisionMarginTriangle;
@@ -43,9 +45,9 @@ int m_triangleCount;
btPersistentManifold* m_manifoldPtr; btPersistentManifold* m_manifoldPtr;
btConvexTriangleCallback(btDispatcher* dispatcher,btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); btConvexTriangleCallback(btDispatcher* dispatcher,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped);
void setTimeStepAndCounters(float collisionMarginTriangle,const btDispatcherInfo& dispatchInfo); void setTimeStepAndCounters(float collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual ~btConvexTriangleCallback(); virtual ~btConvexTriangleCallback();
@@ -71,38 +73,36 @@ int m_triangleCount;
class btConvexConcaveCollisionAlgorithm : public btCollisionAlgorithm class btConvexConcaveCollisionAlgorithm : public btCollisionAlgorithm
{ {
btBroadphaseProxy m_convex; bool m_isSwapped;
btBroadphaseProxy m_concave;
btConvexTriangleCallback m_btConvexTriangleCallback; btConvexTriangleCallback m_btConvexTriangleCallback;
public: public:
btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped);
virtual ~btConvexConcaveCollisionAlgorithm(); virtual ~btConvexConcaveCollisionAlgorithm();
virtual void processCollision (btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,const btDispatcherInfo& dispatchInfo); virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
float calculateTimeOfImpact(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,const btDispatcherInfo& dispatchInfo); float calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
void clearCache(); void clearCache();
struct CreateFunc :public btCollisionAlgorithmCreateFunc struct CreateFunc :public btCollisionAlgorithmCreateFunc
{ {
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
{ {
return new btConvexConcaveCollisionAlgorithm(ci,proxy0,proxy1); return new btConvexConcaveCollisionAlgorithm(ci,body0,body1,false);
} }
}; };
struct SwappedCreateFunc :public btCollisionAlgorithmCreateFunc struct SwappedCreateFunc :public btCollisionAlgorithmCreateFunc
{ {
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
{ {
return new btConvexConcaveCollisionAlgorithm(ci,proxy1,proxy0); return new btConvexConcaveCollisionAlgorithm(ci,body0,body1,true);
} }
}; };

View File

@@ -81,30 +81,21 @@ bool gDisableConvexCollision = false;
btConvexConvexAlgorithm::btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) btConvexConvexAlgorithm::btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1)
: btCollisionAlgorithm(ci), : btCollisionAlgorithm(ci),
m_gjkPairDetector(0,0,&m_simplexSolver,0), m_gjkPairDetector(0,0,&m_simplexSolver,0),
m_useEpa(!gUseEpa), m_useEpa(!gUseEpa),
m_box0(*proxy0),
m_box1(*proxy1),
m_ownManifold (false), m_ownManifold (false),
m_manifoldPtr(mf), m_manifoldPtr(mf),
m_lowLevelOfDetail(false) m_lowLevelOfDetail(false)
{ {
checkPenetrationDepthSolver(); checkPenetrationDepthSolver();
{
if (!m_manifoldPtr && m_dispatcher->needsCollision(m_box0,m_box1))
{
m_manifoldPtr = m_dispatcher->getNewManifold(proxy0->m_clientObject,proxy1->m_clientObject);
m_ownManifold = true;
}
}
} }
btConvexConvexAlgorithm::~btConvexConvexAlgorithm() btConvexConvexAlgorithm::~btConvexConvexAlgorithm()
{ {
if (m_ownManifold) if (m_ownManifold)
@@ -121,26 +112,6 @@ void btConvexConvexAlgorithm ::setLowLevelOfDetail(bool useLowLevel)
class FlippedContactResult : public btDiscreteCollisionDetectorInterface::Result
{
btDiscreteCollisionDetectorInterface::Result* m_org;
public:
FlippedContactResult(btDiscreteCollisionDetectorInterface::Result* org)
: m_org(org)
{
}
virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,float depth)
{
btVector3 flippedNormal = -normalOnBInWorld;
m_org->addContactPoint(flippedNormal,pointInWorld,depth);
}
};
static btMinkowskiPenetrationDepthSolver gPenetrationDepthSolver; static btMinkowskiPenetrationDepthSolver gPenetrationDepthSolver;
@@ -169,146 +140,28 @@ void btConvexConvexAlgorithm::checkPenetrationDepthSolver()
} }
#ifdef USE_HULL
Transform GetTransformFrombtTransform(const btTransform& trans)
{
//const btVector3& rowA0 = trans.getBasis().getRow(0);
////const btVector3& rowA1 = trans.getBasis().getRow(1);
//const btVector3& rowA2 = trans.getBasis().getRow(2);
btVector3 rowA0 = trans.getBasis().getColumn(0);
btVector3 rowA1 = trans.getBasis().getColumn(1);
btVector3 rowA2 = trans.getBasis().getColumn(2);
Vector3 x(rowA0.getX(),rowA0.getY(),rowA0.getZ());
Vector3 y(rowA1.getX(),rowA1.getY(),rowA1.getZ());
Vector3 z(rowA2.getX(),rowA2.getY(),rowA2.getZ());
Matrix33 ornA(x,y,z);
Point3 transA(
trans.getOrigin().getX(),
trans.getOrigin().getY(),
trans.getOrigin().getZ());
return Transform(ornA,transA);
}
class btManifoldResultCollector : public HullContactCollector
{
public:
btManifoldResult& m_manifoldResult;
btManifoldResultCollector(btManifoldResult& manifoldResult)
:m_manifoldResult(manifoldResult)
{
}
virtual ~btManifoldResultCollector() {};
virtual int BatchAddContactGroup(const btSeparation& sep,int numContacts,const Vector3& normalWorld,const Vector3& tangent,const Point3* positionsWorld,const float* depths)
{
for (int i=0;i<numContacts;i++)
{
//printf("numContacts = %i\n",numContacts);
btVector3 normalOnBInWorld(sep.m_axis.GetX(),sep.m_axis.GetY(),sep.m_axis.GetZ());
//normalOnBInWorld.normalize();
btVector3 pointInWorld(positionsWorld[i].GetX(),positionsWorld[i].GetY(),positionsWorld[i].GetZ());
float depth = -depths[i];
m_manifoldResult.addContactPoint(normalOnBInWorld,pointInWorld,depth);
}
return 0;
}
virtual int GetMaxNumContacts() const
{
return 4;
}
};
#endif //USE_HULL
// //
// Convex-Convex collision algorithm // Convex-Convex collision algorithm
// //
void btConvexConvexAlgorithm ::processCollision (btBroadphaseProxy* ,btBroadphaseProxy* ,const btDispatcherInfo& dispatchInfo) void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{ {
if (!m_manifoldPtr) if (!m_manifoldPtr)
return; {
//swapped?
m_manifoldPtr = m_dispatcher->getNewManifold(body0,body1);
m_ownManifold = true;
}
checkPenetrationDepthSolver(); checkPenetrationDepthSolver();
// printf("btConvexConvexAlgorithm::processCollision\n"); btConvexShape* min0 = static_cast<btConvexShape*>(body0->m_collisionShape);
btConvexShape* min1 = static_cast<btConvexShape*>(body1->m_collisionShape);
bool needsCollision = m_dispatcher->needsCollision(m_box0,m_box1);
if (!needsCollision)
return;
btCollisionObject* col0 = static_cast<btCollisionObject*>(m_box0.m_clientObject);
btCollisionObject* col1 = static_cast<btCollisionObject*>(m_box1.m_clientObject);
#ifdef USE_HULL
if (dispatchInfo.m_enableSatConvex)
{
if ((col0->m_collisionShape->isPolyhedral()) &&
(col1->m_collisionShape->isPolyhedral()))
{
btPolyhedralConvexShape* polyhedron0 = static_cast<btPolyhedralConvexShape*>(col0->m_collisionShape);
btPolyhedralConvexShape* polyhedron1 = static_cast<btPolyhedralConvexShape*>(col1->m_collisionShape);
if (polyhedron0->m_optionalHull && polyhedron1->m_optionalHull)
{
//printf("Hull-Hull");
//todo: cache this information, rather then initialize
btSeparation sep;
sep.m_featureA = 0;
sep.m_featureB = 0;
sep.m_contact = -1;
sep.m_separator = 0;
//convert from btTransform to Transform
Transform trA = GetTransformFrombtTransform(col0->m_worldTransform);
Transform trB = GetTransformFrombtTransform(col1->m_worldTransform);
//either use persistent manifold or clear it every time
m_dispatcher->clearManifold(m_manifoldPtr);
btManifoldResult* resultOut = m_dispatcher->getNewManifoldResult(col0,col1,m_manifoldPtr);
btManifoldResultCollector hullContactCollector(*resultOut);
Hull::ProcessHullHull(sep,*polyhedron0->m_optionalHull,*polyhedron1->m_optionalHull,
trA,trB,&hullContactCollector);
//user provided hull's, so we use SAT Hull collision detection
return;
}
}
}
#endif //USE_HULL
btManifoldResult* resultOut = m_dispatcher->getNewManifoldResult(col0,col1,m_manifoldPtr);
btConvexShape* min0 = static_cast<btConvexShape*>(col0->m_collisionShape);
btConvexShape* min1 = static_cast<btConvexShape*>(col1->m_collisionShape);
btGjkPairDetector::ClosestPointInput input; btGjkPairDetector::ClosestPointInput input;
//TODO: if (dispatchInfo.m_useContinuous) //TODO: if (dispatchInfo.m_useContinuous)
m_gjkPairDetector.setMinkowskiA(min0); m_gjkPairDetector.setMinkowskiA(min0);
m_gjkPairDetector.setMinkowskiB(min1); m_gjkPairDetector.setMinkowskiB(min1);
@@ -317,18 +170,18 @@ void btConvexConvexAlgorithm ::processCollision (btBroadphaseProxy* ,btBroadphas
// input.m_maximumDistanceSquared = 1e30f; // input.m_maximumDistanceSquared = 1e30f;
input.m_transformA = col0->m_worldTransform; input.m_transformA = body0->m_worldTransform;
input.m_transformB = col1->m_worldTransform; input.m_transformB = body1->m_worldTransform;
resultOut->setPersistentManifold(m_manifoldPtr);
m_gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw); m_gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
m_dispatcher->releaseManifoldResult(resultOut);
} }
bool disableCcd = false; bool disableCcd = false;
float btConvexConvexAlgorithm::calculateTimeOfImpact(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,const btDispatcherInfo& dispatchInfo) float btConvexConvexAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{ {
///Rather then checking ALL pairs, only calculate TOI when motion exceeds treshold ///Rather then checking ALL pairs, only calculate TOI when motion exceeds treshold
@@ -336,8 +189,6 @@ float btConvexConvexAlgorithm::calculateTimeOfImpact(btBroadphaseProxy* proxy0,b
///col0->m_worldTransform, ///col0->m_worldTransform,
float resultFraction = 1.f; float resultFraction = 1.f;
btCollisionObject* col1 = static_cast<btCollisionObject*>(m_box1.m_clientObject);
btCollisionObject* col0 = static_cast<btCollisionObject*>(m_box0.m_clientObject);
float squareMot0 = (col0->m_interpolationWorldTransform.getOrigin() - col0->m_worldTransform.getOrigin()).length2(); float squareMot0 = (col0->m_interpolationWorldTransform.getOrigin() - col0->m_worldTransform.getOrigin()).length2();
@@ -358,11 +209,6 @@ float btConvexConvexAlgorithm::calculateTimeOfImpact(btBroadphaseProxy* proxy0,b
//For proper CCD, better accuracy and handling of 'allowed' penetration should be added //For proper CCD, better accuracy and handling of 'allowed' penetration should be added
//also the mainloop of the physics should have a kind of toi queue (something like Brian Mirtich's application of Timewarp for Rigidbodies) //also the mainloop of the physics should have a kind of toi queue (something like Brian Mirtich's application of Timewarp for Rigidbodies)
bool needsCollision = m_dispatcher->needsCollision(m_box0,m_box1);
if (!needsCollision)
return 1.f;
/// Convex0 against sphere for Convex1 /// Convex0 against sphere for Convex1
{ {

View File

@@ -33,8 +33,6 @@ class btConvexConvexAlgorithm : public btCollisionAlgorithm
btGjkPairDetector m_gjkPairDetector; btGjkPairDetector m_gjkPairDetector;
bool m_useEpa; bool m_useEpa;
public: public:
btBroadphaseProxy m_box0;
btBroadphaseProxy m_box1;
bool m_ownManifold; bool m_ownManifold;
btPersistentManifold* m_manifoldPtr; btPersistentManifold* m_manifoldPtr;
@@ -46,13 +44,13 @@ public:
public: public:
btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1);
virtual ~btConvexConvexAlgorithm(); virtual ~btConvexConvexAlgorithm();
virtual void processCollision (btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,const btDispatcherInfo& dispatchInfo); virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual float calculateTimeOfImpact(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,const btDispatcherInfo& dispatchInfo); virtual float calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
void setLowLevelOfDetail(bool useLowLevel); void setLowLevelOfDetail(bool useLowLevel);
@@ -71,9 +69,9 @@ public:
struct CreateFunc :public btCollisionAlgorithmCreateFunc struct CreateFunc :public btCollisionAlgorithmCreateFunc
{ {
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
{ {
return new btConvexConvexAlgorithm(0,ci,proxy0,proxy1); return new btConvexConvexAlgorithm(0,ci,body0,body1);
} }
}; };

View File

@@ -22,12 +22,12 @@ btEmptyAlgorithm::btEmptyAlgorithm(const btCollisionAlgorithmConstructionInfo& c
{ {
} }
void btEmptyAlgorithm::processCollision (btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,const btDispatcherInfo& dispatchInfo) void btEmptyAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{ {
} }
float btEmptyAlgorithm::calculateTimeOfImpact(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,const btDispatcherInfo& dispatchInfo) float btEmptyAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{ {
return 1.f; return 1.f;
} }

View File

@@ -29,13 +29,13 @@ public:
btEmptyAlgorithm(const btCollisionAlgorithmConstructionInfo& ci); btEmptyAlgorithm(const btCollisionAlgorithmConstructionInfo& ci);
virtual void processCollision (btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,const btDispatcherInfo& dispatchInfo); virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual float calculateTimeOfImpact(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,const btDispatcherInfo& dispatchInfo); virtual float calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
struct CreateFunc :public btCollisionAlgorithmCreateFunc struct CreateFunc :public btCollisionAlgorithmCreateFunc
{ {
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
{ {
return new btEmptyAlgorithm(ci); return new btEmptyAlgorithm(ci);
} }

View File

@@ -43,25 +43,29 @@ inline btScalar calculateCombinedRestitution(const btCollisionObject* body0,cons
btManifoldResult::btManifoldResult(btCollisionObject* body0,btCollisionObject* body1,btPersistentManifold* manifoldPtr) btManifoldResult::btManifoldResult(btCollisionObject* body0,btCollisionObject* body1)
:m_manifoldPtr(manifoldPtr), :m_manifoldPtr(0),
m_body0(body0), m_body0(body0),
m_body1(body1) m_body1(body1)
{ {
} m_rootTransA = body0->m_worldTransform;
m_rootTransB = body1->m_worldTransform;
}
void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,float depth) void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,float depth)
{ {
assert(m_manifoldPtr);
//order in manifold needs to match
if (depth > m_manifoldPtr->getContactBreakingTreshold()) if (depth > m_manifoldPtr->getContactBreakingTreshold())
return; return;
bool isSwapped = m_manifoldPtr->getBody0() != m_body0;
btTransform transAInv = m_body0->m_worldTransform.inverse(); btTransform transAInv = isSwapped? m_rootTransB.inverse() : m_rootTransA.inverse();
btTransform transBInv= m_body1->m_worldTransform.inverse(); btTransform transBInv = isSwapped? m_rootTransA.inverse() : m_rootTransB.inverse();
//transAInv = m_body0->m_worldTransform.inverse();
//transBInv= m_body1->m_worldTransform.inverse();
btVector3 pointA = pointInWorld + normalOnBInWorld * depth; btVector3 pointA = pointInWorld + normalOnBInWorld * depth;
btVector3 localA = transAInv(pointA ); btVector3 localA = transAInv(pointA );
btVector3 localB = transBInv(pointInWorld); btVector3 localB = transBInv(pointInWorld);
@@ -88,8 +92,8 @@ void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const b
//User can override friction and/or restitution //User can override friction and/or restitution
if (gContactAddedCallback && if (gContactAddedCallback &&
//and if either of the two bodies requires custom material //and if either of the two bodies requires custom material
((m_body0->m_collisionFlags & btCollisionObject::customMaterialCallback) || ((m_body0->m_collisionFlags & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) ||
(m_body1->m_collisionFlags & btCollisionObject::customMaterialCallback))) (m_body1->m_collisionFlags & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK)))
{ {
//experimental feature info, for per-triangle material etc. //experimental feature info, for per-triangle material etc.
(*gContactAddedCallback)(newPt,m_body0,m_partId0,m_index0,m_body1,m_partId1,m_index1); (*gContactAddedCallback)(newPt,m_body0,m_partId0,m_index0,m_body1,m_partId1,m_index1);

View File

@@ -21,6 +21,7 @@ subject to the following restrictions:
struct btCollisionObject; struct btCollisionObject;
class btPersistentManifold; class btPersistentManifold;
class btManifoldPoint; class btManifoldPoint;
#include "LinearMath/btTransform.h"
typedef bool (*ContactAddedCallback)(btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1); typedef bool (*ContactAddedCallback)(btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1);
extern ContactAddedCallback gContactAddedCallback; extern ContactAddedCallback gContactAddedCallback;
@@ -31,6 +32,11 @@ extern ContactAddedCallback gContactAddedCallback;
class btManifoldResult : public btDiscreteCollisionDetectorInterface::Result class btManifoldResult : public btDiscreteCollisionDetectorInterface::Result
{ {
btPersistentManifold* m_manifoldPtr; btPersistentManifold* m_manifoldPtr;
//we need this for compounds
btTransform m_rootTransA;
btTransform m_rootTransB;
btCollisionObject* m_body0; btCollisionObject* m_body0;
btCollisionObject* m_body1; btCollisionObject* m_body1;
int m_partId0; int m_partId0;
@@ -39,10 +45,19 @@ class btManifoldResult : public btDiscreteCollisionDetectorInterface::Result
int m_index1; int m_index1;
public: public:
btManifoldResult(btCollisionObject* body0,btCollisionObject* body1,btPersistentManifold* manifoldPtr); btManifoldResult()
{
}
btManifoldResult(btCollisionObject* body0,btCollisionObject* body1);
virtual ~btManifoldResult() {}; virtual ~btManifoldResult() {};
void setPersistentManifold(btPersistentManifold* manifoldPtr)
{
m_manifoldPtr = manifoldPtr;
}
virtual void setShapeIdentifiers(int partId0,int index0, int partId1,int index1) virtual void setShapeIdentifiers(int partId0,int index0, int partId1,int index1)
{ {
m_partId0=partId0; m_partId0=partId0;

View File

@@ -238,7 +238,7 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
((colObj1) && colObj1->GetActivationState() != ISLAND_SLEEPING)) ((colObj1) && colObj1->GetActivationState() != ISLAND_SLEEPING))
{ {
//filtering for response //filtering for response
if (dispatcher->needsResponse(*colObj0,*colObj1)) if (dispatcher->needsResponse(colObj0,colObj1))
islandmanifold.push_back(manifold); islandmanifold.push_back(manifold);
} }
} }

View File

@@ -20,17 +20,16 @@ subject to the following restrictions:
#include "BulletCollision/CollisionDispatch/btCollisionObject.h" #include "BulletCollision/CollisionDispatch/btCollisionObject.h"
//#include <stdio.h> //#include <stdio.h>
btSphereBoxCollisionAlgorithm::btSphereBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) btSphereBoxCollisionAlgorithm::btSphereBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped)
: btCollisionAlgorithm(ci), : btCollisionAlgorithm(ci),
m_ownManifold(false), m_ownManifold(false),
m_manifoldPtr(mf) m_manifoldPtr(mf),
m_isSwapped(isSwapped)
{ {
m_sphereColObj = static_cast<btCollisionObject*>(proxy0->m_clientObject);
m_boxColObj = static_cast<btCollisionObject*>(proxy1->m_clientObject);
if (!m_manifoldPtr && m_dispatcher->needsCollision(*proxy0,*proxy1)) if (!m_manifoldPtr && m_dispatcher->needsCollision(col0,col1))
{ {
m_manifoldPtr = m_dispatcher->getNewManifold(proxy0->m_clientObject,proxy1->m_clientObject); m_manifoldPtr = m_dispatcher->getNewManifold(col0,col1);
m_ownManifold = true; m_ownManifold = true;
} }
} }
@@ -47,55 +46,59 @@ btSphereBoxCollisionAlgorithm::~btSphereBoxCollisionAlgorithm()
void btSphereBoxCollisionAlgorithm::processCollision (btBroadphaseProxy*,btBroadphaseProxy*,const btDispatcherInfo& dispatchInfo) void btSphereBoxCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{ {
if (!m_manifoldPtr) if (!m_manifoldPtr)
return; return;
btSphereShape* sphere0 = (btSphereShape*)m_sphereColObj ->m_collisionShape; btCollisionObject* sphereObj = m_isSwapped? body1 : body0;
btCollisionObject* boxObj = m_isSwapped? body0 : body1;
btSphereShape* sphere0 = (btSphereShape*)sphereObj ->m_collisionShape;
btVector3 normalOnSurfaceB; btVector3 normalOnSurfaceB;
btVector3 pOnBox,pOnSphere; btVector3 pOnBox,pOnSphere;
btVector3 sphereCenter = m_sphereColObj->m_worldTransform.getOrigin(); btVector3 sphereCenter = sphereObj->m_worldTransform.getOrigin();
btScalar radius = sphere0->getRadius(); btScalar radius = sphere0->getRadius();
float dist = getSphereDistance(pOnBox,pOnSphere,sphereCenter,radius); float dist = getSphereDistance(boxObj,pOnBox,pOnSphere,sphereCenter,radius);
if (dist < SIMD_EPSILON) if (dist < SIMD_EPSILON)
{ {
btVector3 normalOnSurfaceB = (pOnBox- pOnSphere).normalize(); btVector3 normalOnSurfaceB = (pOnBox- pOnSphere).normalize();
/// report a contact. internally this will be kept persistent, and contact reduction is done /// report a contact. internally this will be kept persistent, and contact reduction is done
btManifoldResult* resultOut = m_dispatcher->getNewManifoldResult(m_sphereColObj,m_boxColObj,m_manifoldPtr);
resultOut->setPersistentManifold(m_manifoldPtr);
resultOut->addContactPoint(normalOnSurfaceB,pOnBox,dist); resultOut->addContactPoint(normalOnSurfaceB,pOnBox,dist);
m_dispatcher->releaseManifoldResult(resultOut);
} }
} }
float btSphereBoxCollisionAlgorithm::calculateTimeOfImpact(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,const btDispatcherInfo& dispatchInfo) float btSphereBoxCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{ {
//not yet //not yet
return 1.f; return 1.f;
} }
btScalar btSphereBoxCollisionAlgorithm::getSphereDistance( btVector3& pointOnBox, btVector3& v3PointOnSphere, const btVector3& sphereCenter, btScalar fRadius ) btScalar btSphereBoxCollisionAlgorithm::getSphereDistance(btCollisionObject* boxObj, btVector3& pointOnBox, btVector3& v3PointOnSphere, const btVector3& sphereCenter, btScalar fRadius )
{ {
btScalar margins; btScalar margins;
btVector3 bounds[2]; btVector3 bounds[2];
btBoxShape* boxShape= (btBoxShape*)m_boxColObj->m_collisionShape; btBoxShape* boxShape= (btBoxShape*)boxObj->m_collisionShape;
bounds[0] = -boxShape->getHalfExtents(); bounds[0] = -boxShape->getHalfExtents();
bounds[1] = boxShape->getHalfExtents(); bounds[1] = boxShape->getHalfExtents();
margins = boxShape->getMargin();//also add sphereShape margin? margins = boxShape->getMargin();//also add sphereShape margin?
const btTransform& m44T = m_boxColObj->m_worldTransform; const btTransform& m44T = boxObj->m_worldTransform;
btVector3 boundsVec[2]; btVector3 boundsVec[2];
btScalar fPenetration; btScalar fPenetration;
@@ -175,7 +178,7 @@ btScalar btSphereBoxCollisionAlgorithm::getSphereDistance( btVector3& pointOnBox
////////////////////////////////////////////////// //////////////////////////////////////////////////
// Deep penetration case // Deep penetration case
fPenetration = getSpherePenetration( pointOnBox, v3PointOnSphere, sphereCenter, fRadius,bounds[0],bounds[1] ); fPenetration = getSpherePenetration( boxObj,pointOnBox, v3PointOnSphere, sphereCenter, fRadius,bounds[0],bounds[1] );
bounds[0] = boundsVec[0]; bounds[0] = boundsVec[0];
bounds[1] = boundsVec[1]; bounds[1] = boundsVec[1];
@@ -186,7 +189,7 @@ btScalar btSphereBoxCollisionAlgorithm::getSphereDistance( btVector3& pointOnBox
return 1.0f; return 1.0f;
} }
btScalar btSphereBoxCollisionAlgorithm::getSpherePenetration( btVector3& pointOnBox, btVector3& v3PointOnSphere, const btVector3& sphereCenter, btScalar fRadius, const btVector3& aabbMin, const btVector3& aabbMax) btScalar btSphereBoxCollisionAlgorithm::getSpherePenetration( btCollisionObject* boxObj,btVector3& pointOnBox, btVector3& v3PointOnSphere, const btVector3& sphereCenter, btScalar fRadius, const btVector3& aabbMin, const btVector3& aabbMax)
{ {
btVector3 bounds[2]; btVector3 bounds[2];
@@ -204,7 +207,7 @@ btScalar btSphereBoxCollisionAlgorithm::getSpherePenetration( btVector3& pointOn
n[4].setValue( 0.0f, 1.0f, 0.0f ); n[4].setValue( 0.0f, 1.0f, 0.0f );
n[5].setValue( 0.0f, 0.0f, 1.0f ); n[5].setValue( 0.0f, 0.0f, 1.0f );
const btTransform& m44T = m_boxColObj->m_worldTransform; const btTransform& m44T = boxObj->m_worldTransform;
// convert point in local space // convert point in local space
prel = m44T.invXform( sphereCenter); prel = m44T.invXform( sphereCenter);

View File

@@ -28,33 +28,32 @@ class btSphereBoxCollisionAlgorithm : public btCollisionAlgorithm
{ {
bool m_ownManifold; bool m_ownManifold;
btPersistentManifold* m_manifoldPtr; btPersistentManifold* m_manifoldPtr;
btCollisionObject* m_boxColObj; bool m_isSwapped;
btCollisionObject* m_sphereColObj;
public: public:
btSphereBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); btSphereBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped);
virtual ~btSphereBoxCollisionAlgorithm(); virtual ~btSphereBoxCollisionAlgorithm();
virtual void processCollision (btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,const struct btDispatcherInfo& dispatchInfo); virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual float calculateTimeOfImpact(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,const struct btDispatcherInfo& dispatchInfo); virtual float calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
btScalar getSphereDistance( btVector3& v3PointOnBox, btVector3& v3PointOnSphere, const btVector3& v3SphereCenter, btScalar fRadius ); btScalar getSphereDistance( btCollisionObject* boxObj,btVector3& v3PointOnBox, btVector3& v3PointOnSphere, const btVector3& v3SphereCenter, btScalar fRadius );
btScalar getSpherePenetration( btVector3& v3PointOnBox, btVector3& v3PointOnSphere, const btVector3& v3SphereCenter, btScalar fRadius, const btVector3& aabbMin, const btVector3& aabbMax); btScalar getSpherePenetration( btCollisionObject* boxObj, btVector3& v3PointOnBox, btVector3& v3PointOnSphere, const btVector3& v3SphereCenter, btScalar fRadius, const btVector3& aabbMin, const btVector3& aabbMax);
struct CreateFunc :public btCollisionAlgorithmCreateFunc struct CreateFunc :public btCollisionAlgorithmCreateFunc
{ {
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
{ {
if (!m_swapped) if (!m_swapped)
{ {
return new btSphereBoxCollisionAlgorithm(0,ci,proxy0,proxy1); return new btSphereBoxCollisionAlgorithm(0,ci,body0,body1,false);
} else } else
{ {
return new btSphereBoxCollisionAlgorithm(0,ci,proxy1,proxy0); return new btSphereBoxCollisionAlgorithm(0,ci,body0,body1,true);
} }
} }
}; };

View File

@@ -18,14 +18,14 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btSphereShape.h" #include "BulletCollision/CollisionShapes/btSphereShape.h"
#include "BulletCollision/CollisionDispatch/btCollisionObject.h" #include "BulletCollision/CollisionDispatch/btCollisionObject.h"
btSphereSphereCollisionAlgorithm::btSphereSphereCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) btSphereSphereCollisionAlgorithm::btSphereSphereCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1)
: btCollisionAlgorithm(ci), : btCollisionAlgorithm(ci),
m_ownManifold(false), m_ownManifold(false),
m_manifoldPtr(mf) m_manifoldPtr(mf)
{ {
if (!m_manifoldPtr && m_dispatcher->needsCollision(*proxy0,*proxy1)) if (!m_manifoldPtr)
{ {
m_manifoldPtr = m_dispatcher->getNewManifold(proxy0->m_clientObject,proxy1->m_clientObject); m_manifoldPtr = m_dispatcher->getNewManifold(col0,col1);
m_ownManifold = true; m_ownManifold = true;
} }
} }
@@ -39,13 +39,11 @@ btSphereSphereCollisionAlgorithm::~btSphereSphereCollisionAlgorithm()
} }
} }
void btSphereSphereCollisionAlgorithm::processCollision (btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,const btDispatcherInfo& dispatchInfo) void btSphereSphereCollisionAlgorithm::processCollision (btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{ {
if (!m_manifoldPtr) if (!m_manifoldPtr)
return; return;
btCollisionObject* col0 = static_cast<btCollisionObject*>(proxy0->m_clientObject);
btCollisionObject* col1 = static_cast<btCollisionObject*>(proxy1->m_clientObject);
btSphereShape* sphere0 = (btSphereShape*)col0->m_collisionShape; btSphereShape* sphere0 = (btSphereShape*)col0->m_collisionShape;
btSphereShape* sphere1 = (btSphereShape*)col1->m_collisionShape; btSphereShape* sphere1 = (btSphereShape*)col1->m_collisionShape;
@@ -68,13 +66,12 @@ void btSphereSphereCollisionAlgorithm::processCollision (btBroadphaseProxy* prox
btVector3 pos1 = col1->m_worldTransform.getOrigin() + radius1* normalOnSurfaceB; btVector3 pos1 = col1->m_worldTransform.getOrigin() + radius1* normalOnSurfaceB;
/// report a contact. internally this will be kept persistent, and contact reduction is done /// report a contact. internally this will be kept persistent, and contact reduction is done
btManifoldResult* resultOut = m_dispatcher->getNewManifoldResult(col0,col1,m_manifoldPtr); resultOut->setPersistentManifold(m_manifoldPtr);
resultOut->addContactPoint(normalOnSurfaceB,pos1,dist); resultOut->addContactPoint(normalOnSurfaceB,pos1,dist);
m_dispatcher->releaseManifoldResult(resultOut);
} }
float btSphereSphereCollisionAlgorithm::calculateTimeOfImpact(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,const btDispatcherInfo& dispatchInfo) float btSphereSphereCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{ {
//not yet //not yet
return 1.f; return 1.f;

View File

@@ -30,22 +30,23 @@ class btSphereSphereCollisionAlgorithm : public btCollisionAlgorithm
btPersistentManifold* m_manifoldPtr; btPersistentManifold* m_manifoldPtr;
public: public:
btSphereSphereCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1);
btSphereSphereCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci) btSphereSphereCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci)
: btCollisionAlgorithm(ci) {} : btCollisionAlgorithm(ci) {}
virtual void processCollision (btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,const btDispatcherInfo& dispatchInfo); virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual float calculateTimeOfImpact(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,const btDispatcherInfo& dispatchInfo); virtual float calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
btSphereSphereCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
virtual ~btSphereSphereCollisionAlgorithm(); virtual ~btSphereSphereCollisionAlgorithm();
struct CreateFunc :public btCollisionAlgorithmCreateFunc struct CreateFunc :public btCollisionAlgorithmCreateFunc
{ {
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
{ {
return new btSphereSphereCollisionAlgorithm(0,ci,proxy0,proxy1); return new btSphereSphereCollisionAlgorithm(0,ci,body0,body1);
} }
}; };

View File

@@ -129,14 +129,14 @@ int btConvexHullShape::getNumVertices() const
int btConvexHullShape::getNumEdges() const int btConvexHullShape::getNumEdges() const
{ {
return m_points.size()*m_points.size(); return m_points.size();
} }
void btConvexHullShape::getEdge(int i,btPoint3& pa,btPoint3& pb) const void btConvexHullShape::getEdge(int i,btPoint3& pa,btPoint3& pb) const
{ {
int index0 = i%m_points.size(); int index0 = i%m_points.size();
int index1 = i/m_points.size(); int index1 = (i+1)%m_points.size();
pa = m_points[index0]*m_localScaling; pa = m_points[index0]*m_localScaling;
pb = m_points[index1]*m_localScaling; pb = m_points[index1]*m_localScaling;
} }

View File

@@ -1,48 +0,0 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "btManifoldContactAddResult.h"
#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
btManifoldContactAddResult::btManifoldContactAddResult(btTransform transA,btTransform transB,btPersistentManifold* manifoldPtr)
:m_manifoldPtr(manifoldPtr)
{
m_transAInv = transA.inverse();
m_transBInv = transB.inverse();
}
void btManifoldContactAddResult::addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,float depth)
{
if (depth > m_manifoldPtr->getContactBreakingTreshold())
return;
btVector3 pointA = pointInWorld + normalOnBInWorld * depth;
btVector3 localA = m_transAInv(pointA );
btVector3 localB = m_transBInv(pointInWorld);
btManifoldPoint newPt(localA,localB,normalOnBInWorld,depth);
int insertIndex = m_manifoldPtr->getCacheEntry(newPt);
if (insertIndex >= 0)
{
m_manifoldPtr->replaceContactPoint(newPt,insertIndex);
} else
{
m_manifoldPtr->AddManifoldPoint(newPt);
}
}

View File

@@ -1,37 +0,0 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef MANIFOLD_CONTACT_ADD_RESULT_H
#define MANIFOLD_CONTACT_ADD_RESULT_H
#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
class btPersistentManifold;
class btManifoldContactAddResult : public btDiscreteCollisionDetectorInterface::Result
{
btPersistentManifold* m_manifoldPtr;
btTransform m_transAInv;
btTransform m_transBInv;
public:
btManifoldContactAddResult(btTransform transA,btTransform transB,btPersistentManifold* manifoldPtr);
virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,float depth);
};
#endif //MANIFOLD_CONTACT_ADD_RESULT_H

View File

@@ -16,7 +16,6 @@ subject to the following restrictions:
#include "btGeneric6DofConstraint.h" #include "btGeneric6DofConstraint.h"
#include "BulletDynamics/Dynamics/btRigidBody.h" #include "BulletDynamics/Dynamics/btRigidBody.h"
#include "BulletDynamics/Dynamics/btMassProps.h"
#include "LinearMath/btTransformUtil.h" #include "LinearMath/btTransformUtil.h"
static const btScalar kSign[] = { 1.0f, -1.0f, 1.0f }; static const btScalar kSign[] = { 1.0f, -1.0f, 1.0f };

View File

@@ -16,7 +16,6 @@ subject to the following restrictions:
#include "btHingeConstraint.h" #include "btHingeConstraint.h"
#include "BulletDynamics/Dynamics/btRigidBody.h" #include "BulletDynamics/Dynamics/btRigidBody.h"
#include "BulletDynamics/Dynamics/btMassProps.h"
#include "LinearMath/btTransformUtil.h" #include "LinearMath/btTransformUtil.h"

View File

@@ -16,7 +16,6 @@ subject to the following restrictions:
#include "btPoint2PointConstraint.h" #include "btPoint2PointConstraint.h"
#include "BulletDynamics/Dynamics/btRigidBody.h" #include "BulletDynamics/Dynamics/btRigidBody.h"
#include "BulletDynamics/Dynamics/btMassProps.h"

View File

@@ -16,7 +16,6 @@ subject to the following restrictions:
#include "btTypedConstraint.h" #include "btTypedConstraint.h"
#include "BulletDynamics/Dynamics/btRigidBody.h" #include "BulletDynamics/Dynamics/btRigidBody.h"
#include "BulletDynamics/Dynamics/btMassProps.h"
static btRigidBody s_fixed(0, btTransform::getIdentity(),0); static btRigidBody s_fixed(0, btTransform::getIdentity(),0);

View File

@@ -35,6 +35,7 @@ subject to the following restrictions:
#include "BulletDynamics/Vehicle/btWheelInfo.h" #include "BulletDynamics/Vehicle/btWheelInfo.h"
#include "LinearMath/btIDebugDraw.h" #include "LinearMath/btIDebugDraw.h"
#include "LinearMath/btQuickprof.h" #include "LinearMath/btQuickprof.h"
#include "LinearMath/btMotionState.h"
@@ -44,6 +45,7 @@ btDiscreteDynamicsWorld::btDiscreteDynamicsWorld()
:btDynamicsWorld(), :btDynamicsWorld(),
m_constraintSolver(new btSequentialImpulseConstraintSolver), m_constraintSolver(new btSequentialImpulseConstraintSolver),
m_debugDrawer(0), m_debugDrawer(0),
m_gravity(0,-10,0),
m_profileTimings(0) m_profileTimings(0)
{ {
m_islandManager = new btSimulationIslandManager(); m_islandManager = new btSimulationIslandManager();
@@ -56,6 +58,7 @@ btDiscreteDynamicsWorld::btDiscreteDynamicsWorld(btDispatcher* dispatcher,btOver
:btDynamicsWorld(dispatcher,pairCache), :btDynamicsWorld(dispatcher,pairCache),
m_constraintSolver(constraintSolver? constraintSolver: new btSequentialImpulseConstraintSolver), m_constraintSolver(constraintSolver? constraintSolver: new btSequentialImpulseConstraintSolver),
m_debugDrawer(0), m_debugDrawer(0),
m_gravity(0,-10,0),
m_profileTimings(0) m_profileTimings(0)
{ {
m_islandManager = new btSimulationIslandManager(); m_islandManager = new btSimulationIslandManager();
@@ -73,7 +76,69 @@ btDiscreteDynamicsWorld::~btDiscreteDynamicsWorld()
delete m_constraintSolver; delete m_constraintSolver;
} }
void btDiscreteDynamicsWorld::stepSimulation(float timeStep) void btDiscreteDynamicsWorld::saveKinematicState(float timeStep)
{
for (unsigned int i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
btRigidBody* body = btRigidBody::upcast(colObj);
if (body)
{
btTransform predictedTrans;
if (body->GetActivationState() != ISLAND_SLEEPING)
{
if (body->isKinematicObject())
{
//to calculate velocities next frame
body->saveKinematicState(timeStep);
}
}
}
}
}
void btDiscreteDynamicsWorld::synchronizeMotionStates()
{
//todo: iterate over awake simulation islands!
for (unsigned int i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
btRigidBody* body = btRigidBody::upcast(colObj);
if (body && body->getMotionState())
{
if (body->GetActivationState() != ISLAND_SLEEPING)
{
body->getMotionState()->setWorldOrientation(body->getCenterOfMassTransform().getRotation());
body->getMotionState()->setWorldPosition(body->getCenterOfMassTransform().getOrigin());
}
}
}
}
void btDiscreteDynamicsWorld::stepSimulation(float timeStep, int numSubsteps)
{
if (!btFuzzyZero(timeStep) && numSubsteps)
{
saveKinematicState(timeStep);
int i;
float subTimeStep = timeStep / float(numSubsteps);
for (i=0;i<numSubsteps;i++)
{
internalSingleStepSimulation(subTimeStep);
}
synchronizeMotionStates();
}
}
void btDiscreteDynamicsWorld::internalSingleStepSimulation(float timeStep)
{ {
startProfiling(timeStep); startProfiling(timeStep);
@@ -112,6 +177,35 @@ void btDiscreteDynamicsWorld::stepSimulation(float timeStep)
} }
void btDiscreteDynamicsWorld::setGravity(const btVector3& gravity)
{
m_gravity = gravity;
for (unsigned int i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
btRigidBody* body = btRigidBody::upcast(colObj);
if (body)
{
body->setGravity(gravity);
}
}
}
void btDiscreteDynamicsWorld::addRigidBody(btRigidBody* body)
{
body->setGravity(m_gravity);
bool isDynamic = !(body->isStaticObject() || body->isKinematicObject());
short collisionFilterGroup = isDynamic?
btBroadphaseProxy::DefaultFilter :
btBroadphaseProxy::StaticFilter;
short collisionFilterMask = isDynamic?
btBroadphaseProxy::AllFilter :
btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter;
addCollisionObject(body,collisionFilterGroup,collisionFilterMask);
}
void btDiscreteDynamicsWorld::updateVehicles(float timeStep) void btDiscreteDynamicsWorld::updateVehicles(float timeStep)
{ {
BEGIN_PROFILE("updateVehicles"); BEGIN_PROFILE("updateVehicles");
@@ -360,7 +454,7 @@ void btDiscreteDynamicsWorld::integrateTransforms(float timeStep)
btRigidBody* body = btRigidBody::upcast(colObj); btRigidBody* body = btRigidBody::upcast(colObj);
if (body) if (body)
{ {
if (body->IsActive() && (!body->IsStatic())) if (body->IsActive() && (!body->isStaticObject()))
{ {
body->predictIntegratedTransform(timeStep, predictedTrans); body->predictIntegratedTransform(timeStep, predictedTrans);
body->proceedToTransform( predictedTrans); body->proceedToTransform( predictedTrans);
@@ -381,12 +475,14 @@ void btDiscreteDynamicsWorld::predictUnconstraintMotion(float timeStep)
btRigidBody* body = btRigidBody::upcast(colObj); btRigidBody* body = btRigidBody::upcast(colObj);
if (body) if (body)
{ {
if (body->IsActive() && (!body->IsStatic())) if (!body->isStaticObject())
{ {
body->applyForces( timeStep); if (body->IsActive())
body->integrateVelocities( timeStep); {
body->predictIntegratedTransform(timeStep,body->m_interpolationWorldTransform); body->applyForces( timeStep);
body->integrateVelocities( timeStep);
body->predictIntegratedTransform(timeStep,body->m_interpolationWorldTransform);
}
} }
} }
} }

View File

@@ -43,6 +43,8 @@ protected:
btIDebugDraw* m_debugDrawer; btIDebugDraw* m_debugDrawer;
btVector3 m_gravity;
bool m_ownsIslandManager; bool m_ownsIslandManager;
bool m_ownsConstraintSolver; bool m_ownsConstraintSolver;
@@ -65,6 +67,13 @@ protected:
void updateVehicles(float timeStep); void updateVehicles(float timeStep);
void startProfiling(float timeStep); void startProfiling(float timeStep);
virtual void internalSingleStepSimulation( float timeStep);
void synchronizeMotionStates();
void saveKinematicState(float timeStep);
public: public:
@@ -76,7 +85,7 @@ public:
virtual ~btDiscreteDynamicsWorld(); virtual ~btDiscreteDynamicsWorld();
virtual void stepSimulation( float timeStep); virtual void stepSimulation( float timeStep, int numSubsteps=1);
virtual void updateAabbs(); virtual void updateAabbs();
@@ -113,6 +122,10 @@ public:
return m_debugDrawer; return m_debugDrawer;
} }
virtual void setGravity(const btVector3& gravity);
virtual void addRigidBody(btRigidBody* body);
}; };
#endif //BT_DISCRETE_DYNAMICS_WORLD_H #endif //BT_DISCRETE_DYNAMICS_WORLD_H

View File

@@ -38,7 +38,7 @@ class btDynamicsWorld : public btCollisionWorld
} }
///stepSimulation proceeds the simulation over timeStep units ///stepSimulation proceeds the simulation over timeStep units
virtual void stepSimulation( float timeStep) = 0; virtual void stepSimulation( float timeStep,int numSubsteps=1) = 0;
virtual void updateAabbs() = 0; virtual void updateAabbs() = 0;
@@ -50,6 +50,12 @@ class btDynamicsWorld : public btCollisionWorld
virtual btIDebugDraw* getDebugDrawer() = 0; virtual btIDebugDraw* getDebugDrawer() = 0;
//once a rigidbody is added to the dynamics world, it will get this gravity assigned
//existing rigidbodies in the world get gravity assigned too, during this method
virtual void setGravity(const btVector3& gravity) = 0;
virtual void addRigidBody(btRigidBody* body) = 0;
}; };
#endif //BT_DYNAMICS_WORLD_H #endif //BT_DYNAMICS_WORLD_H

View File

@@ -1,33 +0,0 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef MASS_PROPS_H
#define MASS_PROPS_H
#include <LinearMath/btVector3.h>
struct btMassProps {
btMassProps(float mass,const btVector3& inertiaLocal):
m_mass(mass),
m_inertiaLocal(inertiaLocal)
{
}
float m_mass;
btVector3 m_inertiaLocal;
};
#endif

View File

@@ -14,10 +14,10 @@ subject to the following restrictions:
*/ */
#include "btRigidBody.h" #include "btRigidBody.h"
#include "btMassProps.h"
#include "BulletCollision/CollisionShapes/btConvexShape.h" #include "BulletCollision/CollisionShapes/btConvexShape.h"
#include "LinearMath/btMinMax.h" #include "LinearMath/btMinMax.h"
#include <LinearMath/btTransformUtil.h> #include <LinearMath/btTransformUtil.h>
#include <LinearMath/btMotionState.h>
float gLinearAirDamping = 1.f; float gLinearAirDamping = 1.f;
//'temporarily' global variables //'temporarily' global variables
@@ -28,6 +28,44 @@ float gLinearSleepingTreshold = 0.8f;
float gAngularSleepingTreshold = 1.0f; float gAngularSleepingTreshold = 1.0f;
static int uniqueId = 0; static int uniqueId = 0;
btRigidBody::btRigidBody(float mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia,btScalar linearDamping,btScalar angularDamping,btScalar friction,btScalar restitution)
:
m_gravity(0.0f, 0.0f, 0.0f),
m_totalForce(0.0f, 0.0f, 0.0f),
m_totalTorque(0.0f, 0.0f, 0.0f),
m_linearVelocity(0.0f, 0.0f, 0.0f),
m_angularVelocity(0.f,0.f,0.f),
m_linearDamping(0.f),
m_angularDamping(0.5f),
m_kinematicTimeStep(0.f),
m_optionalMotionState(motionState),
m_contactSolverType(0),
m_frictionSolverType(0)
{
btQuaternion worldOrn;
btVector3 worldPos;
motionState->getWorldOrientation(worldOrn);
motionState->getWorldPosition(worldPos);
m_worldTransform = btTransform(worldOrn,worldPos);
//moved to btCollisionObject
m_friction = friction;
m_restitution = restitution;
m_collisionShape = collisionShape;
m_debugBodyId = uniqueId++;
//m_internalOwner is to allow upcasting from collision object to rigid body
m_internalOwner = this;
setMassProps(mass, localInertia);
setDamping(linearDamping, angularDamping);
updateInertiaTensor();
}
btRigidBody::btRigidBody( float mass,const btTransform& worldTransform,btCollisionShape* collisionShape,const btVector3& localInertia,btScalar linearDamping,btScalar angularDamping,btScalar friction,btScalar restitution) btRigidBody::btRigidBody( float mass,const btTransform& worldTransform,btCollisionShape* collisionShape,const btVector3& localInertia,btScalar linearDamping,btScalar angularDamping,btScalar friction,btScalar restitution)
: :
m_gravity(0.0f, 0.0f, 0.0f), m_gravity(0.0f, 0.0f, 0.0f),
@@ -38,13 +76,11 @@ btRigidBody::btRigidBody( float mass,const btTransform& worldTransform,btCollisi
m_linearDamping(0.f), m_linearDamping(0.f),
m_angularDamping(0.5f), m_angularDamping(0.5f),
m_kinematicTimeStep(0.f), m_kinematicTimeStep(0.f),
m_optionalMotionState(0),
m_contactSolverType(0), m_contactSolverType(0),
m_frictionSolverType(0) m_frictionSolverType(0)
{ {
if (mass == 0.f)
m_collisionFlags = btCollisionObject::isStatic;
m_worldTransform = worldTransform; m_worldTransform = worldTransform;
//moved to btCollisionObject //moved to btCollisionObject
@@ -64,11 +100,7 @@ btRigidBody::btRigidBody( float mass,const btTransform& worldTransform,btCollisi
} }
void btRigidBody::setLinearVelocity(const btVector3& lin_vel)
{
assert (m_collisionFlags != btCollisionObject::isStatic);
m_linearVelocity = lin_vel;
}
void btRigidBody::predictIntegratedTransform(btScalar timeStep,btTransform& predictedTransform) const void btRigidBody::predictIntegratedTransform(btScalar timeStep,btTransform& predictedTransform) const
@@ -126,10 +158,9 @@ void btRigidBody::setDamping(btScalar lin_damping, btScalar ang_damping)
void btRigidBody::applyForces(btScalar step) void btRigidBody::applyForces(btScalar step)
{ {
if (IsStatic()) if (isStaticObject() || isKinematicObject())
return; return;
applyCentralForce(m_gravity); applyCentralForce(m_gravity);
m_linearVelocity *= GEN_clamped((1.f - step * gLinearAirDamping * m_linearDamping), 0.0f, 1.0f); m_linearVelocity *= GEN_clamped((1.f - step * gLinearAirDamping * m_linearDamping), 0.0f, 1.0f);
@@ -178,15 +209,14 @@ void btRigidBody::setMassProps(btScalar mass, const btVector3& inertia)
{ {
if (mass == 0.f) if (mass == 0.f)
{ {
m_collisionFlags = btCollisionObject::isStatic; m_collisionFlags |= btCollisionObject::CF_STATIC_OBJECT;
m_inverseMass = 0.f; m_inverseMass = 0.f;
} else } else
{ {
m_collisionFlags = 0; m_collisionFlags & (~btCollisionObject::CF_STATIC_OBJECT);
m_inverseMass = 1.0f / mass; m_inverseMass = 1.0f / mass;
} }
m_invInertiaLocal.setValue(inertia[0] != 0.0f ? 1.0f / inertia[0]: 0.0f, m_invInertiaLocal.setValue(inertia[0] != 0.0f ? 1.0f / inertia[0]: 0.0f,
inertia[1] != 0.0f ? 1.0f / inertia[1]: 0.0f, inertia[1] != 0.0f ? 1.0f / inertia[1]: 0.0f,
inertia[2] != 0.0f ? 1.0f / inertia[2]: 0.0f); inertia[2] != 0.0f ? 1.0f / inertia[2]: 0.0f);
@@ -203,7 +233,7 @@ void btRigidBody::updateInertiaTensor()
void btRigidBody::integrateVelocities(btScalar step) void btRigidBody::integrateVelocities(btScalar step)
{ {
if (IsStatic()) if (isStaticObject() || isKinematicObject())
return; return;
m_linearVelocity += m_totalForce * (m_inverseMass * step); m_linearVelocity += m_totalForce * (m_inverseMass * step);

View File

@@ -25,7 +25,8 @@ subject to the following restrictions:
#include "BulletCollision/CollisionDispatch/btCollisionObject.h" #include "BulletCollision/CollisionDispatch/btCollisionObject.h"
class btCollisionShape; class btCollisionShape;
struct btMassProps; class btMotionState;
typedef btScalar dMatrix3[4*3]; typedef btScalar dMatrix3[4*3];
extern float gLinearAirDamping; extern float gLinearAirDamping;
@@ -57,9 +58,13 @@ class btRigidBody : public btCollisionObject
btScalar m_kinematicTimeStep; btScalar m_kinematicTimeStep;
//m_optionalMotionState allows to automatic synchronize the world transform for active objects
btMotionState* m_optionalMotionState;
public: public:
btRigidBody(float mass, const btTransform& worldTransform, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0),btScalar linearDamping=0.f,btScalar angularDamping=0.f,btScalar friction=0.5f,btScalar restitution=0.f); btRigidBody(float mass, const btTransform& worldTransform, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0),btScalar linearDamping=0.f,btScalar angularDamping=0.f,btScalar friction=0.5f,btScalar restitution=0.f);
btRigidBody(float mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0),btScalar linearDamping=0.f,btScalar angularDamping=0.f,btScalar friction=0.5f,btScalar restitution=0.f);
void proceedToTransform(const btTransform& newTrans); void proceedToTransform(const btTransform& newTrans);
@@ -138,9 +143,8 @@ public:
void applyTorqueImpulse(const btVector3& torque) void applyTorqueImpulse(const btVector3& torque)
{ {
if (!IsStatic()) if (!isStaticObject()&& !isKinematicObject())
m_angularVelocity += m_invInertiaTensorWorld * torque; m_angularVelocity += m_invInertiaTensorWorld * torque;
} }
void applyImpulse(const btVector3& impulse, const btVector3& rel_pos) void applyImpulse(const btVector3& impulse, const btVector3& rel_pos)
@@ -176,9 +180,14 @@ public:
} }
void setLinearVelocity(const btVector3& lin_vel); inline void setLinearVelocity(const btVector3& lin_vel)
void setAngularVelocity(const btVector3& ang_vel) { {
if (!IsStatic()) assert (m_collisionFlags != btCollisionObject::CF_STATIC_OBJECT);
m_linearVelocity = lin_vel;
}
inline void setAngularVelocity(const btVector3& ang_vel) {
assert (m_collisionFlags != btCollisionObject::CF_STATIC_OBJECT);
{ {
m_angularVelocity = ang_vel; m_angularVelocity = ang_vel;
} }
@@ -275,6 +284,20 @@ public:
m_broadphaseHandle = broadphaseProxy; m_broadphaseHandle = broadphaseProxy;
} }
//btMotionState allows to automatic synchronize the world transform for active objects
btMotionState* getMotionState()
{
return m_optionalMotionState;
}
const btMotionState* getMotionState() const
{
return m_optionalMotionState;
}
void setMotionState(btMotionState* motionState)
{
m_optionalMotionState = motionState;
}
//for experimental overriding of friction/contact solver func //for experimental overriding of friction/contact solver func
int m_contactSolverType; int m_contactSolverType;
int m_frictionSolverType; int m_frictionSolverType;

View File

@@ -25,7 +25,8 @@ subject to the following restrictions:
btSimpleDynamicsWorld::btSimpleDynamicsWorld() btSimpleDynamicsWorld::btSimpleDynamicsWorld()
:m_constraintSolver(new btSequentialImpulseConstraintSolver), :m_constraintSolver(new btSequentialImpulseConstraintSolver),
m_ownsConstraintSolver(true), m_ownsConstraintSolver(true),
m_debugDrawer(0) m_debugDrawer(0),
m_gravity(0,0,-10)
{ {
} }
@@ -33,7 +34,8 @@ btSimpleDynamicsWorld::btSimpleDynamicsWorld(btDispatcher* dispatcher,btOverlapp
:btDynamicsWorld(dispatcher,pairCache), :btDynamicsWorld(dispatcher,pairCache),
m_constraintSolver(constraintSolver), m_constraintSolver(constraintSolver),
m_ownsConstraintSolver(false), m_ownsConstraintSolver(false),
m_debugDrawer(0) m_debugDrawer(0),
m_gravity(0,0,-10)
{ {
} }
@@ -69,6 +71,26 @@ void btSimpleDynamicsWorld::stepSimulation(float timeStep)
} }
void btSimpleDynamicsWorld::setGravity(const btVector3& gravity)
{
m_gravity = gravity;
for (unsigned int i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
btRigidBody* body = btRigidBody::upcast(colObj);
if (body)
{
body->setGravity(gravity);
}
}
}
void btSimpleDynamicsWorld::addRigidBody(btRigidBody* body)
{
body->setGravity(m_gravity);
addCollisionObject(body);
}
void btSimpleDynamicsWorld::updateAabbs() void btSimpleDynamicsWorld::updateAabbs()
{ {
@@ -79,7 +101,7 @@ void btSimpleDynamicsWorld::updateAabbs()
btRigidBody* body = btRigidBody::upcast(colObj); btRigidBody* body = btRigidBody::upcast(colObj);
if (body) if (body)
{ {
if (body->IsActive() && (!body->IsStatic())) if (body->IsActive() && (!body->isStaticObject()))
{ {
btPoint3 minAabb,maxAabb; btPoint3 minAabb,maxAabb;
colObj->m_collisionShape->getAabb(colObj->m_worldTransform, minAabb,maxAabb); colObj->m_collisionShape->getAabb(colObj->m_worldTransform, minAabb,maxAabb);
@@ -99,7 +121,7 @@ void btSimpleDynamicsWorld::integrateTransforms(float timeStep)
btRigidBody* body = btRigidBody::upcast(colObj); btRigidBody* body = btRigidBody::upcast(colObj);
if (body) if (body)
{ {
if (body->IsActive() && (!body->IsStatic())) if (body->IsActive() && (!body->isStaticObject()))
{ {
body->predictIntegratedTransform(timeStep, predictedTrans); body->predictIntegratedTransform(timeStep, predictedTrans);
body->proceedToTransform( predictedTrans); body->proceedToTransform( predictedTrans);
@@ -118,12 +140,14 @@ void btSimpleDynamicsWorld::predictUnconstraintMotion(float timeStep)
btRigidBody* body = btRigidBody::upcast(colObj); btRigidBody* body = btRigidBody::upcast(colObj);
if (body) if (body)
{ {
if (body->IsActive() && (!body->IsStatic())) if (!body->isStaticObject())
{ {
body->applyForces( timeStep); if (body->IsActive())
body->integrateVelocities( timeStep); {
body->predictIntegratedTransform(timeStep,body->m_interpolationWorldTransform); body->applyForces( timeStep);
body->integrateVelocities( timeStep);
body->predictIntegratedTransform(timeStep,body->m_interpolationWorldTransform);
}
} }
} }
} }

View File

@@ -41,6 +41,7 @@ protected:
void integrateTransforms(float timeStep); void integrateTransforms(float timeStep);
btVector3 m_gravity;
public: public:
@@ -65,6 +66,10 @@ public:
return m_debugDrawer; return m_debugDrawer;
} }
virtual void setGravity(const btVector3& gravity);
virtual void addRigidBody(btRigidBody* body);
virtual void updateAabbs(); virtual void updateAabbs();
}; };

View File

@@ -18,7 +18,6 @@
#include "btWheelInfo.h" #include "btWheelInfo.h"
#include "BulletDynamics/Dynamics/btMassProps.h"
#include "BulletDynamics/ConstraintSolver/btContactConstraint.h" #include "BulletDynamics/ConstraintSolver/btContactConstraint.h"

View File

@@ -14,7 +14,7 @@
#include "BulletDynamics/Dynamics/btRigidBody.h" #include "BulletDynamics/Dynamics/btRigidBody.h"
#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h" #include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
struct btMassProps;
#include "btWheelInfo.h" #include "btWheelInfo.h"
struct btVehicleRaycaster; struct btVehicleRaycaster;

View File

@@ -30,7 +30,7 @@
#ifndef QUICK_PROF_H #ifndef QUICK_PROF_H
#define QUICK_PROF_H #define QUICK_PROF_H
//#define USE_QUICKPROF 1 #define USE_QUICKPROF 1
#ifdef USE_QUICKPROF #ifdef USE_QUICKPROF

View File

@@ -37,7 +37,7 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btTetrahedronShape.h" #include "BulletCollision/CollisionShapes/btTetrahedronShape.h"
#include "BulletCollision/CollisionShapes/btEmptyShape.h" #include "BulletCollision/CollisionShapes/btEmptyShape.h"
#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h" #include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h"
#include "BulletCollision/CollisionShapes/btMultiSphereShape.h"
///Narrowphase Collision Detector ///Narrowphase Collision Detector
#include "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h" #include "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h"

View File

@@ -22,7 +22,6 @@ subject to the following restrictions:
#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h" #include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
#include "BulletDynamics/Dynamics/btSimpleDynamicsWorld.h" #include "BulletDynamics/Dynamics/btSimpleDynamicsWorld.h"
#include "BulletDynamics/Dynamics/btRigidBody.h" #include "BulletDynamics/Dynamics/btRigidBody.h"
#include "BulletDynamics/Dynamics/btMassProps.h"
#include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h" #include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h"
#include "BulletDynamics/ConstraintSolver/btHingeConstraint.h" #include "BulletDynamics/ConstraintSolver/btHingeConstraint.h"