From c8a0c9519599383df407e780ecc9cc7974dc405f Mon Sep 17 00:00:00 2001 From: ejcoumans Date: Sun, 25 Jun 2006 19:36:50 +0000 Subject: [PATCH] added basic collision filtering, in broadphase. more advanced collision filtering should happen in CollisionDispatch::NeedsCollision fixed CcdPhysicsDemo: don't pick static objects, it create a point 2 point constraint, which assert in jacobian generation --- Bullet/BroadphaseCollision/AxisSweep3.cpp | 10 +++--- Bullet/BroadphaseCollision/AxisSweep3.h | 4 +-- .../BroadphaseCollision/BroadphaseInterface.h | 2 +- Bullet/BroadphaseCollision/BroadphaseProxy.h | 12 ++++--- .../BroadphaseCollision/SimpleBroadphase.cpp | 8 +++-- Bullet/BroadphaseCollision/SimpleBroadphase.h | 18 ++++++++-- Bullet/CollisionDispatch/CollisionWorld.cpp | 6 ++-- Bullet/CollisionDispatch/CollisionWorld.h | 2 +- Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp | 19 +++++++---- Demos/ConcaveDemo/ConcavePhysicsDemo.cpp | 15 ++++++++ .../CcdPhysics/CcdPhysicsController.h | 34 +++++++++++++++++++ .../CcdPhysics/CcdPhysicsEnvironment.cpp | 2 +- 12 files changed, 106 insertions(+), 26 deletions(-) diff --git a/Bullet/BroadphaseCollision/AxisSweep3.cpp b/Bullet/BroadphaseCollision/AxisSweep3.cpp index 25abf92ae..71b89053f 100644 --- a/Bullet/BroadphaseCollision/AxisSweep3.cpp +++ b/Bullet/BroadphaseCollision/AxisSweep3.cpp @@ -21,11 +21,12 @@ #include -BroadphaseProxy* AxisSweep3::CreateProxy( const SimdVector3& min, const SimdVector3& max,int shapeType,void* userPtr ) +BroadphaseProxy* AxisSweep3::CreateProxy( const SimdVector3& min, const SimdVector3& max,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask) { - unsigned short handleId = AddHandle(min,max, userPtr); + unsigned short handleId = AddHandle(min,max, userPtr,collisionFilterGroup,collisionFilterMask); Handle* handle = GetHandle(handleId); + return handle; } @@ -156,7 +157,7 @@ void AxisSweep3::FreeHandle(unsigned short handle) -unsigned short AxisSweep3::AddHandle(const SimdPoint3& aabbMin,const SimdPoint3& aabbMax, void* pOwner) +unsigned short AxisSweep3::AddHandle(const SimdPoint3& aabbMin,const SimdPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask) { // quantize the bounds unsigned short min[3], max[3]; @@ -169,10 +170,11 @@ unsigned short AxisSweep3::AddHandle(const SimdPoint3& aabbMin,const SimdPoint3& Handle* pHandle = GetHandle(handle); - pHandle->m_handleId = handle; //pHandle->m_pOverlaps = 0; pHandle->m_clientObject = pOwner; + pHandle->m_collisionFilterGroup = collisionFilterGroup; + pHandle->m_collisionFilterMask = collisionFilterMask; // compute current limit of edge arrays int limit = m_numHandles * 2; diff --git a/Bullet/BroadphaseCollision/AxisSweep3.h b/Bullet/BroadphaseCollision/AxisSweep3.h index 0a2cb55de..b29534724 100644 --- a/Bullet/BroadphaseCollision/AxisSweep3.h +++ b/Bullet/BroadphaseCollision/AxisSweep3.h @@ -99,14 +99,14 @@ public: //this is replace by sweep and prune } - unsigned short AddHandle(const SimdPoint3& aabbMin,const SimdPoint3& aabbMax, void* pOwner); + unsigned short AddHandle(const SimdPoint3& aabbMin,const SimdPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask); void RemoveHandle(unsigned short handle); void UpdateHandle(unsigned short handle, const SimdPoint3& aabbMin,const SimdPoint3& aabbMax); inline Handle* GetHandle(unsigned short index) const {return m_pHandles + index;} //Broadphase Interface - virtual BroadphaseProxy* CreateProxy( const SimdVector3& min, const SimdVector3& max,int shapeType,void* userPtr ); + virtual BroadphaseProxy* CreateProxy( const SimdVector3& min, const SimdVector3& max,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask); virtual void DestroyProxy(BroadphaseProxy* proxy); virtual void SetAabb(BroadphaseProxy* proxy,const SimdVector3& aabbMin,const SimdVector3& aabbMax); diff --git a/Bullet/BroadphaseCollision/BroadphaseInterface.h b/Bullet/BroadphaseCollision/BroadphaseInterface.h index 5b9efc6b9..88bf896a9 100644 --- a/Bullet/BroadphaseCollision/BroadphaseInterface.h +++ b/Bullet/BroadphaseCollision/BroadphaseInterface.h @@ -29,7 +29,7 @@ class BroadphaseInterface public: virtual ~BroadphaseInterface() {} - virtual BroadphaseProxy* CreateProxy( const SimdVector3& min, const SimdVector3& max,int shapeType,void* userPtr ) =0; + virtual BroadphaseProxy* CreateProxy( const SimdVector3& min, const SimdVector3& max,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask) =0; virtual void DestroyProxy(BroadphaseProxy* proxy)=0; virtual void SetAabb(BroadphaseProxy* proxy,const SimdVector3& aabbMin,const SimdVector3& aabbMax)=0; virtual void CleanProxyFromPairs(BroadphaseProxy* proxy)=0; diff --git a/Bullet/BroadphaseCollision/BroadphaseProxy.h b/Bullet/BroadphaseCollision/BroadphaseProxy.h index 1fd3ea1b8..c1c83502f 100644 --- a/Bullet/BroadphaseCollision/BroadphaseProxy.h +++ b/Bullet/BroadphaseCollision/BroadphaseProxy.h @@ -54,12 +54,16 @@ struct BroadphaseProxy //Usually the client CollisionObject or Rigidbody class void* m_clientObject; + unsigned int m_collisionFilterGroup; + unsigned int m_collisionFilterMask; - + //used for memory pools BroadphaseProxy() :m_clientObject(0){} - BroadphaseProxy(int shapeType,void* userPtr) - :m_clientObject(userPtr) - //m_clientObjectType(shapeType) + + BroadphaseProxy(void* userPtr,short int collisionFilterGroup, short int collisionFilterMask) + :m_clientObject(userPtr), + m_collisionFilterGroup(collisionFilterGroup), + m_collisionFilterMask(collisionFilterMask) { } diff --git a/Bullet/BroadphaseCollision/SimpleBroadphase.cpp b/Bullet/BroadphaseCollision/SimpleBroadphase.cpp index c0796f9b9..5025309b3 100644 --- a/Bullet/BroadphaseCollision/SimpleBroadphase.cpp +++ b/Bullet/BroadphaseCollision/SimpleBroadphase.cpp @@ -74,7 +74,7 @@ SimpleBroadphase::~SimpleBroadphase() } -BroadphaseProxy* SimpleBroadphase::CreateProxy( const SimdVector3& min, const SimdVector3& max,int shapeType,void* userPtr) +BroadphaseProxy* SimpleBroadphase::CreateProxy( const SimdVector3& min, const SimdVector3& max,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask) { if (m_numProxies >= m_maxProxies) { @@ -84,7 +84,7 @@ BroadphaseProxy* SimpleBroadphase::CreateProxy( const SimdVector3& min, const assert(min[0]<= max[0] && min[1]<= max[1] && min[2]<= max[2]); int freeIndex= m_freeProxies[m_firstFreeProxy]; - SimpleBroadphaseProxy* proxy = new (&m_proxies[freeIndex])SimpleBroadphaseProxy(min,max,shapeType,userPtr); + SimpleBroadphaseProxy* proxy = new (&m_proxies[freeIndex])SimpleBroadphaseProxy(min,max,shapeType,userPtr,collisionFilterGroup,collisionFilterMask); m_firstFreeProxy++; SimpleBroadphaseProxy* proxy1 = &m_proxies[0]; @@ -181,6 +181,10 @@ void SimpleBroadphase::AddOverlappingPair(BroadphaseProxy* proxy0,BroadphaseProx //don't add overlap with own assert(proxy0 != proxy1); + if (!NeedsCollision(proxy0,proxy1)) + return; + + BroadphasePair pair(*proxy0,*proxy1); m_OverlappingPairs[m_NumOverlapBroadphasePair] = pair; diff --git a/Bullet/BroadphaseCollision/SimpleBroadphase.h b/Bullet/BroadphaseCollision/SimpleBroadphase.h index b61f82b62..be891f403 100644 --- a/Bullet/BroadphaseCollision/SimpleBroadphase.h +++ b/Bullet/BroadphaseCollision/SimpleBroadphase.h @@ -30,8 +30,8 @@ struct SimpleBroadphaseProxy : public BroadphaseProxy SimpleBroadphaseProxy() {}; - SimpleBroadphaseProxy(const SimdPoint3& minpt,const SimdPoint3& maxpt,int shapeType,void* userPtr) - :BroadphaseProxy(shapeType,userPtr), + SimpleBroadphaseProxy(const SimdPoint3& minpt,const SimdPoint3& maxpt,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask) + :BroadphaseProxy(userPtr,collisionFilterGroup,collisionFilterMask), m_min(minpt),m_max(maxpt) { } @@ -82,13 +82,25 @@ public: SimpleBroadphase(int maxProxies=4096,int maxOverlap=8192); virtual ~SimpleBroadphase(); - virtual BroadphaseProxy* CreateProxy( const SimdVector3& min, const SimdVector3& max,int shapeType,void* userPtr); + + virtual BroadphaseProxy* CreateProxy( const SimdVector3& min, const SimdVector3& max,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask); + virtual void DestroyProxy(BroadphaseProxy* proxy); virtual void SetAabb(BroadphaseProxy* proxy,const SimdVector3& aabbMin,const SimdVector3& aabbMax); virtual void CleanProxyFromPairs(BroadphaseProxy* proxy); virtual void DispatchAllCollisionPairs(Dispatcher& dispatcher,DispatcherInfo& dispatchInfo); + + inline bool NeedsCollision(BroadphaseProxy* proxy0,BroadphaseProxy* proxy1) const + { + bool collides = proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask; + collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask); + + return collides; + } + + }; diff --git a/Bullet/CollisionDispatch/CollisionWorld.cpp b/Bullet/CollisionDispatch/CollisionWorld.cpp index e8f73b2cc..58c243a53 100644 --- a/Bullet/CollisionDispatch/CollisionWorld.cpp +++ b/Bullet/CollisionDispatch/CollisionWorld.cpp @@ -112,7 +112,7 @@ void CollisionWorld::StoreIslandActivationState() -void CollisionWorld::AddCollisionObject(CollisionObject* collisionObject) +void CollisionWorld::AddCollisionObject(CollisionObject* collisionObject,short int collisionFilterGroup,short int collisionFilterMask) { m_collisionObjects.push_back(collisionObject); @@ -128,7 +128,9 @@ void CollisionWorld::AddCollisionObject(CollisionObject* collisionObject) minAabb, maxAabb, type, - collisionObject + collisionObject, + collisionFilterGroup, + collisionFilterMask ); diff --git a/Bullet/CollisionDispatch/CollisionWorld.h b/Bullet/CollisionDispatch/CollisionWorld.h index 1589da6da..fd34a83a2 100644 --- a/Bullet/CollisionDispatch/CollisionWorld.h +++ b/Bullet/CollisionDispatch/CollisionWorld.h @@ -201,7 +201,7 @@ public: void RayTest(const SimdVector3& rayFromWorld, const SimdVector3& rayToWorld, RayResultCallback& resultCallback); - void AddCollisionObject(CollisionObject* collisionObject); + void AddCollisionObject(CollisionObject* collisionObject,short int collisionFilterGroup=1,short int collisionFilterMask=1); CollisionObjectArray& GetCollisionObjectArray() { diff --git a/Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp b/Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp index 02b6750ea..6023c6b4d 100644 --- a/Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp +++ b/Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp @@ -155,11 +155,7 @@ int main(int argc,char** argv) materialProps.m_friction = 10.5f; materialProps.m_restitution = 0.0f; - CcdConstructionInfo ccdObjectCi; - ccdObjectCi.m_friction = 0.5f; - - ccdObjectCi.m_linearDamping = shapeProps.m_lin_drag; - ccdObjectCi.m_angularDamping = shapeProps.m_ang_drag; + SimdTransform tr; tr.setIdentity(); @@ -180,6 +176,13 @@ int main(int argc,char** argv) for (i=0;iSetMargin(0.05f); @@ -242,12 +245,16 @@ int main(int argc,char** argv) shapeProps.m_mass = 0.f; ccdObjectCi.m_mass = shapeProps.m_mass; ccdObjectCi.m_collisionFlags = CollisionObject::isStatic; + + ccdObjectCi.m_collisionFilterGroup = CollisionFilterGroups::Static; + ccdObjectCi.m_collisionFilterMask = CollisionFilterGroups::All ^ CollisionFilterGroups::Static; } else { shapeProps.m_mass = 1.f; ccdObjectCi.m_mass = shapeProps.m_mass; ccdObjectCi.m_collisionFlags = 0; + } @@ -817,7 +824,7 @@ void clientMouseFunc(int button, int state, int x, int y) CcdPhysicsController* physCtrl = static_cast(hitObj); RigidBody* body = physCtrl->GetRigidBody(); - if (body) + if (body && !body->IsStatic()) { pickedBody = body; pickedBody->SetActivationState(DISABLE_DEACTIVATION); diff --git a/Demos/ConcaveDemo/ConcavePhysicsDemo.cpp b/Demos/ConcaveDemo/ConcavePhysicsDemo.cpp index 79e963a98..efb09b9a6 100644 --- a/Demos/ConcaveDemo/ConcavePhysicsDemo.cpp +++ b/Demos/ConcaveDemo/ConcavePhysicsDemo.cpp @@ -20,6 +20,8 @@ subject to the following restrictions: #include "CollisionShapes/BoxShape.h" #include "CollisionShapes/Simplex1to4Shape.h" #include "Dynamics/RigidBody.h" +#include "BroadphaseCollision/AxisSweep3.h" + #include "ConstraintSolver/SimpleConstraintSolver.h" #include "ConstraintSolver/OdeConstraintSolver.h" #include "CollisionDispatch/CollisionDispatcher.h" @@ -84,6 +86,19 @@ int gIndices[NUM_TRIANGLES*3]; int main(int argc,char** argv) { + printf("BroadphaseProxy: %i\n",sizeof(BroadphaseProxy)); + printf("AxisSweep3::Handle : %i\n",sizeof(AxisSweep3::Handle)); + + printf("SimpleBroadphaseProxy : %i\n",sizeof(SimpleBroadphaseProxy)); + + printf("RigidBody : %i\n",sizeof(RigidBody)); + + printf("CcdPhysicsController: %i\n",sizeof(CcdPhysicsController)); + + printf("ManifoldPoint: %i\n",sizeof(ManifoldPoint)); + + + setCameraDistance(30.f); #define TRISIZE 10.f diff --git a/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.h b/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.h index 856e08a51..7e72d6da5 100644 --- a/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.h +++ b/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsController.h @@ -39,6 +39,18 @@ extern bool gDisableDeactivation; class CcdPhysicsEnvironment; +///CollisionFilterGroups provides some optional usage of basic collision filtering +///this is done during broadphase, so very early in the pipeline +///more advanced collision filtering should be done in CollisionDispatcher::NeedsCollision +enum CollisionFilterGroups +{ + Default = 1, + Static = 2, + Kinematic = 4, + Debris = 8, + All = Default | Static | Kinematic | Debris, +}; + struct CcdConstructionInfo { CcdConstructionInfo() @@ -50,6 +62,8 @@ struct CcdConstructionInfo m_linearDamping(0.1f), m_angularDamping(0.1f), m_collisionFlags(0), + m_collisionFilterGroup(CollisionFilterGroups::Default), + m_collisionFilterMask(CollisionFilterGroups::All), m_MotionState(0), m_physicsEnv(0), m_inertiaFactor(1.f) @@ -66,6 +80,15 @@ struct CcdConstructionInfo SimdScalar m_angularDamping; int m_collisionFlags; + ///optional use of collision group/mask: + ///only collision with object goups that match the collision mask. + ///this is very basic early out. advanced collision filtering should be + ///done in the CollisionDispatcher::NeedsCollision and NeedsResponse + ///both values default to 1 + short int m_collisionFilterGroup; + short int m_collisionFilterMask; + + CollisionShape* m_collisionShape; class PHY_IMotionState* m_MotionState; @@ -158,6 +181,17 @@ class CcdPhysicsController : public PHY_IPhysicsController virtual void setNewClientInfo(void* clientinfo); virtual PHY_IPhysicsController* GetReplica(); + ///There should be no 'SetCollisionFilterGroup' method, as changing this during run-time is will result in errors + short int GetCollisionFilterGroup() const + { + return m_cci.m_collisionFilterGroup; + } + ///There should be no 'SetCollisionFilterGroup' method, as changing this during run-time is will result in errors + short int GetCollisionFilterMask() const + { + return m_cci.m_collisionFilterMask; + } + virtual void calcXform() {} ; virtual void SetMargin(float margin) {}; diff --git a/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsEnvironment.cpp b/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsEnvironment.cpp index 972d38faa..d871711e4 100644 --- a/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsEnvironment.cpp +++ b/Extras/PhysicsInterface/CcdPhysics/CcdPhysicsEnvironment.cpp @@ -374,7 +374,7 @@ void CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl) body->setGravity( m_gravity ); m_controllers.push_back(ctrl); - m_collisionWorld->AddCollisionObject(body); + m_collisionWorld->AddCollisionObject(body,ctrl->GetCollisionFilterGroup(),ctrl->GetCollisionFilterMask()); assert(body->m_broadphaseHandle);