Collision groups?

gizwiz
Posts: 7
Joined: Mon Apr 16, 2007 9:18 pm

Collision groups?

Post by gizwiz »

I did a small program to simulate a broken windshield (the old fashioned type that shatter into 100.000 pieces) for a motion picture, and it's coming along very well.

But with 20.000 3D triangles (extruded) that collides with each other, and with my proxy car and actor, it's not very fast. - It's not very slow nether, but I prefer it to be faster. (With the 20.000 objects close together, it's around 50 sec/frame on my PC)

Looking at the results I'm getting, the inter-glass-piece collision don't really add allot to the visual impression, so I wanted to try it without the glass pieces colliding, but to only have the glass hit the car.

But I can't figure it out....

Please explain it to me, like I'm a two-year old :)

For my glass pieces, I tried (among alot other tests)

bool isDynamic = !(body->isStaticObject() || body->isKinematicObject());
collisionFilterMask = GLASS; // GLASS = 32
body->setCollisionFlags(collisionFilterMask);
m_dynamicsWorld->addRigidBody(body);

and for the car...

body->setCollisionFlags( body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
body->setActivationState(DISABLE_DEACTIVATION);
bool isDynamic = !(body->isStaticObject() || body->isKinematicObject());
collisionFilterGroup = CAR;//isDynamic? btBroadphaseProxy::DefaultFilter : btBroadphaseProxy::StaticFilter;
collisionFilterMask = isDynamic? btBroadphaseProxy::AllFilter : btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter;
}
m_dynamicsWorld->addCollisionObject(body, collisionFilterGroup, collisionFilterMask);


Which makes the glass not hit the car, but the glass hits the glass :(

How do I make this work?

Thanks alot....

PS: I'll upload a flick at http://www.gizwiz.dk/car_glass.avi in a hour or two.
gizwiz
Posts: 7
Joined: Mon Apr 16, 2007 9:18 pm

Changed filename in upload

Post by gizwiz »

It's late at night, and I couldn't find a good AVI codec to upload in, so I made a quicktime.

http://www.gizwiz.dk/car_glass.mov

The boxy thing is a fast test-version of a car colission object. The car hits a stunt-ramp, and is thrown up into the air, spinning around it's long axis.

In some sequences, you will see me trying to change the camera to make everything visible.

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

Post by Erwin Coumans »

For the glass, assign collisionFilterGroup to GLASS and assign collisionFilterMask to CAR. The mask selects the group of objects to collide with.

For the car, all filter should be fine, as long as it includes the GLASS.

Hope this helps,
Erwin
gizwiz
Posts: 7
Joined: Mon Apr 16, 2007 9:18 pm

Group on rigid bodies?

Post by gizwiz »

Right - that's what I tried to do, but how do I assign a collision group to a rigid body? - I can't find a interface to do so.

--Michael
gizwiz
Posts: 7
Joined: Mon Apr 16, 2007 9:18 pm

Dont work :(

Post by gizwiz »

I pasted the code from addRigidBody() so I could set the filter group for the glass pieces, so it now looks like this:

if(isDynamic) // This is a piece of glass
{
// this is the addRigidBody() Code with some minor changes
if (!body->isStaticOrKinematicObject())
{
body->setGravity(btVector3(0,-10,0));
}

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

m_dynamicsWorld->addCollisionObject(body,collisionFilterGroup,collisionFilterMask);
}
}
else // This is a animated (car) object, imported from maya
{
if((int)userData != -1)
{
body->setCollisionFlags( body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
body->setActivationState(DISABLE_DEACTIVATION);
bool isDynamic = !(body->isStaticObject() || body->isKinematicObject());
collisionFilterGroup = CAR;//isDynamic? btBroadphaseProxy::DefaultFilter : btBroadphaseProxy::StaticFilter;
collisionFilterMask = isDynamic? btBroadphaseProxy::AllFilter : btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter;
}
m_dynamicsWorld->addCollisionObject(body, collisionFilterGroup, collisionFilterMask);
}


And the glass dont hit the car (and dont hit a "default" object) - I dont know if the glass hits the glass, as it's just falling down under gravity.

What went wrong?

Thanks
gizwiz
Posts: 7
Joined: Mon Apr 16, 2007 9:18 pm

New FTP site

Post by gizwiz »

My FTP site can apparently not accept files over 34Mb :(

So I have uploaded the movie on my mothers webserver:

http://www.astrupholm.dk/car_glass.mov

--Michael
gizwiz
Posts: 7
Joined: Mon Apr 16, 2007 9:18 pm

Bug?

Post by gizwiz »

In btOverlappingPairCache.h:


inline bool needsBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const
{
bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);

return collides;
}


I belive line 4 in that code should say:

collides = collides | (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);

With the code as it is now there's no way (that I can see) that my glass/car example will ever work.

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

Post by Erwin Coumans »

You introduced collision groups CAR and GLASS, and they are not included in the 'AllFilter':

Code: Select all

	///optional filtering to cull potential collisions
	enum CollisionFilterGroups
	{
	        DefaultFilter = 1,
	        StaticFilter = 2,
	        KinematicFilter = 4,
	        DebrisFilter = 8,
			SensorTrigger = 16,
	        AllFilter = DefaultFilter | StaticFilter | KinematicFilter | DebrisFilter | SensorTrigger
	};
So you need to adjust the car 'collisionMask' to include 'GLASS':

Code: Select all

int carMaskfilter = btBroadphaseProxy::AllFilter | GLASS;
collisionFilterMask = isDynamic? carMaskfilter : carMaskfilter ^ btBroadphaseProxy::StaticFilter; 
hope this helps,
Erwin
gizwiz
Posts: 7
Joined: Mon Apr 16, 2007 9:18 pm

Solution

Post by gizwiz »

With the change I added, I made a localCreateRigidBody function with more understandable names for the parameters:

I hope this can help others understand how Masks and Groups works.


btRigidBody* View::localCreateRigidBody(float mass, const btTransform& startTransform,btCollisionShape* shape, void* userData, short IamOneOf, short ICollideWIth)

.........................................................

I'll try your method, it that works without changing the lib.

Thanks alot, and did I forget to say that Bullet is a supercool library, and very easy to work with and understand :)

Please keep up the good work.

With 15000 pieces of glass (btConvexHullShape with 6 vertices each), and around 15 box to define my car, I can render 600 frames of animation in around 15 minutes :) - Good times.

Now I just need to move the animation back into Maya, create some more realistic looking glass pieces, and render :)

I'll probably use Bullet for another motion picture, where I need to blow up a private jet as it takes off. The script says "the plane explodes in a ball of fire" but I think I'll make some airplane debris too, now that it's so easy :)

You would'nt happen to be working on a 3D Fluid dynamics system that can simulate explotions, now would you :)

Regards,

Michael