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
m_dynamicsWorld = new btDiscreteDynamicsWorld();
m_dynamicsWorld->setGravity(-m_cameraUp);
#ifdef QUAKE_BSP_IMPORTING

View File

@@ -14,7 +14,8 @@ subject to the following restrictions:
*/
//#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
#include "btBulletDynamicsCommon.h"
@@ -121,6 +122,14 @@ void CcdPhysicsDemo::clientMoveAndDisplay()
{
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)
m_dynamicsWorld->stepSimulation(deltaTime);
@@ -243,7 +252,7 @@ void CcdPhysicsDemo::initPhysics()
btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver);
//setGravity(btVector3(0,0,1));
m_dynamicsWorld->setGravity(btVector3(0,-10,0));
m_dynamicsWorld->setDebugDrawer(&debugDrawer);
@@ -328,6 +337,14 @@ void CcdPhysicsDemo::initPhysics()
mass = 0.f;
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

View File

@@ -100,7 +100,7 @@ class MyColladaConverter : public ColladaConverter
virtual void setGravity(const btVector3& grav)
{
m_demoApp->setGravity(grav);
m_demoApp->getDynamicsWorld()->setGravity(grav);
}
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 restitution1 = colObj1->getRestitution();
if (colObj0->m_collisionFlags & btCollisionObject::customMaterialCallback)
if (colObj0->m_collisionFlags & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK)
{
friction0 = 1.0;//partId0,index0
restitution0 = 0.f;
}
if (colObj1->m_collisionFlags & btCollisionObject::customMaterialCallback)
if (colObj1->m_collisionFlags & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK)
{
if (index1&1)
{
@@ -161,10 +161,10 @@ void ConcaveDemo::initPhysics()
btRigidBody* staticBody = localCreateRigidBody(mass, startTransform,trimeshShape);
staticBody->m_collisionFlags |=btCollisionObject::isStatic;
staticBody->m_collisionFlags |=btCollisionObject::CF_STATIC_OBJECT;
//enable custom material callback
staticBody->m_collisionFlags |= btCollisionObject::customMaterialCallback;
staticBody->m_collisionFlags |= btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK;
{
for (int i=0;i<10;i++)

View File

@@ -24,8 +24,8 @@ subject to the following restrictions:
#include "GL_ShapeDrawer.h"
#include "LinearMath/btQuickprof.h"
#include "BMF_Api.h"
#include "BulletDynamics/Dynamics/btMassProps.h"
extern bool gDisableDeactivation;
int numObjects = 0;
const int maxNumObjects = 16384;
btTransform startTransforms[maxNumObjects];
@@ -37,7 +37,6 @@ DemoApplication::DemoApplication()
:
m_dynamicsWorld(0),
m_pickConstraint(0),
m_gravity(0,-10,0),
m_cameraDistance(15.0),
m_debugMode(0),
m_ele(0.f),
@@ -58,6 +57,7 @@ m_gravity(0,-10,0),
}
DemoApplication::~DemoApplication()
{
@@ -290,10 +290,18 @@ void DemoApplication::keyboardCallback(unsigned char key, int x, int y)
m_debugMode = m_debugMode & (~btIDebugDraw::DBG_NoDeactivation);
else
m_debugMode |= btIDebugDraw::DBG_NoDeactivation;
if (m_debugMode | btIDebugDraw::DBG_NoDeactivation)
{
gDisableDeactivation = true;
} else
{
gDisableDeactivation = false;
}
break;
case 'o' :
{
m_stepping = !m_stepping;
@@ -346,6 +354,29 @@ void DemoApplication::specialKeyboard(int key, int x, int y)
{
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_RIGHT : stepRight(); 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);
if (body)
{
if (!body->IsStatic())
//other exclusions?
if (!(body->isStaticObject() || body->isKinematicObject()))
{
pickedBody = body;
pickedBody->SetActivationState(DISABLE_DEACTIVATION);
@@ -616,26 +648,7 @@ btRigidBody* DemoApplication::localCreateRigidBody(float mass, const btTransform
btRigidBody* body = new btRigidBody(mass,startTransform,shape,localInertia);
//filtering allows to excluded collision pairs, early in the collision pipeline (broadphase)
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);
m_dynamicsWorld->addRigidBody(body);
return body;
}

View File

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

View File

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

View File

@@ -18,6 +18,9 @@ subject to the following restrictions:
struct btBroadphaseProxy;
class btDispatcher;
class btManifoldResult;
struct btCollisionObject;
struct btDispatcherInfo;
struct btCollisionAlgorithmConstructionInfo
{
@@ -57,9 +60,9 @@ public:
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;
class btRigidBody;
struct btCollisionObject;
class btManifoldResult;
class btOverlappingPairCache;
enum btCollisionDispatcherId
@@ -66,7 +65,7 @@ class btDispatcher
public:
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]
@@ -79,13 +78,9 @@ public:
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 btManifoldResult* getNewManifoldResult(btCollisionObject* obj0,btCollisionObject* obj1,btPersistentManifold* manifold) =0;
virtual void releaseManifoldResult(btManifoldResult*)=0;
virtual bool needsResponse(btCollisionObject* body0,btCollisionObject* body1)=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
assert(proxy0 != proxy1);
if (!needsCollision(proxy0,proxy1))
if (!needsBroadphaseCollision(proxy0,proxy1))
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
btBroadphasePair* btOverlappingPairCache::findPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
{
if (!needsCollision(proxy0,proxy1))
if (!needsBroadphaseCollision(proxy0,proxy1))
return 0;
btBroadphasePair tmpPair(*proxy0,*proxy1);

View File

@@ -64,7 +64,7 @@ class btOverlappingPairCache : public btBroadphaseInterface
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;
collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);

View File

@@ -134,25 +134,7 @@ void btSimpleBroadphase::destroyProxy(btBroadphaseProxy* proxyOrg)
assert (index < m_maxProxies);
m_freeProxies[--m_firstFreeProxy] = index;
//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);
}
}
*/
removeOverlappingPairsContainingProxy(proxyOrg);
for (i=0;i<m_numProxies;i++)
{

View File

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

View File

@@ -29,13 +29,13 @@ subject to the following restrictions:
int gNumManifold = 0;
#include <stdio.h>
btCollisionDispatcher::btCollisionDispatcher ():
m_useIslands(true),
m_defaultManifoldResult(0,0,0),
m_count(0)
{
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
#ifdef USE_DISPATCH_REGISTRY_ARRAY
btCollisionObject* body0 = (btCollisionObject*)proxy0.m_clientObject;
btCollisionObject* body1 = (btCollisionObject*)proxy1.m_clientObject;
btCollisionAlgorithmConstructionInfo ci;
ci.m_dispatcher = this;
btCollisionAlgorithm* algo = m_doubleDispatch[body0->m_collisionShape->getShapeType()][body1->m_collisionShape->getShapeType()]
->CreateCollisionAlgorithm(ci,&proxy0,&proxy1);
->CreateCollisionAlgorithm(ci,body0,body1);
#else
btCollisionAlgorithm* algo = internalFindAlgorithm(proxy0,proxy1);
btCollisionAlgorithm* algo = internalFindAlgorithm(body0,body1);
#endif //USE_DISPATCH_REGISTRY_ARRAY
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++;
btCollisionObject* body0 = (btCollisionObject*)proxy0.m_clientObject;
btCollisionObject* body1 = (btCollisionObject*)proxy1.m_clientObject;
btCollisionAlgorithmConstructionInfo ci;
ci.m_dispatcher = this;
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())
{
return new btConvexConcaveCollisionAlgorithm(ci,&proxy0,&proxy1);
return new btConvexConcaveCollisionAlgorithm(ci,body0,body1,false);
}
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())
{
return new btCompoundCollisionAlgorithm(ci,&proxy0,&proxy1);
return new btCompoundCollisionAlgorithm(ci,body0,body1,false);
} else
{
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
bool hasResponse =
(!(colObj0.m_collisionFlags & btCollisionObject::noContactResponse)) &&
(!(colObj1.m_collisionFlags & btCollisionObject::noContactResponse));
(body0->hasContactResponse() && body1->hasContactResponse());
hasResponse = hasResponse &&
(colObj0.IsActive() || colObj1.IsActive());
(body0->IsActive() || body1->IsActive());
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(body1);
bool needsCollision = true;
if ((body0->m_collisionFlags & btCollisionObject::isStatic) &&
(body1->m_collisionFlags & btCollisionObject::isStatic))
needsCollision = false;
//broadphase filtering already deals with this
if ((body0->isStaticObject() || body0->isKinematicObject()) &&
(body1->isStaticObject() || body1->isKinematicObject()))
{
printf("warning btCollisionDispatcher::needsCollision: static-static collision!\n");
}
if ((!body0->IsActive()) && (!body1->IsActive()))
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
{
@@ -281,48 +260,35 @@ public:
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
if (!pair.m_algorithms[m_dispatcherId])
{
pair.m_algorithms[m_dispatcherId] = m_dispatcher->findAlgorithm(
*pair.m_pProxy0,
*pair.m_pProxy1);
}
pair.m_algorithms[m_dispatcherId] = m_dispatcher->findAlgorithm(
body0,
body1);
}
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
if (pair.m_algorithms[m_dispatcherId])
{
//non-persistent algorithm dispatcher
btCollisionAlgorithm* algo = m_dispatcher->findAlgorithm(
*pair.m_pProxy0,
*pair.m_pProxy1);
if (algo)
btManifoldResult* resultOut = m_dispatcher->internalGetNewManifoldResult(body0,body1);
if (m_dispatchInfo.m_dispatchFunc == btDispatcherInfo::DISPATCH_DISCRETE)
{
if (m_dispatchInfo.m_dispatchFunc == btDispatcherInfo::DISPATCH_DISCRETE)
{
algo->processCollision(pair.m_pProxy0,pair.m_pProxy1,m_dispatchInfo);
} else
{
float toi = algo->calculateTimeOfImpact(pair.m_pProxy0,pair.m_pProxy1,m_dispatchInfo);
if (m_dispatchInfo.m_timeOfImpact > toi)
m_dispatchInfo.m_timeOfImpact = toi;
}
pair.m_algorithms[m_dispatcherId]->processCollision(body0,body1,m_dispatchInfo,resultOut);
} else
{
float toi = pair.m_algorithms[m_dispatcherId]->calculateTimeOfImpact(body0,body1,m_dispatchInfo,resultOut);
if (m_dispatchInfo.m_timeOfImpact > toi)
m_dispatchInfo.m_timeOfImpact = toi;
}
m_dispatcher->internalReleaseManifoldResult(resultOut);
}
return false;

View File

@@ -56,8 +56,24 @@ class btCollisionDispatcher : public btDispatcher
btCollisionAlgorithmCreateFunc* m_swappedCompoundCreateFunc;
btCollisionAlgorithmCreateFunc* m_emptyCreateFunc;
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
void registerCollisionCreateFunc(int proxyType0,int proxyType1, btCollisionAlgorithmCreateFunc* createFunc);
@@ -91,22 +107,16 @@ public:
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);
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;}

View File

@@ -42,15 +42,11 @@ void btCollisionObject::ForceActivationState(int newState)
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;
}
}
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
{
isStatic = 1,
noContactResponse = 2,
customMaterialCallback = 4,//this allows per-triangle material (friction/restitution)
CF_STATIC_OBJECT= 1,
CF_KINEMATIC_OJBECT= 2,
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
float m_ccdSquareMotionTreshold;
bool mergesSimulationIslands() const;
inline bool IsStatic() const {
return m_collisionFlags & isStatic;
inline bool mergesSimulationIslands() const
{
//static objects, kinematic and object without contact response don't merge islands
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)
{
btCollisionWorld::LocalRayResult localRayResult
(
collisionObject,

View File

@@ -18,31 +18,24 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btCompoundShape.h"
btCompoundCollisionAlgorithm::btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
:m_dispatcher(ci.m_dispatcher),
m_compoundProxy(*proxy0),
m_otherProxy(*proxy1)
btCompoundCollisionAlgorithm::btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped)
:m_isSwapped(isSwapped)
{
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());
btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->m_collisionShape);
int numChildren = compoundShape->getNumChildShapes();
m_childProxies.resize( numChildren );
int i;
for (i=0;i<numChildren;i++)
{
m_childProxies[i] = btBroadphaseProxy(*proxy0);
}
m_childCollisionAlgorithms.resize(numChildren);
for (i=0;i<numChildren;i++)
{
btCollisionShape* childShape = compoundShape->getChildShape(i);
btCollisionObject* colObj = static_cast<btCollisionObject*>(m_childProxies[i].m_clientObject);
btCollisionShape* orgShape = colObj->m_collisionShape;
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;
}
}
@@ -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);
assert (colObj->m_collisionShape->isCompound());
btCollisionObject* colObj = m_isSwapped? body1 : body0;
btCollisionObject* otherObj = m_isSwapped? body0 : body1;
assert (colObj->m_collisionShape->isCompound());
btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->m_collisionShape);
//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
//and vise versa.
int numChildren = m_childCollisionAlgorithms.size();
int i;
for (i=0;i<numChildren;i++)
{
//temporarily exchange parent btCollisionShape with childShape, and recurse
btCollisionShape* childShape = compoundShape->getChildShape(i);
btCollisionObject* colObj = static_cast<btCollisionObject*>(m_childProxies[i].m_clientObject);
//backup
btTransform orgTrans = colObj->m_worldTransform;
@@ -88,18 +80,21 @@ void btCompoundCollisionAlgorithm::processCollision (btBroadphaseProxy* ,btBroad
btTransform childTrans = compoundShape->getChildTransform(i);
btTransform newChildWorldTrans = orgTrans*childTrans ;
colObj->m_worldTransform = newChildWorldTrans;
//the contactpoint is still projected back using the original inverted worldtrans
colObj->m_collisionShape = childShape;
m_childCollisionAlgorithms[i]->processCollision(&m_childProxies[i],&m_otherProxy,dispatchInfo);
m_childCollisionAlgorithms[i]->processCollision(colObj,otherObj,dispatchInfo,resultOut);
//revert back
colObj->m_collisionShape =orgShape;
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());
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
btCollisionShape* childShape = compoundShape->getChildShape(i);
btCollisionObject* colObj = static_cast<btCollisionObject*>(m_childProxies[i].m_clientObject);
//backup
btTransform orgTrans = colObj->m_worldTransform;
@@ -130,7 +124,7 @@ float btCompoundCollisionAlgorithm::calculateTimeOfImpact(btBroadphaseProxy* pro
colObj->m_worldTransform = newChildWorldTrans;
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)
{
hitFraction = frac;

View File

@@ -30,40 +30,32 @@ class btDispatcher;
/// Place holder, not fully implemented yet
class btCompoundCollisionAlgorithm : public btCollisionAlgorithm
{
btDispatcher* m_dispatcher;
btBroadphaseProxy m_compoundProxy;
btBroadphaseProxy m_otherProxy;
std::vector<btBroadphaseProxy> m_childProxies;
std::vector<btCollisionAlgorithm*> m_childCollisionAlgorithms;
btBroadphaseProxy m_compound;
btBroadphaseProxy m_other;
bool m_isSwapped;
public:
btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped);
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
{
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
{
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 "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
btConvexConcaveCollisionAlgorithm::btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
: btCollisionAlgorithm(ci),m_convex(*proxy0),m_concave(*proxy1),
m_btConvexTriangleCallback(ci.m_dispatcher,proxy0,proxy1)
btConvexConcaveCollisionAlgorithm::btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1,bool isSwapped)
: btCollisionAlgorithm(ci),
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):
m_convexProxy(proxy0),m_triangleProxy(*proxy1),m_dispatcher(dispatcher),
btConvexTriangleCallback::btConvexTriangleCallback(btDispatcher* dispatcher,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped):
m_dispatcher(dispatcher),
m_dispatchInfoPtr(0)
{
m_convexBody = isSwapped? body1:body0;
m_triBody = isSwapped? body0:body1;
//
// 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();
}
@@ -80,7 +82,7 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i
btCollisionAlgorithmConstructionInfo ci;
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]);
tm.setMargin(m_collisionMarginTriangle);
@@ -114,9 +116,9 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i
ob->m_collisionShape = &tm;
///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.processCollision(m_convexProxy,&m_triangleProxy,*m_dispatchInfoPtr);
cvxcvxalgo.processCollision(m_convexBody,m_triBody,*m_dispatchInfoPtr,m_resultOut);
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_collisionMarginTriangle = collisionMarginTriangle;
m_resultOut = resultOut;
//recalc aabbs
btCollisionObject* convexBody = (btCollisionObject* )m_convexProxy->m_clientObject;
btCollisionObject* triBody = (btCollisionObject* )m_triangleProxy.m_clientObject;
btTransform convexInTriangleSpace;
convexInTriangleSpace = triBody->m_worldTransform.inverse() * convexBody->m_worldTransform;
btCollisionShape* convexShape = static_cast<btCollisionShape*>(convexBody->m_collisionShape);
convexInTriangleSpace = m_triBody->m_worldTransform.inverse() * m_convexBody->m_worldTransform;
btCollisionShape* convexShape = static_cast<btCollisionShape*>(m_convexBody->m_collisionShape);
//CollisionShape* triangleShape = static_cast<btCollisionShape*>(triBody->m_collisionShape);
convexShape->getAabb(convexInTriangleSpace,m_aabbMin,m_aabbMax);
float extraMargin = collisionMarginTriangle;//CONVEX_DISTANCE_MARGIN;//+0.1f;
float extraMargin = collisionMarginTriangle;
btVector3 extra(extraMargin,extraMargin,extraMargin);
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 (!m_dispatcher->needsCollision(m_convex,m_concave))
return;
btCollisionObject* triOb = static_cast<btCollisionObject*>(m_concave.m_clientObject);
btCollisionObject* triOb = triBody;
ConcaveShape* concaveShape = static_cast<ConcaveShape*>( triOb->m_collisionShape);
if (convexBody->m_collisionShape->isConvex())
{
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.
//m_dispatcher->clearManifold(m_btConvexTriangleCallback.m_manifoldPtr);
m_btConvexTriangleCallback.m_manifoldPtr->setBodies(m_convex.m_clientObject,m_concave.m_clientObject);
m_btConvexTriangleCallback.m_manifoldPtr->setBodies(convexBody,triBody);
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)
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
//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();
//todo: only do if the motion exceeds the 'radius'
btTransform worldToLocalTrimesh = triBody->m_worldTransform.inverse();
btTransform convexFromLocal = worldToLocalTrimesh * convexbody->m_worldTransform;
btTransform convexToLocal = worldToLocalTrimesh * convexbody->m_interpolationWorldTransform;
btTransform triInv = triBody->m_worldTransform.inverse();
btTransform convexFromLocal = triInv * convexbody->m_worldTransform;
btTransform convexToLocal = triInv * convexbody->m_interpolationWorldTransform;
struct LocalTriangleSphereCastCallback : public btTriangleCallback
{
@@ -285,7 +280,7 @@ float btConvexConcaveCollisionAlgorithm::calculateTimeOfImpact(btBroadphaseProxy
raycastCallback.m_hitFraction = convexbody->m_hitFraction;
btCollisionObject* concavebody = (btCollisionObject* )m_concave.m_clientObject;
btCollisionObject* concavebody = triBody;
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.
class btConvexTriangleCallback : public btTriangleCallback
{
btBroadphaseProxy* m_convexProxy;
btBroadphaseProxy m_triangleProxy;
btCollisionObject* m_convexBody;
btCollisionObject* m_triBody;
btVector3 m_aabbMin;
btVector3 m_aabbMax ;
btManifoldResult* m_resultOut;
btDispatcher* m_dispatcher;
const btDispatcherInfo* m_dispatchInfoPtr;
float m_collisionMarginTriangle;
@@ -43,9 +45,9 @@ int m_triangleCount;
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();
@@ -71,38 +73,36 @@ int m_triangleCount;
class btConvexConcaveCollisionAlgorithm : public btCollisionAlgorithm
{
btBroadphaseProxy m_convex;
btBroadphaseProxy m_concave;
bool m_isSwapped;
btConvexTriangleCallback m_btConvexTriangleCallback;
public:
btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped);
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();
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
{
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),
m_gjkPairDetector(0,0,&m_simplexSolver,0),
m_useEpa(!gUseEpa),
m_box0(*proxy0),
m_box1(*proxy1),
m_ownManifold (false),
m_manifoldPtr(mf),
m_lowLevelOfDetail(false)
{
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()
{
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;
@@ -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
//
void btConvexConvexAlgorithm ::processCollision (btBroadphaseProxy* ,btBroadphaseProxy* ,const btDispatcherInfo& dispatchInfo)
void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
if (!m_manifoldPtr)
return;
{
//swapped?
m_manifoldPtr = m_dispatcher->getNewManifold(body0,body1);
m_ownManifold = true;
}
checkPenetrationDepthSolver();
// printf("btConvexConvexAlgorithm::processCollision\n");
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);
btConvexShape* min0 = static_cast<btConvexShape*>(body0->m_collisionShape);
btConvexShape* min1 = static_cast<btConvexShape*>(body1->m_collisionShape);
btGjkPairDetector::ClosestPointInput input;
//TODO: if (dispatchInfo.m_useContinuous)
m_gjkPairDetector.setMinkowskiA(min0);
m_gjkPairDetector.setMinkowskiB(min1);
@@ -317,18 +170,18 @@ void btConvexConvexAlgorithm ::processCollision (btBroadphaseProxy* ,btBroadphas
// input.m_maximumDistanceSquared = 1e30f;
input.m_transformA = col0->m_worldTransform;
input.m_transformB = col1->m_worldTransform;
input.m_transformA = body0->m_worldTransform;
input.m_transformB = body1->m_worldTransform;
resultOut->setPersistentManifold(m_manifoldPtr);
m_gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
m_dispatcher->releaseManifoldResult(resultOut);
}
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
@@ -336,8 +189,6 @@ float btConvexConvexAlgorithm::calculateTimeOfImpact(btBroadphaseProxy* proxy0,b
///col0->m_worldTransform,
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();
@@ -358,11 +209,6 @@ float btConvexConvexAlgorithm::calculateTimeOfImpact(btBroadphaseProxy* proxy0,b
//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)
bool needsCollision = m_dispatcher->needsCollision(m_box0,m_box1);
if (!needsCollision)
return 1.f;
/// Convex0 against sphere for Convex1
{

View File

@@ -33,8 +33,6 @@ class btConvexConvexAlgorithm : public btCollisionAlgorithm
btGjkPairDetector m_gjkPairDetector;
bool m_useEpa;
public:
btBroadphaseProxy m_box0;
btBroadphaseProxy m_box1;
bool m_ownManifold;
btPersistentManifold* m_manifoldPtr;
@@ -46,13 +44,13 @@ 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 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);
@@ -71,9 +69,9 @@ public:
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;
}

View File

@@ -29,13 +29,13 @@ public:
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
{
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
{
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)
:m_manifoldPtr(manifoldPtr),
btManifoldResult::btManifoldResult(btCollisionObject* body0,btCollisionObject* body1)
:m_manifoldPtr(0),
m_body0(body0),
m_body1(body1)
{
}
{
m_rootTransA = body0->m_worldTransform;
m_rootTransB = body1->m_worldTransform;
}
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())
return;
bool isSwapped = m_manifoldPtr->getBody0() != m_body0;
btTransform transAInv = m_body0->m_worldTransform.inverse();
btTransform transBInv= m_body1->m_worldTransform.inverse();
btTransform transAInv = isSwapped? m_rootTransB.inverse() : m_rootTransA.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 localA = transAInv(pointA );
btVector3 localB = transBInv(pointInWorld);
@@ -88,8 +92,8 @@ void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const b
//User can override friction and/or restitution
if (gContactAddedCallback &&
//and if either of the two bodies requires custom material
((m_body0->m_collisionFlags & btCollisionObject::customMaterialCallback) ||
(m_body1->m_collisionFlags & btCollisionObject::customMaterialCallback)))
((m_body0->m_collisionFlags & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) ||
(m_body1->m_collisionFlags & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK)))
{
//experimental feature info, for per-triangle material etc.
(*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;
class btPersistentManifold;
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);
extern ContactAddedCallback gContactAddedCallback;
@@ -31,6 +32,11 @@ extern ContactAddedCallback gContactAddedCallback;
class btManifoldResult : public btDiscreteCollisionDetectorInterface::Result
{
btPersistentManifold* m_manifoldPtr;
//we need this for compounds
btTransform m_rootTransA;
btTransform m_rootTransB;
btCollisionObject* m_body0;
btCollisionObject* m_body1;
int m_partId0;
@@ -39,10 +45,19 @@ class btManifoldResult : public btDiscreteCollisionDetectorInterface::Result
int m_index1;
public:
btManifoldResult(btCollisionObject* body0,btCollisionObject* body1,btPersistentManifold* manifoldPtr);
btManifoldResult()
{
}
btManifoldResult(btCollisionObject* body0,btCollisionObject* body1);
virtual ~btManifoldResult() {};
void setPersistentManifold(btPersistentManifold* manifoldPtr)
{
m_manifoldPtr = manifoldPtr;
}
virtual void setShapeIdentifiers(int partId0,int index0, int partId1,int index1)
{
m_partId0=partId0;

View File

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

View File

@@ -20,17 +20,16 @@ subject to the following restrictions:
#include "BulletCollision/CollisionDispatch/btCollisionObject.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),
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;
}
}
@@ -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)
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 pOnBox,pOnSphere;
btVector3 sphereCenter = m_sphereColObj->m_worldTransform.getOrigin();
btVector3 sphereCenter = sphereObj->m_worldTransform.getOrigin();
btScalar radius = sphere0->getRadius();
float dist = getSphereDistance(pOnBox,pOnSphere,sphereCenter,radius);
float dist = getSphereDistance(boxObj,pOnBox,pOnSphere,sphereCenter,radius);
if (dist < SIMD_EPSILON)
{
btVector3 normalOnSurfaceB = (pOnBox- pOnSphere).normalize();
/// 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);
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
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;
btVector3 bounds[2];
btBoxShape* boxShape= (btBoxShape*)m_boxColObj->m_collisionShape;
btBoxShape* boxShape= (btBoxShape*)boxObj->m_collisionShape;
bounds[0] = -boxShape->getHalfExtents();
bounds[1] = boxShape->getHalfExtents();
margins = boxShape->getMargin();//also add sphereShape margin?
const btTransform& m44T = m_boxColObj->m_worldTransform;
const btTransform& m44T = boxObj->m_worldTransform;
btVector3 boundsVec[2];
btScalar fPenetration;
@@ -175,7 +178,7 @@ btScalar btSphereBoxCollisionAlgorithm::getSphereDistance( btVector3& pointOnBox
//////////////////////////////////////////////////
// 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[1] = boundsVec[1];
@@ -186,7 +189,7 @@ btScalar btSphereBoxCollisionAlgorithm::getSphereDistance( btVector3& pointOnBox
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];
@@ -204,7 +207,7 @@ btScalar btSphereBoxCollisionAlgorithm::getSpherePenetration( btVector3& pointOn
n[4].setValue( 0.0f, 1.0f, 0.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
prel = m44T.invXform( sphereCenter);

View File

@@ -28,33 +28,32 @@ class btSphereBoxCollisionAlgorithm : public btCollisionAlgorithm
{
bool m_ownManifold;
btPersistentManifold* m_manifoldPtr;
btCollisionObject* m_boxColObj;
btCollisionObject* m_sphereColObj;
bool m_isSwapped;
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 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
{
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
{
if (!m_swapped)
{
return new btSphereBoxCollisionAlgorithm(0,ci,proxy0,proxy1);
return new btSphereBoxCollisionAlgorithm(0,ci,body0,body1,false);
} 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/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),
m_ownManifold(false),
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;
}
}
@@ -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)
return;
btCollisionObject* col0 = static_cast<btCollisionObject*>(proxy0->m_clientObject);
btCollisionObject* col1 = static_cast<btCollisionObject*>(proxy1->m_clientObject);
btSphereShape* sphere0 = (btSphereShape*)col0->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;
/// 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);
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
return 1.f;

View File

@@ -30,22 +30,23 @@ class btSphereSphereCollisionAlgorithm : public btCollisionAlgorithm
btPersistentManifold* m_manifoldPtr;
public:
btSphereSphereCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1);
btSphereSphereCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& 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();
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
{
return m_points.size()*m_points.size();
return m_points.size();
}
void btConvexHullShape::getEdge(int i,btPoint3& pa,btPoint3& pb) const
{
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;
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 "BulletDynamics/Dynamics/btRigidBody.h"
#include "BulletDynamics/Dynamics/btMassProps.h"
#include "LinearMath/btTransformUtil.h"
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 "BulletDynamics/Dynamics/btRigidBody.h"
#include "BulletDynamics/Dynamics/btMassProps.h"
#include "LinearMath/btTransformUtil.h"

View File

@@ -16,7 +16,6 @@ subject to the following restrictions:
#include "btPoint2PointConstraint.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 "BulletDynamics/Dynamics/btRigidBody.h"
#include "BulletDynamics/Dynamics/btMassProps.h"
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 "LinearMath/btIDebugDraw.h"
#include "LinearMath/btQuickprof.h"
#include "LinearMath/btMotionState.h"
@@ -44,6 +45,7 @@ btDiscreteDynamicsWorld::btDiscreteDynamicsWorld()
:btDynamicsWorld(),
m_constraintSolver(new btSequentialImpulseConstraintSolver),
m_debugDrawer(0),
m_gravity(0,-10,0),
m_profileTimings(0)
{
m_islandManager = new btSimulationIslandManager();
@@ -56,6 +58,7 @@ btDiscreteDynamicsWorld::btDiscreteDynamicsWorld(btDispatcher* dispatcher,btOver
:btDynamicsWorld(dispatcher,pairCache),
m_constraintSolver(constraintSolver? constraintSolver: new btSequentialImpulseConstraintSolver),
m_debugDrawer(0),
m_gravity(0,-10,0),
m_profileTimings(0)
{
m_islandManager = new btSimulationIslandManager();
@@ -73,7 +76,69 @@ btDiscreteDynamicsWorld::~btDiscreteDynamicsWorld()
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);
@@ -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)
{
BEGIN_PROFILE("updateVehicles");
@@ -360,7 +454,7 @@ void btDiscreteDynamicsWorld::integrateTransforms(float timeStep)
btRigidBody* body = btRigidBody::upcast(colObj);
if (body)
{
if (body->IsActive() && (!body->IsStatic()))
if (body->IsActive() && (!body->isStaticObject()))
{
body->predictIntegratedTransform(timeStep, predictedTrans);
body->proceedToTransform( predictedTrans);
@@ -381,12 +475,14 @@ void btDiscreteDynamicsWorld::predictUnconstraintMotion(float timeStep)
btRigidBody* body = btRigidBody::upcast(colObj);
if (body)
{
if (body->IsActive() && (!body->IsStatic()))
if (!body->isStaticObject())
{
body->applyForces( timeStep);
body->integrateVelocities( timeStep);
body->predictIntegratedTransform(timeStep,body->m_interpolationWorldTransform);
if (body->IsActive())
{
body->applyForces( timeStep);
body->integrateVelocities( timeStep);
body->predictIntegratedTransform(timeStep,body->m_interpolationWorldTransform);
}
}
}
}

View File

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

View File

@@ -38,7 +38,7 @@ class btDynamicsWorld : public btCollisionWorld
}
///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;
@@ -50,6 +50,12 @@ class btDynamicsWorld : public btCollisionWorld
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

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 "btMassProps.h"
#include "BulletCollision/CollisionShapes/btConvexShape.h"
#include "LinearMath/btMinMax.h"
#include <LinearMath/btTransformUtil.h>
#include <LinearMath/btMotionState.h>
float gLinearAirDamping = 1.f;
//'temporarily' global variables
@@ -28,6 +28,44 @@ float gLinearSleepingTreshold = 0.8f;
float gAngularSleepingTreshold = 1.0f;
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)
:
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_angularDamping(0.5f),
m_kinematicTimeStep(0.f),
m_optionalMotionState(0),
m_contactSolverType(0),
m_frictionSolverType(0)
{
if (mass == 0.f)
m_collisionFlags = btCollisionObject::isStatic;
m_worldTransform = worldTransform;
//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
@@ -126,10 +158,9 @@ void btRigidBody::setDamping(btScalar lin_damping, btScalar ang_damping)
void btRigidBody::applyForces(btScalar step)
{
if (IsStatic())
if (isStaticObject() || isKinematicObject())
return;
applyCentralForce(m_gravity);
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)
{
m_collisionFlags = btCollisionObject::isStatic;
m_collisionFlags |= btCollisionObject::CF_STATIC_OBJECT;
m_inverseMass = 0.f;
} else
{
m_collisionFlags = 0;
m_collisionFlags & (~btCollisionObject::CF_STATIC_OBJECT);
m_inverseMass = 1.0f / mass;
}
m_invInertiaLocal.setValue(inertia[0] != 0.0f ? 1.0f / inertia[0]: 0.0f,
inertia[1] != 0.0f ? 1.0f / inertia[1]: 0.0f,
inertia[2] != 0.0f ? 1.0f / inertia[2]: 0.0f);
@@ -203,7 +233,7 @@ void btRigidBody::updateInertiaTensor()
void btRigidBody::integrateVelocities(btScalar step)
{
if (IsStatic())
if (isStaticObject() || isKinematicObject())
return;
m_linearVelocity += m_totalForce * (m_inverseMass * step);

View File

@@ -25,7 +25,8 @@ subject to the following restrictions:
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
class btCollisionShape;
struct btMassProps;
class btMotionState;
typedef btScalar dMatrix3[4*3];
extern float gLinearAirDamping;
@@ -57,9 +58,13 @@ class btRigidBody : public btCollisionObject
btScalar m_kinematicTimeStep;
//m_optionalMotionState allows to automatic synchronize the world transform for active objects
btMotionState* m_optionalMotionState;
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, 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);
@@ -138,9 +143,8 @@ public:
void applyTorqueImpulse(const btVector3& torque)
{
if (!IsStatic())
if (!isStaticObject()&& !isKinematicObject())
m_angularVelocity += m_invInertiaTensorWorld * torque;
}
void applyImpulse(const btVector3& impulse, const btVector3& rel_pos)
@@ -176,9 +180,14 @@ public:
}
void setLinearVelocity(const btVector3& lin_vel);
void setAngularVelocity(const btVector3& ang_vel) {
if (!IsStatic())
inline void setLinearVelocity(const btVector3& lin_vel)
{
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;
}
@@ -275,6 +284,20 @@ public:
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
int m_contactSolverType;
int m_frictionSolverType;

View File

@@ -25,7 +25,8 @@ subject to the following restrictions:
btSimpleDynamicsWorld::btSimpleDynamicsWorld()
:m_constraintSolver(new btSequentialImpulseConstraintSolver),
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),
m_constraintSolver(constraintSolver),
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()
{
@@ -79,7 +101,7 @@ void btSimpleDynamicsWorld::updateAabbs()
btRigidBody* body = btRigidBody::upcast(colObj);
if (body)
{
if (body->IsActive() && (!body->IsStatic()))
if (body->IsActive() && (!body->isStaticObject()))
{
btPoint3 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);
if (body)
{
if (body->IsActive() && (!body->IsStatic()))
if (body->IsActive() && (!body->isStaticObject()))
{
body->predictIntegratedTransform(timeStep, predictedTrans);
body->proceedToTransform( predictedTrans);
@@ -118,12 +140,14 @@ void btSimpleDynamicsWorld::predictUnconstraintMotion(float timeStep)
btRigidBody* body = btRigidBody::upcast(colObj);
if (body)
{
if (body->IsActive() && (!body->IsStatic()))
if (!body->isStaticObject())
{
body->applyForces( timeStep);
body->integrateVelocities( timeStep);
body->predictIntegratedTransform(timeStep,body->m_interpolationWorldTransform);
if (body->IsActive())
{
body->applyForces( timeStep);
body->integrateVelocities( timeStep);
body->predictIntegratedTransform(timeStep,body->m_interpolationWorldTransform);
}
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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