Need some help using only Collision in Bullet.

Post Reply
reltham
Posts: 66
Joined: Fri Oct 12, 2007 6:28 pm
Location: San Diego

Need some help using only Collision in Bullet.

Post by reltham »

The project I am working on is using Bullet for collision only, and I need help with stuff I haven't found in the docs or demos.

First, the project is a seamless world that is streaming in chunks as you move around, and at any given time there will be about 1000-2000 btCollisionObjects. The majority of the objects are static (the ground, trees, buildings, etc.), and consist of a btBvhTriangleMeshShape. The rest of the objects are NPCs & PCs that are represented as simple boxes or sphere shapes.

1. Currently I initialize a btAxisSweep object with an aabb that is just arbitrarily large to cover what we have of the world so far, but doesn't this want to "fit" what is currently in the btCollisionWorld? Is there some other broadphase I should use if I have a dynamic world aabb? Does this even matter? Should I just specify a really HUGE world aabb and not worry?

2. The default values used in btDefaultCollisionConfiguration for the stack and pools seem rather large (consuming a fairly big chunk of memory) considering my number of objects, can you explain what a good size would be for the stackAlloc, persistenManifoldPool, and collisionAlgorithmPool members? Also, an API interface that let the user specify the numbers for max overlaping pairs and stack size (that are currently defines) and did the allocations internally still would be nice.

3. Right now I am only using the rayTest and convexTest stuff to do things like find the ground, test for movement, line of sight, etc. Do I even need to call performDiscreteCollisionDetection()? Should I be using the collision pair stuff for anything? I don't care about any of the collisions between my static objects, but won't they be in the pair list (as a majority of it)?

Maybe this stuff is supposed to be obvious? I'm normally a graphics engine person, so doing collision is new to me.

Thanks for any help you can give.

Roy Eltham
Senior Programmer
Sony Online Entertainment
User avatar
Erwin Coumans
Site Admin
Posts: 4232
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: Need some help using only Collision in Bullet.

Post by Erwin Coumans »

reltham wrote: 1. Currently I initialize a btAxisSweep object with an aabb that is just arbitrarily large to cover what we have of the world so far, but doesn't this want to "fit" what is currently in the btCollisionWorld? Is there some other broadphase I should use if I have a dynamic world aabb? Does this even matter? Should I just specify a really HUGE world aabb and not worry?
For streaming broadphase, you can consider using the btMultiSapBroadphase, or wait for Bullet 2.69 and use the btDbvhBroadphase. btMultiSapBroadphase allows you to add btAxisSweep broadphases. We can provide demos how to use those broadphases in large streaming worlds. (several streaming games use Bullet collision detection)
You should not use a HUGE aabbMin/Max for the world extends in the btAxisSweep . That will impact performance objects will not deactivate.
2. The default values used in btDefaultCollisionConfiguration for the stack and pools seem rather large (consuming a fairly big chunk of memory) considering my number of objects, can you explain what a good size would be for the stackAlloc, persistenManifoldPool, and collisionAlgorithmPool members? Also, an API interface that let the user specify the numbers for max overlaping pairs and stack size (that are currently defines) and did the allocations internally still would be nice.
persistenManifoldPool, and collisionAlgorithmPool should be large enough to contain the maximum number of pairs you ever expect. In many worlds, a safe bet would be 10*(total number of objects), but this is just a guestimate.
You can pass pool allocators of your own preferred size into the btDefaultCollisionConfiguration, or derive from the btDefaultCollisionConfiguration.
3. Right now I am only using the rayTest and convexTest stuff to do things like find the ground, test for movement, line of sight, etc. Do I even need to call performDiscreteCollisionDetection()? Should I be using the collision pair stuff for anything? I don't care about any of the collisions between my static objects, but won't they be in the pair list (as a majority of it)?
performDiscreteCollisionDetection usually performs better, instead of doing a separate query for each object. Especially when doing batch processing on the SPU. You can request a SPURS optimized version of Bullet through PS3 DevNet.

Hope this helps,
Erwin
reltham
Posts: 66
Joined: Fri Oct 12, 2007 6:28 pm
Location: San Diego

Re: Need some help using only Collision in Bullet.

Post by reltham »

Sorry to bring back this old post, but I needed some more details answered if possible.

1. I was curious as to what the stackAlloc object (inside the collision configuration) is used for and what it's size should be based on.

2. In my world I have a large number of static objects that make up the ground and stuff (trees, rocks, houses, etc.). I never want them to consume collision pair space between eachother. I only want them to participate in pairing with my dynamic objects. For example, I don't want to get pairs of two ground tiles, but I do want the pair of a ground tile and my dynamic object standing on the ground. How would I accomplish this? Is it possible?

Thanks,
Roy Eltham
SOE
User avatar
Erwin Coumans
Site Admin
Posts: 4232
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: Need some help using only Collision in Bullet.

Post by Erwin Coumans »

reltham wrote: 1. I was curious as to what the stackAlloc object (inside the collision configuration) is used for and what it's size should be based on.
btStackAlloc is not used anymore, by default. It is only used by the optional ODE quickstep solver, if you explicitly construct a btOdeQuickstepConstraintSolver. The btStackAlloc was introduced by a now deprecated penetration depth solver (btGjkEpaSolver, see USE_ORIGINAL_GJK in btGjkEpaPenetrationDepthSolver). The new btGjkEpaSolver2 doesn't use the stack allocator. This should be cleared up and documented.
2. In my world I have a large number of static objects that make up the ground and stuff (trees, rocks, houses, etc.). I never want them to consume collision pair space between eachother. I only want them to participate in pairing with my dynamic objects. For example, I don't want to get pairs of two ground tiles, but I do want the pair of a ground tile and my dynamic object standing on the ground. How would I accomplish this? Is it possible?
This is default behaviour. There are no broadphase collision pairs generated between static objects.

Thanks for the feedback,
Erwin
reltham
Posts: 66
Joined: Fri Oct 12, 2007 6:28 pm
Location: San Diego

Re: Need some help using only Collision in Bullet.

Post by reltham »

Thanks for the quick reply.

One last question I think, how to I make sure my collision object is considered static? Do I need to set a flag on them or what?

Most of my objects are btBvhTriangleMeshShapes, but I do have several that are btSphereShape and btBoxShape.
User avatar
Erwin Coumans
Site Admin
Posts: 4232
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: Need some help using only Collision in Bullet.

Post by Erwin Coumans »

reltham wrote:One last question I think, how to I make sure my collision object is considered static? Do I need to set a flag on them or what?

Most of my objects are btBvhTriangleMeshShapes, but I do have several that are btSphereShape and btBoxShape.
Yes, when adding the object to the collision world, just provide the right collision group and mask, like this (example taken from btDynamicsWorld::addRigidBody):

Code: Select all

	if (body->getCollisionShape())
	{
		bool isDynamic = !(body->isStaticObject() || body->isKinematicObject());
		short collisionFilterGroup = isDynamic? short(btBroadphaseProxy::DefaultFilter) : short(btBroadphaseProxy::StaticFilter);
		short collisionFilterMask = isDynamic? 	short(btBroadphaseProxy::AllFilter) : 	short(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);

		addCollisionObject(body,collisionFilterGroup,collisionFilterMask);
	}
The broadphase calls the 'needsBroadphaseCollision' before adding/removing an overlapping pair. The default implementation performs an 'AND' operation like this:

Code: Select all

SIMD_FORCE_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;
	}
You can override this behaviour by setting your custom filter callback using 'setOverlapFilterCallback'. See the CharacterDemo how to use this:

Code: Select all

m_hashPairCache->setOverlapFilterCallback (&myCustomOverlapFilterCallback);
Hope this helps,
Erwin
Post Reply