Collision only - collision culling using flags?

Buckeye
Posts: 3
Joined: Thu Aug 20, 2009 6:57 am

Collision only - collision culling using flags?

Post by Buckeye »

First - I'm a noob. I've worked a bit with ODE and am coming to the conclusion that ODE might be overkill for my purposes. However, the API concepts appear somewhat similar between Bullet and ODE (collision objects, callbacks, culling, etc.) So, for use in a game, I'm trying to get started with Bullet collision-only to see if it will work for me. Dynamics really isn't necessary for the interface I want.

As I will likely have many static objects in the environment and few moving objects, I'm mostly interested in quick culling of static-static collision testing, or, perhaps elimination altogether? AABB testing will probably be fine for what I need, although (for the time being) I'm also maintaining an OOBB in my code until I find an adequate collision-detection system.

I've looked at the collision-only demo example and have several questions for which I can't find documentation.

I've noticed btCollisionObjects have a collision flag and a collision type. Are those used or can they be used for culling, say, to eliminate early static-static collisions?

Is there a collision object equivalent to the bitmasks for filter group and filter mask (that can be set for rigid bodies)?

Unlike rigid bodies, the source code for collision objects implies there are only fixed types (rather than a user bitfield) for collision flags and collision types. If they are used during collision detection (I haven't found anything yet in the source code that tells me), what algorithm is used? If they aren't used, can I use them for my own purposes? Will I need a callback to do that?

Since I will have just a few moving objects, is there a way I can test for just my moving objects and thereby eliminate any static-static testing? Would that be faster?

The user manual states that position and depth are returned for collisions. Is the depth the getDistance() function for btManifoldPoint? Is the m_normalWorldOnB attribute of btManifoldPoint the normal on object B at the collision position? If so, is the penetration depth the distance along the normal from the position to the AABB boundary?

Sorry to have so many questions. I've looked through the FAQ, user's manual and API reference and couldn't seem to find much info on collision-only stuff. Is there information available somewhere that describes the use/purpose of btCollisionObject attributes and functions and/or how the collision detection pipeline works?
Buckeye
Posts: 3
Joined: Thu Aug 20, 2009 6:57 am

Re: Collision only - collision culling using flags?

Post by Buckeye »

I've answered some of my own questions (hopefully for the benefit of other noobs).

I still would like to know:
- Is there a way to check collisions on a per-object basis, rather than checking every pair?
- Are my assumptions below correct?
- Can the normalOnA be determined? I'd like to have both normals.
- Am I allowed to create another collision test in the FilterCallback to do that? I.e., can I force a collision test between object B and object A (just reversing the order) and get the other normal?
I've noticed btCollisionObjects have a collision flag and a collision type. Are those used or can they be used for culling, say, to eliminate early static-static collisions?
A qualified "Yes." It appears that the collision flags/type are not used as I can set them to various values and (apparently) still get proper collision detection.
Is there a collision object equivalent to the bitmasks for filter group and filter mask (that can be set for rigid bodies)?
Apparently not, but collision flags can be used. See below.
Is the m_normalWorldOnB attribute of btManifoldPoint the normal on object B at the collision position?
Still not sure. I'm guessing that a better description would be "m_normalWorldOnB is the normal on object B's AABB at the position on object B's AABB given by m_positionWorldOnB when an overlap of the AABBs for A and B were detected."

If Bullet is similar to ODE, then translating object A along m_normalWorldOnB a distance of getDistance() would produce a point contact between the two objects at m_positionWorldOnB. I assume that's correct because the code for btManifoldPoint has

Code: Select all

m_positionWorldOnA = m_positionWorldOnB + m_normalWorldOnB * m_distance1;
What I'm trying out at present is:

Code: Select all

// objects is an array of btCollisionObject
objects[<any moving object>].setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT);
//...
// instead of btAxisSweep3
btDbvtBroadphase* broadphase = new btDbvtBroadphase(); // allow the world to be any size
broadphase->getOverlappingPairCache()->setOverlapFilterCallback(new FilterCallback);
collisionWorld = new btCollisionWorld(dispatcher,broadphase,collisionConfiguration);
where FilterCallback is:

Code: Select all

struct FilterCallback : public btOverlapFilterCallback {
// return true when pairs need collision
	virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
	const
	{ // this code can be shortened. still testing
		btCollisionObject *c0 = (btCollisionObject*)proxy0->m_clientObject;
		btCollisionObject *c1 = (btCollisionObject*)proxy1->m_clientObject;
		bool collides = c0->isKinematicObject() || c1->isKinematicObject();
		return collides;
	}
};
btCollisionDispatcher (debug) complains that I haven't overridden needsCollision. That appears to be acceptable.

I suppose I can add my own category and "collidesWith" bitfields to btCollisionObject and compile my own library. However, if collision-only is to be fully supported, is there a reason why that shouldn't be done as a change to Bullet?