[BloodyMess 1.5.4] Callbacks! Im really confused!

Kalgar

02-07-2009 08:35:45

Hey all,

I've been trying to read up on how to do the callback functions on collisions between objects (so that I can intervene and do things like reduce health, etc). However, I can't seem to find anywhere on these forums (or elsewhere) where there's a clearly explained way to do this. All I've been able to find is multiple threads of people trying things like this, and disjointed pieces of code, which mean very little to me :?

I'm amazingly confused by all of this, is there a chance one of you could explain it to me? I've spent the better part of two hours searching around for this!

Thanks,
~Kalgar

Karan

02-07-2009 09:34:19

Haven't done it myself yet, but I plan to do that using the PhysX functions directly as described in the PhysX SDK Documentation under Guide->Collision Detection->Contact Reports. There's also some example code.

spacegaier

02-07-2009 09:48:03

As far as I know, there isn't any collision code in BloodyMess in yet. Hopefully that will come in the next ime. However, there are only volumes / triggers so far, but very likely, they aren't appropriate for your needs. So currently you have to do it yourself (Karan pointed out how).

betajaen

02-07-2009 09:54:49

I haven't written the wrapping code for collision callbacks yet, I'm afraid.

However; if you need it now - You can mix PhysX code with BloodyMess code, and the NxScene and NxActors are accessible in the appropriate classes.

Benjiro

02-07-2009 12:15:21

I'll help you about abit, like betaJ said above you can access physx through nxogre you just need to include the physx header and libs

basicly you need to set a contact report with scene
mNxOgreScene->getScene()->setUserContactReport(new myContactReport());

Then you need to set up a contact reporter class

class myContactReport : public NxUserContactReport
{
void onContactNotify(NxContactPair& pair, NxU32 events)
{
//Stream iterator is away of getting what pairs collided and were
NxContactStreamIterator i(pair.stream);
// Read the Physx Doc about this, its pretty logical
while(i.goNextPair())
{
while (i.goNextPatch())
{
while(i.goNextPoint())
{
}
}
}
}
};


inside that contract report you want can do what ever you want with the pairs that caused a contact

to check if say a player made contact with say a ramp it would be like


if(pair.actors[0]->userData ==(Void*)mPlayer) //Userdata is basicly a null pointor you can assign anything to idenifiy it
{
NxActor *player = pair.actors[0];
NxActor *ramp= pair.actors[1];
//do stuff ^^
}


Hope that helps you

betajaen

02-07-2009 13:52:01

What Benjiro said.

However; In 1.5.5 (and I think 1.5.4) I use the NxOgre "PhysXPointer" class casted as a void* in the userData of NxActors. Which is a bit like an Ogre::Any. It's more safer and has some good casting functions, and even gives you what type of pointer is stored in there.

Benjiro

02-07-2009 14:07:17

from the top of my head i think i just accessed the NxActor through NxOgre Actor and set the userdata to be a (void*) of the object


NxActorName->getNxActor()->userdata


i think its something along the lines of that

Kalgar

02-07-2009 15:02:34

OK, I'll give it a run.

Thanks a lot! :)

~Kal

EDIT:

So I have something basic working.


class myContactReport : public NxUserContactReport
{
void onContactNotify(NxContactPair& pair, NxU32 events)
{
//Stream iterator is away of getting what pairs collided and were
NxContactStreamIterator i(pair.stream);
// Read the Physx Doc about this, its pretty logical
while(i.goNextPair())
{
cout << "Collision between actors!" << endl;
cout << "Moving actor1 upwards!" << endl;
pair.actors[0]->setGlobalPosition(NxVec3(0, 10, 0));
while (i.goNextPatch())
{
while(i.goNextPoint())
{
}
}
}
}
};


So basically it just picks whatever happens to be the first object in the pair and teleports it to (0, 10, 0) (which has hilarious results in my program). Obviously this is very rudimentary, but its a start!

However, part of Benjiro's post bothered me... pretty much just the if statement part.
I can't really test it in my current program (due to it being 2 files, one being the contact report and the other being a main.cpp with the rest of the nx stuff - this is a small test program for me to learn how this stuff all works before implementing it in a game), but if I understand it right, the if statement works if I create say, a Player class, and pass the player's collision actor to it?
Or am I misinterpreting the concept of the userdata member?

Thanks a lot for the help so far, you all made me so, so happy :)
~Kalgar

Pans

23-07-2009 01:28:10

Just as a heads up to anyone who tries this out, contact reports between actors are not set to occur by default (at least, they weren't for me when I did all of the above). I struggled with this for a bit, but then went to the source for PhysX's example of contact reports. You've gotta set something like

mScene->getScene()->setActorGroupPairFlags( mCube->getNxActor()->getGroup(), mCubeTwo->getNxActor()->getGroup(), NX_NOTIFY_ON_START_TOUCH|NX_NOTIFY_ON_TOUCH|NX_NOTIFY_ON_END_TOUCH);


to get your onContactNotify() to fire. You can extrapolate from the code above what you need to do to get different types of touch to notify you. Also note that the above code will set contact reports to fire for any objects of those two group types (in this case, they were of the same group), but you can do it for individual actors as well using setActorPairFlags().