irrBullet - rigid bodies reacting on fired bullet

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.
cookie
Posts: 83
Joined: Sun Aug 23, 2009 9:30 pm

irrBullet - rigid bodies reacting on fired bullet

Post by cookie »

Hi,

does somebody know, how I let rigid bodies react on fired bullets of my weapon? Something like "add an impulse at one position (where the bullet hit the object) and let all bodies, which where hit by the bullet, move"
I can't explain it better but I think you know what I want :?
Iyad
Posts: 140
Joined: Sat Mar 07, 2009 1:18 am
Location: Montreal, Canada

Post by Iyad »

Code: Select all

void  applyImpulse (const btVector3 &impulse, const btVector3 &rel_pos) 
This was taken from the btRigidBody class, impulse is the direction of the shot, and rel_pos is the position where you hit. I never tryed this, but it should work. Hope this help.
#include <Iyad.h>
Iyad
Posts: 140
Joined: Sat Mar 07, 2009 1:18 am
Location: Montreal, Canada

Post by Iyad »

Oh srry, this was not from the Irrbullet wrapper. But looks like Irrbullet also have the function which is in IRigidBody class, the method is :

Code: Select all

void applyImpulse(const irr::core::vector3df &impulse, const irr::core::vector3df &relPos, ERBTransformSpace transformSpace=ERBTS_WORLD);
#include <Iyad.h>
cookie
Posts: 83
Joined: Sun Aug 23, 2009 9:30 pm

Post by cookie »

ok...thanks. But now I've got a problem: I know the nodes which belongs to the rigid bodies but I don't have a pointer for them. It means that I can't call the addImpulse function directly, I have to get the pointer for the rigid body, which get hit of the bullet but for the scene nodes there isn't a method like "getRigidBody". The rigidBodies have a method called "getNode" or something like this... do I have to save the pointer of every created rigid Body or is there another way?
Iyad
Posts: 140
Joined: Sat Mar 07, 2009 1:18 am
Location: Montreal, Canada

Post by Iyad »

I dont use IrrBullet so i dont know how it manages rigid bodys. But what i suggest you is to make a dynamic array, where you store your rigid bodys in, and where you can call them when ever you need them.
#include <Iyad.h>
serengeor
Posts: 1712
Joined: Tue Jan 13, 2009 7:34 pm
Location: Lithuania

Post by serengeor »

I think it has a list of them just look for it hard
because irrbullet has to have all of the pointers so it can update every nodes position translation ect.
Working on game: Marrbles (Currently stopped).
cookie
Posts: 83
Joined: Sun Aug 23, 2009 9:30 pm

Post by cookie »

Hmm... does somebody know how I can check if a rigid body collided with another rigid body?
serengeor
Posts: 1712
Joined: Tue Jan 13, 2009 7:34 pm
Location: Lithuania

Post by serengeor »

cookie wrote:Hmm... does somebody know how I can check if a rigid body collided with another rigid body?
Theres 'no' function for that.
you should use this code i think(unless irrBullet has this implemented)

Code: Select all

const int numManifolds = collisionWorld->getDispatcher()->getNumManifolds();
	
	int i;
	for (i=0;i<numManifolds;i++)
	{
		int id[2];
		id[0]=id[1]=-1;
		btPersistentManifold* contactManifold = collisionWorld->getDispatcher()->getManifoldByIndexInternal(i);
		btCollisionObject* obA = static_cast<btCollisionObject*>(contactManifold->getBody0());
		btCollisionObject* obB = static_cast<btCollisionObject*>(contactManifold->getBody1());
		
	}
obA, obB are two coliding bodies you could put 'if' statement's in the for loop to check if they are the objects you need, or you could put every object into a list and than make a function that would do that :wink:
Working on game: Marrbles (Currently stopped).
cookie
Posts: 83
Joined: Sun Aug 23, 2009 9:30 pm

Post by cookie »

Umm... could you explain me, what happens in this piece of code?
cobra
Posts: 371
Joined: Fri Jan 23, 2009 2:56 am
Location: United States
Contact:

Post by cobra »

Hi.

You do need to use manifolds (in irrBullet I call this ICollisionCallback so that beginners can understand it more easily) for collision callbacks.

Also check in irrBullet "ICollisionObject::hasCollidedWithAttribute(attributeName)" and ICollisionObject::getAttributes() to add a new attribute.

This isn't the fastest way; I recommend using the manifolds (this is how I do it in my own game using irrBullet).

If you have irrBullet 0.1.6, you can see the irrBulletTest's code for both collision detection ways! I will make this an actual collision example in the next release. (I will have lots of new examples in this release in fact!)

Also, comparing a rigid body's scene node with the scene node hit in the ray would be the best way for now (although not the fastest).

Bullet has internally a ray cast method. I'll work on developing an interface for this, but I have a lot of things to do such as working on my game, my game's tools, irrBullet, teaching C++, and school.
Josiah Hartzell
Image
cookie
Posts: 83
Joined: Sun Aug 23, 2009 9:30 pm

Post by cookie »

Code: Select all

for(int i=0; i < worldp->getNumManifolds(); i++)
        {
            ICollisionCallbackInformation *info = worldp->getCollisionCallback(i);

            bool hasCollidedAttribute = (info->getBody0()->getAttributes()->existsAttribute("collided"));
            ICollisionObject* obj = (hasCollidedAttribute==true) ? info->getBody0() : info->getBody1();

            if(obj->getAttributes()->getAttributeAsBool("collided") == true)
            {
                obj->getAttributes()->setAttribute("collided", false);
                worldp->addToDeletionQueue(obj);
            }
        }
Is this the line for collision detection? If this is it can you explain me where there is a collision detection? ._.
d3jake
Posts: 198
Joined: Sat Mar 22, 2008 7:49 pm
Location: United States of America

Post by d3jake »

The detection happens before that code is reached. After it has been, the collision(s) are held in a list (or vector, I don't know) that you access through world->getCollisionCallback(unsigned int). If you look at the API, and that example that you posted you can find what kind of information you can pull about the collision. Also, that snippet of code you posted shows how to retrieve pointers of the rigid bodies that collided.
The Open Descent Foundation is always looking for programmers! http://www.odf-online.org
"I'll find out if what I deleted was vital here shortly..." -d3jake
cookie
Posts: 83
Joined: Sun Aug 23, 2009 9:30 pm

Post by cookie »

d3jake wrote:If you look at the API, and that example that you posted you can find what kind of information you can pull about the collision.
I can't find anything in the API about this Oo
cookie
Posts: 83
Joined: Sun Aug 23, 2009 9:30 pm

Post by cookie »

Sorry for doublepost!

Code: Select all

list<IRigidBody*>::Iterator current_body = bullets.begin();
    for (; current_body != bullets.end(); ++current_body)
    {
        if((*current_body)->getAttributes()->existsAttribute("bullet") && (*current_body)->hasCollidedWithAttribute("world"))
            {
                if((*current_body)->getAttributes()->getAttributeAsBool("collided") == false)
                {
                    (*current_body)->getAttributes()->setAttribute("collided", true);
                    std::cout<<"COLLISION!!1"<<std::endl;
                }
            }
    }
This is my actual code to detect collision between bullets and rigidBodies. I save the bullets in a list and check them if they collided with an rigid body with the attribute "world". When I just check the dynamic objects (which stands around in my world) for collision, all works fine. But when I check the static objects, like the room I'm walking while the game is running, I get the message "COLLISION!!1" not in the moment when the bullet hits the body, I get this message directly after creating the bullet... I don't know why but I think it is because the room, I'm walking in is an dynamic body and the engine thinks I already hit the body...
cobra
Posts: 371
Joined: Fri Jan 23, 2009 2:56 am
Location: United States
Contact:

Post by cobra »

cookie:

Code: Select all

if(info->getContactPoint(0).getDistance()<0.f)
You can also get how hard it hit with this:

Code: Select all

info->getContactPoint(0).getAppliedImpulse()
This gets the first contact point. Sometimes there are multiple contact points in one manifold. You can also step through each contact point, but I usually only take the first one.

What's more, collisions are registered once an object begins to enter the Axis-Aligned Bounding Box of another object. That's why it's registering the collision between your bullet and the enclosed map/level.

This is generally fine for quick collisions for objects whose AABB actually covers only what's collideable, but for levels this isn't the case, so you need to check distance to be sure.
Josiah Hartzell
Image
Post Reply