Equivalent of OpenDE's space?

Post Reply
bram
Posts: 50
Joined: Sun Nov 23, 2008 4:43 pm

Equivalent of OpenDE's space?

Post by bram » Wed Nov 27, 2013 7:13 pm

I have not been able to find any reference to this in Bullet's manual.

Is there a Bullet equivalent for OpenDE's space object?
In OpenDE, geometries can be grouped as a space, and saves on collision tests in two ways:
  • If a geometry does not intersect with the bounding box of the space, it is not necessary to test for intersection with the contained geometries.
  • Collisions testing for geometries contained in the same space can be ignored.
E.g. it is quite customary to contain different parts of a vehicle in a single space for better culling, and also avoiding collisions of the wheels with the chassis. (Note: I am aware of Bullet's ray based vehicle system.)

tuan kuranes
Posts: 10
Joined: Mon Sep 04, 2006 1:40 pm
Location: Grenoble, France

Re: Equivalent of OpenDE's space?

Post by tuan kuranes » Thu Nov 28, 2013 9:04 am

bram wrote:
  • If a geometry does not intersect with the bounding box of the space, it is not necessary to test for intersection with the contained geometries.
You can check GhostObject http://www.bulletphysics.org/mediawiki- ... d_Triggers

But note Bullet does optimise a lot more than openDe the broadphase collision part, using spatial partitioning system for collision (Dynamic AABB Tree), with conservative optimisation, etc. ( http://www.bulletphysics.org/mediawiki- ... Broadphase ) so it may not be very useful to go that route, it may even hurt more than it helps (breaking the conservative algo).
bram wrote:
  • Collisions testing for geometries contained in the same space can be ignored.
[/list]
I think the equivalent would be collision masks in bullet.

Overall collision mask and callback are more flexible in order to solve situation application side in more dynamic ways.
http://www.bulletphysics.org/mediawiki- ... _Filtering

User avatar
Erwin Coumans
Site Admin
Posts: 4155
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: Equivalent of OpenDE's space?

Post by Erwin Coumans » Tue Dec 03, 2013 10:50 pm

It looks like you are using spaces to perform collision filtering (exclude collisions using some condition, in your case if they are in the same space).

The easiest is to use collision group and mask, but then you can only have a limited number of vehicles.
Another solution is to create your custom collision filter and assign it to the broadphase using setOverlapFilterCallback(btOverlapFilterCallback* callback).
Just derive a class from btOverlapFilterCallback and implement needsBroadphaseCollision, with your custom rules.

Here is the default implementation:

Code: Select all

inline bool needsBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const
		{
			if (m_overlapFilterCallback)
				return m_overlapFilterCallback->needBroadphaseCollision(proxy0,proxy1);

			bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
			collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
			
			return collides;
		}
 
One way to recognize that a vehicle part is colliding against a part of the same vehicle is by using user pointer stored in the btRigidBody, and store the information there.
(you can access the btRigidBody from the broadphase proxy)

I wouldn't worry about performance implications, the default btDbvtBroadphase is pretty well optimized. Unlike OpenDE, Bullet's overlapping pairs are incrementally added and removed, so there are no duplicate checks.
Hope this helps,
Erwin

bram
Posts: 50
Joined: Sun Nov 23, 2008 4:43 pm

Re: Equivalent of OpenDE's space?

Post by bram » Tue Dec 11, 2018 8:35 pm

Thx,

For people trying to replicate this: you have to go through the cache, like so:

Code: Select all

broadphase->getOverlappingPairCache()->setOverlapFilterCallback(...)
I decided to use btCollisionObject's userIndex for the grouping per vehicle.

But note: because the information is cached, you need to set the userIndex before you add the rigidBody to the world, as collision filtering is decided at that moment.

This is my callback:

Code: Select all

class OverlapFilterCallback: public btOverlapFilterCallback
{
        inline bool needBroadphaseCollision( btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1 ) const
        {
                bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
                collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);

                if ( collides )
                {
                        const btCollisionObject* ob0 = (const btCollisionObject*)proxy0->m_clientObject;
                        const btCollisionObject* ob1 = (const btCollisionObject*)proxy1->m_clientObject;
                        const int u0 = ob0->getUserIndex();
                        const int u1 = ob1->getUserIndex();
                        if ( u0 == u1 && u0 != -1 )
                        {
                                //LOGI( "Skipping %p vs %p (%d/%d)", ob0, ob1, u0, u1 );
                                collides = false;
                        }
                }

                return collides;
        }
};
It works pretty well... it enables me to have wheels be tested against a chassis of another vehicle, but not against its own chassis, for instance.

Post Reply