as you can see, I use following code to detect two object collision, I can see the objects collision in visual, but the object_recipient and object_sender are always NULL ? I see some other has the same code and config that works fine, did I miss something ?
And I try to trace the function, but the eventHandler seems to run from the beginning of program for many many times? I just create an object at the initial step, why there is a lot of physical events of orxPHYSICS_EVENT_CONTACT_ADD happened before I create another object?
[Tank1Body]
Dynamic = true
PartList = Tank1PartTemplate
[Tank1PartTemplate]
Type = box;
Friction = 0.0;
Restitution = 1.0;
Density = 1.0;
SelfFlags = 0x0001;
CheckMask = 0x0001;
Solid = true;
[Tank1]
Graphic = Tank1Graphic
Scale = 0.5
Body = Tank1Body
AnimationSet = AnimSet
Position = (0.0, 0.0, 0.0)
[BulletBodyPart]
Type = box;
Friction = 0.0;
Restitution = 1.0;
Density = 1.0;
SelfFlags = 0x0001;
CheckMask = 0x0001;
Solid = true;
[BulletBody]
PartList = BulletBodyPart
Dynamic = true; <= We use the same physical body than ground, except we are dynamic and not static
[Bullet]
Graphic = BulletGraphic
Body = BulletBody
Scale = 0.25
AnimationSet = BulletAnim
orxEvent_AddHandler(orxEVENT_TYPE_PHYSICS, Tank::eventHandler);
orxSTATUS orxFASTCALL Tank::eventHandler(const orxEVENT *_pstEvent)
{
if(_pstEvent->eType == orxEVENT_TYPE_PHYSICS) {
if( _pstEvent->eID == orxPHYSICS_EVENT_CONTACT_ADD ) {
/* Gets colliding objects */
orxOBJECT *object_recipient = orxOBJECT(_pstEvent->hRecipient);
orxOBJECT *object_sender = orxOBJECT(_pstEvent->hSender);
if (object_recipient != orxNULL && object_sender != orxNULL) {
/* Never run to here, as the pointers are always null */
string recipient_name(orxObject_GetName(object_recipient));
string sender_name(orxObject_GetName(object_sender));
if(recipient_name == "Tank1" && sender_name == "Bullet") {
orxObject_Delete(object_sender);
}
}
}
}
}
Comments
The fact you're having no recipient nor sender for your event makes me think it can be one of these two issues:
- You're compiling a release version and linking against a debug orx library, or vice-versa, as the macro orxOBJECT() is different in these two modes (in debug it does extra checking to make sure what you're casting actually is a orxOBJECT and not something else, whereas there's no check in release, faster but unsafe). Are the values of pstEvent->hRecipient/->hSender NULL before the macro-cast?
- the .h header files you're using as includes are not the same version as the orx library against which you're linking your program. In this case orxEVENT_TYPE_PHYSICS might not have the same value in both versions, which means you'd actually get another type of event when you expect a orxEVENT_TYPE_PHYSICS. That would also explain why you get the event fired multiple times at the beginning.
Before going any further I'd check which version you're using and be sure the .h and .lib/.so/.dylib are all from the same release version. Also, check you're using __orxDEBUG__ when linking against orxd.lib/liborxd.so/liborxd.dylib and that it's not defined when linking against orx.lib/liborx.so/liborx.dylib.
If you're not already using the SVN HEAD version, I advise you to use it instead of any official release as it's actually stable, include some fixes and improvements, and will be released as 1.3 (when I'm finished moving and I have my computers back).
Let me know if you still have issues.
After I update the orx lib to svn HEAD version, I tried again, this time the eventhandler function just run once after two object collision happened.
The NULL pointer problem seems to be caused by is these code :
the _pstEvent->hRecipient are not NULL, but object_recipient is NULL after execute the statement, I am not sure what orxOBJECT() have done, but I guess the hRecipient is an orxOBJECT * pointer, I convert the void * to orxOBJECT * forcedly. And now the pointer is not NULL any more. The following code works as I expected
As for the orxOBJECT() macro, I'm pretty sure it's a release/debug mismatch issue. I'd check that again if I were you.
What the macro does is check if the eID member of the orxSTRUCTURE matches the cast (orxSTRUCTURE_ID_OBJECT for orxOBJECT()). But to prevent false positive in debug, it also use a magic number XORed to validate the eID (0xDEFACED0 is the magic number).
However, in release this magic number is 0, which allows the compiler to remove the XOR instruction for faster processing. As a result, the cast is not validated and is less safe.
Now if you compile in debug and link against a release, or vice-versa, the magic number won't match both sides and the result won't be validated. Which means the cast will then return orxNULL.
That beind said, your code above works but is less safe than using the macro orxOBJECT(). Well, in this case it doesn't matter much as you know that the event recipient and sender can only be orxOBJECTs.
As for the west coast, everything's great so far but I can't wait to get out of the hotel and finally have all our stuff back!