Simple collision detection with Ogrenewt

l34ndr4

25-02-2006 03:04:24

hi,
I have a problem with ogrenewt
it works find and the fisics are great but
I wanted to use it for collision detection,
I have search the examples and didnt find a simple example for this
, I search the forums for this and it says to use the namespace
OgreNewt::CollisionTools and I tried to use some functions in there
but didnt have sucess. SO I was wondering if someone can give me a simple example of a collision detection.

thx in advance.

misterface

25-02-2006 21:56:19

was in the same situation a while ago...
try demo1 and demo5.

I found/find those very helpfull!!

l34ndr4

26-02-2006 05:27:46

hi,
thx for answering,
well I looked at those examples
and yeah they show you how to create different types of collision bodys
and how you can control them,
but what I really want is to detect the collision between 2 objects
Example:
imagine you have a Car and a wall , well the car collides with
the wall and I want to know with whom it collides and that it returns me the body of the wall so I can decrement the life of the car.

if u know how pls help me out, cause I cant continue with my game cause
the logic of the game starts there.
:?

walaber

26-02-2006 07:32:35

if you just want to use Newton for collision detection (and NOT physics), use the collision tools functions I mentioned.

if you want the physics TOO, you need to look at the contactCallback system. it is a very powerful system that will notify you when objects collide. basically you create materials, and then choose to be notified when bodies of certain materials interact. inside the callback you get pointers to the 2 specific bodies that are colliding.

l34ndr4

26-02-2006 11:54:25

hi,
thx for answering
I have looked the examples and it looks like
the Demo 3 implements it,
but Im a little Newb, so I dont understanded well
is this the function
that checks the 2 bodys ?
int conveyorMatCallback::userProcess()
{
// first, find which body represents the conveyor belt!
conveyorBelt* belt;
OgreNewt::Body* object;

if (m_body0->getType() == mConveyorID)
{
belt = (conveyorBelt*)m_body0->getUserData();
object = m_body1;
}

if (m_body1->getType() == mConveyorID)
{
belt = (conveyorBelt*)m_body1->getUserData();
object = m_body0;
}

if (!belt) { return 0; }

// okay, found the belt... let's adjust the collision based on this.
Ogre::Vector3 thedir = belt->getGlobalDir();

rotateTangentDirections( thedir );
Ogre::Vector3 result_accel = (thedir * belt->getSpeed()) - object->getVelocity();
setContactTangentAcceleration( result_accel.length(), 0 );


return 1;
}

if not , can u explain it a little bit more cause it dont get to well
about the conveyorBelt.
thx.
PS: how can I put 2 objects with the same material ?

walaber

26-02-2006 18:56:43

quick explanation. you create a material, let's call it "boxMaterial". let's say you have 2 bodies that you make, and you set them both to this material.

then you make a contactCallback, and assign that callback for interactions of boxMaterial vs. boxMaterial.

now, in your callback you have 3 functions:
userBegin()
userProces()
userEnd()

let me explain them.

when you call NewtonUpdate(), it moves bodies according to the forces acting on them. then it checks to make sure nothing is colliding. now let's say it finds that your 2 bodies are likely to collide (their bounding boxes are intersecting).

first, it calls userBegin() to let you know that there is a good chance that the 2 bodies will collide. at this point it tells which 2 bodies it is talking about, and the m_Body0 and m_Body1 members of the contactCallback class are valid. at this point you can do some checks, and if you want to allow the collision, you return 1 from the function. if you want to let Newton know its OK to ignore the collision, you return 0.

okay, so let' assume you've returned 1 from begin(). now Newton will calculate the actual contact between the 2 bodies, and for each discreet contact between them, it will call userProcess(). in this function all of the member functions are available, so you can determine the location, normal, speed, etc.. of the contact.

you can also return 0 or 1 to tell Newton to ignore or apply this contact.

finally after all contacts have been processed, Newton calls the userEnd() function, to give you a chance to act one last time, now that you have had a chance to gather all of the data about the collision.



so generally the idea is to use userBegin() and userProcess() to gather data about the collision (and possibly choose to ignore the collision), and then use userEnd() to act on that data, by playing a sound effect, or spawning particle effects, etc.


anyway, you get 2 pointers to the 2 bodies interacting from the start (userBegin()), so you can determine what to do from there.

you'll see that in userProcess() I check the ID (an int value) of the bodies to figure out which one is the conveyor belt. you can do something imilar yourself to determine which bodies are interacting.

l34ndr4

27-02-2006 15:01:49

Thx
I tried it and thats what I need it
:D:D:D
thx for the explanation now Ill start playing with newton.
:D

darkdragon

30-04-2006 04:14:27


so generally the idea is to use userBegin() and userProcess() to gather data about the collision (and possibly choose to ignore the collision), and then use userEnd() to act on that data, by playing a sound effect, or spawning particle effects, etc.

Execuse me.
I have a problem on here.
That is the userEnd() always seems to be active.
In other words, if I put the particle effects in the userEnd() and generate the object, particle system will act at the first, not after colliding.
Is it right?
Or I have something wrong on here.

walaber

30-04-2006 04:51:53

userEnd() is called even when only the AABB of the 2 bodies collides, not a *true* collision.

here are the 3 possible scenarios:

1) the bodies AABB never overlap:
nothing is called.

2) The bodies AABB overlap, but the actual bodies are not called.
userBegin()
userEnd()

3) The bodies physically collide
userBegin()
userProcess() <- once for each contact.
userEnd()


so you can see that if you want to do something only when a "true" collision has occured, you need to flag that in the userProcess() function. then check in userEnd() if it was a true collision, and if it was, make your particles, etc.

darkdragon

30-04-2006 05:39:21

Thanks!
I see. :D

helloween

14-05-2006 14:24:08

Hi,

I would like to know if an object, lets say a ball, appears completly inside a second bigger ball, so that even the bouding boxes are not colliding, will this collision will be notice and reported with a callback ?
Because I really need this for my project, I m using a collision detection library for now but it doesn't report this kind of collisions.

thanks

walaber

15-05-2006 17:57:53

i don't think newton provides a way to tell if 1 collision volume is entirely inside another.

helloween

15-05-2006 22:26:27

well, I tested and it seems to work :)
I made a collision pair between 2 objects and the callback tells me when the object is inside the other one, that's weird because uselly collision detection is based on the borders of a shape :?: