irrBullet - how to check collision and play a sound

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
cookie
Posts: 83
Joined: Sun Aug 23, 2009 9:30 pm

irrBullet - how to check collision and play a sound

Post by cookie »

Hm, maybe not the best Topic Title, but here is my problem:

I want to play a sound (with irrKlang. I know how to do this :>) when an physic object hits another one or the floor of the room or something different. I know how to detect collision but I've had this problem a few months ago: when I'm inside a room - which was given to irrBullet as rigidbody - and I want detect collision with this room, it shows always that there is an collision, because I'm standing INSIDE the room and this means I'm inside the "collision box".
Now I want to know: is there a way to fix this (no, I don't want to build each side of my room manually in the level editor by placing physic-using cubes all around it) or is there another possibility to check when I have to play a sound?
I can check collisions with other rigid-bodies, thats no problem, but when I want to check the "world" (thats the "collision-attribute" for all non-dynamical objects in my engine) then I'll become this "error".

I hope you understand what I mean and can help me!

Thanks for answers
codydbgt
Posts: 7
Joined: Fri Nov 05, 2010 4:25 am
Location: US
Contact:

Post by codydbgt »

ever tried your own colistion code like just for the things u want or talking about..........and i could help you if you posed some code.
HELLO LIKE TF2 THEN COME JOIN OUR SERVER GO TO http://steamcommunity.com/groups/TF2BMS ENJOY- multi sentry and 50+ mods- and i like to program!
serengeor
Posts: 1712
Joined: Tue Jan 13, 2009 7:34 pm
Location: Lithuania

Post by serengeor »

if you want to know when you're colliding with the mesh of the world, you make a collision shape of "btBvhTriangleMeshShape", then it will collide with the triangles of the mesh, instead of collision box.

Read more on http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=39007

It creates the map in the CPhysics constructor, so you'll have to rewrite what you need.

Hope I understood the problem.

And you should make some kind of variable, so you wouldnt play the sound every frame that it collides.
Working on game: Marrbles (Currently stopped).
cookie
Posts: 83
Joined: Sun Aug 23, 2009 9:30 pm

Post by cookie »

Thanks for the answers.

No, both of you didn't understand my problem :>

So here is an better description of my problem:

1. I've got a room. The room-node is given to irrBullet to create an IBvhTriangleMeshShape of it.

2. I add the attributes "collided" and "world" as bools to the room-rigid-body:

Code: Select all

rbody->getAttributes()->addBool("world", true);
    rbody->getAttributes()->addBool("collided",false);
collided is true when a collision with this attribute was detected else it will be false.
World is in every rigidbody which belongs to the static objects of the world.

3. The IBvhTriangleMeshShape was created and work, all movements of the rigid bodys are correct.

4. Now I want to check if there is a collision between a rigid-body and a rigid-body with the attribute world:

Code: Select all

if(rbody->hasCollidedWithAttribute("world"))
            {
                if(rbody->getAttributes()->getAttributeAsBool("collided") == false)
                {
                    rbody->getAttributes()->setAttribute("collided", true);
                   //here would be played the sound, but thats not my problem now ;)
                }
            }
            else
           {
                rbody->getAttributes()->setAttribute("collided", false);
         }
5. When I'm inside of the room with the attribute "world" the collision result will be true, although there isn't a collision with the "world" attribute.
The reason why irrbullet thinks there is already a collision is:
I'm inside of this room, so irrBullet thinks the rigidBodie already collided with it, so it shows me all the time there would be a collision...

Do you understand my problem now?
serengeor
Posts: 1712
Joined: Tue Jan 13, 2009 7:34 pm
Location: Lithuania

Post by serengeor »

Oh dang, this is irrBullet, no wonder why i havent found anything about getAttribute method on bullets API page :lol:

Can't help much with irrBullet, you should consider posting this in the irrbullets thread, maybe there you could get your answer quicker.
Working on game: Marrbles (Currently stopped).
cookie
Posts: 83
Joined: Sun Aug 23, 2009 9:30 pm

Post by cookie »

Cobra isn't avaible I think...because I wrote him a few days ago a PM and he didn't answer until now :0

But I've got an update for my problem, which is...bad...

I tried it again with this code:

Code: Select all

list<IRigidBody*>::Iterator current_body= dynamic_bodies.begin();
    for (; current_body !=dynamic_bodies.end();)
    {
            if((*current_body)->hasCollidedWithAttribute("world"))
            {
                if((*current_body)->getAttributes()->getAttributeAsBool("collided") == false)
                {
                    (*current_body)->getAttributes()->setAttribute("collided", true);
                    std::cout<<"collision!"<<std::endl;
                }
            }
            else
            {
                 (*current_body)->getAttributes()->setAttribute("collided", false);
                 std::cout<<NO collision!"<<std::endl;
            }
    }
The code checks all dynamic bodies in the dynamic_bodies list about a collision with the attribute "world" which is avaible in every static rigid body in my scene... but when I start my program, I see the first frame and then the programm doesn't want to continue... it plays the background sounds of the scene but I can't move and all the physics are frozen too... I _really_ don't know what the code above do that the program won't continue... the last message in my debugger is "collision!" so it seems that one collision was detected and then the program stopped to continue ._. maybe the first collision with the world objects hurt my programs feelings so hard that it refuse to going on in the code :D


I hope somebody can help me...

[EDIT]

Uh... it wasn't the collision on its self, I just forgot to write "++current_body" to continue in the loop >.<

[EDIT 2]

Hm...that's weird but now the collision detecting is working perfect ._.
Well, thanks for your help...the topic can be closed :D
cobra
Posts: 371
Joined: Fri Jan 23, 2009 2:56 am
Location: United States
Contact:

Post by cobra »

Hi cookie.

Sorry about the delayed response to your problem.


Anyway, I advise against using IRigidBody::hasCollidedWithAttribute().
I will probably remove it in the next irrBullet release.

0.1.7 is actually mature, and it has been for a while, so I'll probably get around to a release soon. I've been busy with others things and working on my game.


Here's the way you should handle your collisions:

Code: Select all

void ICollisionProcessor::processCollisions()
{
    irrBulletWorld* DynamicsWorld = FightersTW->getDynamicsWorld();
    for(int i=0; i < DynamicsWorld->getNumManifolds(); i++)
    {
        ICollisionCallbackInformation *info = 0;
        info = DynamicsWorld->getCollisionCallback(i);

        int numContacts = info->getPointer()->getNumContacts();
        for(int j=0; j < numContacts; j++)
        {
            if(verifyCollisionCallback(info))
            {
                if(info->getContactPoint(j).getDistance()<1.5f && info->getContactPoint(j).getLifeTime() < 2.0f)
                {
                    handleWeaponVersusTerrain(info, j);
                    handleChildObjectVersusTerrain(info, j);
                    handleChildObjectVersusWater(info, j);
                    handleMainObjectVersusTerrain(info, j);
                }
            }
        }
        info->getPointer()->clearManifold();
    }
}
Each function called in there with the beginning "handle" checks to see what type of objects are colliding (by checking attributes).

Good luck! :)
Josiah Hartzell
Image
cookie
Posts: 83
Joined: Sun Aug 23, 2009 9:30 pm

Post by cookie »

Okay, thank you.

Is there a way to check just for example my dynamic bodies, when I've got them in a list like the code a few posts above?
cobra
Posts: 371
Joined: Fri Jan 23, 2009 2:56 am
Location: United States
Contact:

Post by cobra »

cookie:

Either way you'd be cycling through all the collision manifolds and points, so it's best to do it the way I advised.
Josiah Hartzell
Image
cookie
Posts: 83
Joined: Sun Aug 23, 2009 9:30 pm

Post by cookie »

Allright, but whats happening in the functions with "handle" at the beginning?
... checks to see what type of objects are colliding (by checking attributes)
How do you do that?
cobra
Posts: 371
Joined: Fri Jan 23, 2009 2:56 am
Location: United States
Contact:

Post by cobra »

cookie:

Just use a switch-case or if statement to check attributes of types that you want to handle. You must first add these attributes when you create the rigid-body, or some time before you start trying to access them.

Code: Select all

if(info->getBody1()->getAttributes()->getAttributeAsInt("Type") == OT_WORLD_OBJECT)
Josiah Hartzell
Image
cookie
Posts: 83
Joined: Sun Aug 23, 2009 9:30 pm

Post by cookie »

Thank you.

So now 2 more questions:

What does the function "verifyCollisionCallback" do?

and

Which of the colliding bodys is info->getBody1, the one I check about collision or the body which collides with the body I'm checking? I think the one which I want to check...

Thanks for your help.
cobra
Posts: 371
Joined: Fri Jan 23, 2009 2:56 am
Location: United States
Contact:

Post by cobra »

verifyCollisionCallback() just checks the two bodies (info->getBody1() and info->getBody0()) to see if they both contain the attribute with the name "collide."


Also, you'll just have to check both of the bodies to find the attributes you want.

I think the way Bullet adds them is the object with the highest velocity might be getBody1(), but I'm not sure.

Anyway, just find the one with the right attribute, for instance weapon, and then handle it accordingly from there.
Josiah Hartzell
Image
cookie
Posts: 83
Joined: Sun Aug 23, 2009 9:30 pm

Post by cookie »

Allrigt, it works perfect :)

Thank you!

Only problem now: the sounds get played to often on every little movement of the rigid bodys, but I think I can fix this.
cobra
Posts: 371
Joined: Fri Jan 23, 2009 2:56 am
Location: United States
Contact:

Post by cobra »

cookie:

You need to set an attribute to false, and check to see if that's true before you register a collision.

For instance, add the attribute as a bool with the name "isDestroyed" and set it to true on collision.

Or set a "last collision" float attribute in the bodies, then on collide you can set that value to the timer's current time. Then if the time is, say, greater than lastCollisionTime + 2000, you could play the sound. If not, you would not play the sound.

Hope that works out for you.

- Josiah
Josiah Hartzell
Image
Post Reply