new to the forum, collision group filtering

vicviper
Posts: 21
Joined: Thu Jun 01, 2006 9:55 pm

new to the forum, collision group filtering

Post by vicviper »

Hi, I've been looking for a free, good physics engine for a long time, I've been disappointed by the current scene... most physics engines around are commercial, and the only reasonably good, and free engine has been ODE, although it's getting old very fast.

I recently found Bullet, and found it very interesting, and I am considering using it in my home project as a core collision detection system.

But, I have some questions I would like to know:

The authors think Bullet is mature enough to be used in a reasonably complex project? or it will explode at the first bump?

I'm planning to use only the collision detector, not the dynamics solver, but, I am going to place 100s of objects in scene, all the time, will be able to handle this stress?

Also, due to the nature of the project (let's just say it, a shooter), it's extremely important for me to be able to cull some collisions between objects, in this way:

For every collision object in the scene, I have 2 DWORD flags:

DWORD group; // indicates with a bit, which group pertains this object
DWORD groupmask; // this object will only detect collisions with all objects that give positive to this mask (objectA.group & objectB.mask == true) ... or something like that.

I need this because I don't want all the bullets colliding each other.

Also, it is possible to use a static, tri-mesh collision detection against lots of primitives? and, it is fast and stable?

Thanks in advance
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Re: new to the forum, and some questions

Post by Erwin Coumans »

vicviper wrote:Hi, I've been looking for a free, good physics engine for a long time, I've been disappointed by the current scene... most physics engines around are commercial, and the only reasonably good, and free engine has been ODE, although it's getting old very fast.

I recently found Bullet, and found it very interesting, and I am considering using it in my home project as a core collision detection system.

But, I have some questions I would like to know:

The authors think Bullet is mature enough to be used in a reasonably complex project? or it will explode at the first bump?
Bullet Discrete Collision Detection system should be mature enough for a reasonably complex project... But, it has some limitations and rules that might break things. Most important: there are hardcoded margins / tolerances of 0.06 units, so Collision Shapes should be at least say 0.3 units in any direction, otherwise you get instability. Also, no 'compound' support yet, but this can easily be added. Some extra work is needed if you need much smaller object sizes. The Collision Margin not only serves for stability, it also prevents more expensive penetration cases. Once objects penetrate more then the sum of their margins, it becomes more expensive.

The Continuous Collision Detection part is not so mature yet, so I would use that with 'care'. The Continuous Collision Detection algorithms are currently used for the ray casting, linear casting (Sweep) etc.
vicviper wrote: I'm planning to use only the collision detector, not the dynamics solver, but, I am going to place 100s of objects in scene, all the time, will be able to handle this stress?
It depends what kind of collision representation: a few hundred spheres, boxes, cylinders and cones should be fine, convex polyhedra too, as long as they don't have too much detail (say less then 25 points). There is some profiling support, which can give some performance indication. Locate quickprof.h, in LinearMath folder, and #define USE_QUICKPROF 1
vicviper wrote: Also, due to the nature of the project (let's just say it, a shooter), it's extremely important for me to be able to cull some collisions between objects, in this way:

For every collision object in the scene, I have 2 DWORD flags:

DWORD group; // indicates with a bit, which group pertains this object
DWORD groupmask; // this object will only detect collisions with all objects that give positive to this mask (objectA.group & objectB.mask == true) ... or something like that.
I need this because I don't want all the bullets colliding each other.
You can easily modify/add collision filters yourself, check out:

bool CollisionDispatcher::NeedsCollision(BroadphaseProxy& proxy0,BroadphaseProxy& proxy1)
vicviper wrote: Also, it is possible to use a static, tri-mesh collision detection against lots of primitives? and, it is fast and stable?
Yes, Bullet has TriangleMeshShape, see the ConcaveDemo. It uses a bounding volume hierarchy (AABB tree) for acceleration.

I'm happy to get feedback, so we can improve the library.
Thanks,
Erwin
vicviper
Posts: 21
Joined: Thu Jun 01, 2006 9:55 pm

Post by vicviper »

So far, I understand that I have to move the objects manually in the scene, then, I should call PerformDiscreteCollisionDetection(); , and after that, I am not completely sure on the steps to go, I've checked the "CollisionInterfaceDemo" that shows that, after the world update, I should get the CollisionDispatcher, and from that, get a list of "manifolds".

What I am not sure is what these "manifolds" are... I assume they're a list of collision detections, but, Will I receive just a single "manifold" for every object pair which collided? or I will received a "manifold" for every contact point? (thus, I'll have the possibility to receive more than one "manifold" for two colliding objects. In the code it is mentioned that this is "one way" to get the list of collisions... which are the other ways?

In which part of the collision pipeline should I call "NeedsCollision" ? By looking at the code, I looks like a callback called after the collision pairs have been collected... shouldn't be better to cull them at the beginning of the pipeline?

also, when dealing with objects (without dynamics) which is the proper way of moving/rotating them? , can I just modify m_WorldTransform without any additional process, or should I call some special function?

Thanks in advance!
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Post by Erwin Coumans »

I'm planning to add more interface to the Collision Detection (CollisionWorld/CollisionObejct). So far, most interface is to the entire Physics Engine (CcdPhysicsEnvironment/CcdPhysicsController).
vicviper wrote:So far, I understand that I have to move the objects manually in the scene, then, I should call PerformDiscreteCollisionDetection(); , and after that, I am not completely sure on the steps to go, I've checked the "CollisionInterfaceDemo" that shows that, after the world update, I should get the CollisionDispatcher, and from that, get a list of "manifolds".

What I am not sure is what these "manifolds" are... I assume they're a list of collision detections, but, Will I receive just a single "manifold" for every object pair which collided? or I will received a "manifold" for every contact point? (thus, I'll have the possibility to receive more than one "manifold" for two colliding objects. In the code it is mentioned that this is "one way" to get the list of collisions... which are the other ways?
Each potential overlapping object pair has 1 Persistent Manifold. Each Persistent Manifold has a maximum of 4 contact points.
In which part of the collision pipeline should I call "NeedsCollision" ? By looking at the code, I looks like a callback called after the collision pairs have been collected... shouldn't be better to cull them at the beginning of the pipeline?
Correct, you just get a callback.

You could add the filter during the broadphase if it really is a bottleneck. Narrowphase and Constraint solving take up most time usually, but if your scenario is different, it can be modified.
Also, when dealing with objects (without dynamics) which is the proper way of moving/rotating them? , can I just modify m_WorldTransform without any additional process, or should I call some special function?

Thanks in advance!
If you just use the Collision Detection, you can just modify the m_WorldTransform, as long as the motion is coherent (small steps). If the object moves to a completely different location, some extra work needs to be done to flush the contact points.

Thanks for the suggestions/feedback. I will take it into consideration while adding more interfaces to the Collision Detection API.

Hope this helps,
Erwin
vicviper
Posts: 21
Joined: Thu Jun 01, 2006 9:55 pm

Post by vicviper »

Erwin Coumans wrote: You could add the filter during the broadphase if it really is a bottleneck. Narrowphase and Constraint solving take up most time usually, but if your scenario is different, it can be modified.
Yes, my current project involves a lot ( arround 300) moving arround, and overlapping, but usually not colliding, with the current implementation, Bullet would give a lot of collision hits, just to be discarded by the NeedCollision callback.

The solution would be to add a pair of variables to the CollisionObject class, these two variables would be used this way (I'll give you a sample given my current project, so things will be more clear)

Le't say I have this:

enum ObjectTypes
{
scenary = 1,
player = 2,
enemy = 4,
playerbullet = 8,
enemybullet = 16,
item = 32,
};


When I create a player, I create it with these values for the two variables:

m_Group = player;
m_GroupMask = scenary | enemy | enemybullet | item;

Whith this, I am telling the system that this object can collide with the scenary, enemies, enemy bullets and items, but it can't collide with other players or its own bullets.

For an item object it would be:

m_Group = item;
m_GroupMask = player;

This way, only the players can pick the items.

Having this two variables, in the very beginning of testing if two objects can collide, you can do this:

if ( !(object1.m_Group & object2.m_GroupMask) ) return(false);

this is a really fast test that can be placed before everything else, even before than simple bounding sphere tests.

And, in order to keep default functionality (all objects colliding against all others), the flag values for all objects would be:

m_Group = 1;
m_GroupMask = 1;

Another advantage of this system is that, in many cases, when a collision is detected, just by checking the flags of both objects you can decide a response (a bullet with an enemy renders an explosion and destroys both objects), and leaves the callback for only very special cases.

Edit: Ine extra feature would be to add the GroupMask to they CollisionWorld::RayTest(from, to, callback, groupmask), this way, it could be possible to cast rays keeping certain objects "transparent" (for example, when casting rays against the scenary, skipping moving entitities)

Hope this helps you improve Bullet :)

Thanks in advance
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Post by Erwin Coumans »

Basic collision filtering is implemented in Bullet 1.6a.

See CcdPhysicsDemo how to use it.
You can modify the CcdConstructionInfo members:

Code: Select all


//to disable static-static collision processing, move static objects into their own group (StaticFilter), and disable collision with that group:

ccdObjectCi.m_collisionFilterGroup = CcdConstructionInfo::StaticFilter;
ccdObjectCi.m_collisionFilterMask = CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::StaticFilter;
If you are interested:

Code: Select all

//those are the members / data types in CcdConstructionInfo

short int  m_collisionFilterGroup  ( defaults to DefaultFilter = 1)
short int  m_collisionFilterMask (defaults to AllFilter)

enum   CollisionFilterGroups { 
  DefaultFilter = 1, 
  StaticFilter = 2, 
  KinematicFilter = 4, 
  DebrisFilter = 8, 
  AllFilter = DefaultFilter | StaticFilter | KinematicFilter | DebrisFilter 
}

this is a really fast test that can be placed before everything else, even before than simple bounding sphere tests.
Bullet uses the 3d axis sweep and prune. This incremental approach has only cost for moving objects / swaps. So overlapping static-static objects will only perform the check once, during startup/addition to the broadphase, when you use this new collision filter.

Let me know if this works for you.
Download:
http://www.continuousphysics.com/mediaw ... e=Download