Right, now this is starting to ring some bells... I had collision callbacks working fine in PhysX 2.x, but do remember taking one look at the new system in 3.x and deciding to come back to that later.

But "later" is now, so... gave it a pretty good try last night. It seems like I did all the things I should have to do, but am still failing to get a call to my onContact() function.
What I did:
1) Added inheritance from PxSimulationEventCallback to my Px3World class, like so:
Code: Select all
class Px3World : public PhysicsWorld, public physx::PxSimulationEventCallback
2) Added the following function definitions/declarations to keep up with the virtuals:
Code: Select all
virtual void onContact(const physx::PxContactPairHeader& pairHeader, const physx::PxContactPair* pairs, physx::PxU32 nbPairs);
virtual void onTrigger(physx::PxTriggerPair* pairs, physx::PxU32 count) {}
virtual void onConstraintBreak(physx::PxConstraintInfo*, physx::PxU32) {}
virtual void onWake(physx::PxActor**, physx::PxU32) {}
virtual void onSleep(physx::PxActor**, physx::PxU32) {}
3) Defined a new filterShader function, like so:
Code: Select all
static physx::PxFilterFlags MegamotionFilterShader(
physx::PxFilterObjectAttributes attributes0,
physx::PxFilterData filterData0,
physx::PxFilterObjectAttributes attributes1,
physx::PxFilterData filterData1,
physx::PxPairFlags& pairFlags,
const void* constantBlock,
physx::PxU32 constantBlockSize)
{
pairFlags = physx::PxPairFlag::eCONTACT_DEFAULT;
// trigger the contact callback for pairs (A,B) where
// the filtermask of A contains the ID of B and vice versa.
if ((filterData0.word0 & filterData1.word1) || (filterData1.word0 & filterData0.word1))
{
pairFlags |= physx::PxPairFlag::eNOTIFY_TOUCH_FOUND;
return physx::PxFilterFlag::eNOTIFY;
}
return physx::PxFilterFlag::eDEFAULT;
}
You may note that I changed the SampleSubmarine version of this from a && to a || when it comes to the word0/word1 bit, because I am only telling my rockets to respond to the rest of the world, but not bothering to tell the rest of the world they have to respond to rockets. That seemed a little silly, and it seemed like right here was the only place it mattered... but I also tried just setting the filterShader up to send an eNOTIFY every damn time no matter what, and still didn't get any response.
4) Attached that filterShader to my sceneDesc object, like so:
Code: Select all
sceneDesc.filterShader = MegamotionFilterShader;
5) Added a new category to the Px3CollisionGroup enum, to cover my explosive objects:
Code: Select all
enum Px3CollisionGroup
{
PX3_DEFAULT = BIT(0),
PX3_PLAYER = BIT(1),
PX3_DEBRIS = BIT(2),
PX3_TRIGGER = BIT(3),
PX3_EXPLOSIVE = BIT(4),
};
6) Assigned my rocket shapes to have that collision group as word0, and PX3_DEFAULT as word1.
7) Defined my onContact function in Px3World.cpp, for starters just to try to kick out a console message to let me know we're getting anything:
Code: Select all
void Px3World::onContact(const physx::PxContactPairHeader& pairHeader, const physx::PxContactPair* pairs, physx::PxU32 nbPairs)
{
Con::printf("WE HAVE A CONTACT!!!");
for (physx::PxU32 i = 0; i < nbPairs; i++)
{
const physx::PxContactPair& cp = pairs[i];
if (cp.events & physx::PxPairFlag::eNOTIFY_TOUCH_FOUND)
{
Con::printf("WE HAVE A ROCKET CONTACT!!!");
}
}
}
Now, given all of the above, I would presume that whenever my filter shader sets a pair flag to eNOTIFY_TOUCH_FOUND, and/or (?) returns a value of eNOTIFY, that my onContact function should get a callback.
So far, no dice. Anything you can see that I might have missed?