Game Development Community

Collision Event for PhysX objects

by A F · in Torque 3D Professional · 04/23/2012 (6:23 pm) · 2 replies

I wanted to make a function run in Torque Script when a PhysicsShape collides with another object.

I made a function like the players onCollision function for physicsShapeData but this is never called.

I looked through the c++ code and I can see that the onCollision call back that the player uses is created in shapeBase.cpp.

PhysicsShape inherits from gameBase, not shapeBase, so there is no code that would run the onCollision function in torque script for the physicsShape.

The collisions are already happening, physicsShapes bounce around, I don't want to create my own ray casts to figure out when the physicsShape collides, I would like to use the physX code to figure out when to raise my event in torque script.

From what little I've seen about setting this up for PhysX, you need to create a new class that inherits from NxUserContactReport.

This is already done in T3D in pxContactReporter.h

pxContactReporter.cpp has
void PxContactReporter::onContactNotify( NxContactPair &pair, NxU32 events )
which is the function that physX should run to determine the collisions, but this function never runs for me.

Do I have to manually run the onContactNotify function, or do I need to register the individual physX objects I want to be notified?


Has anyone seen this work in T3D?

#1
04/23/2012 (10:18 pm)
Not any progress but this is where I am at and some of the things I've found.
All this information I can find is basically the same.

This post from 2008: http://www.gamedev.net/topic/482784-physx-collision-detection/

define a class that derives from NxUserContactReport, and that over-rides the function "void onContactNotify (NxContactPair& pair, NxU32 events)"
This is already done in pxContactReporter.h and pxContactReporter.cpp.

call NxScene::setUserContactReport and pass it a pointer to an instance of the class you created
This is already done in pxWorld.cpp with this code:
mConactReporter = new PxContactReporter();
mScene->setUserContactReport( mConactReporter );

After this, you must specify for which actors you want to receive contact reports. 
You can either explicitly set pairs of actors with NxScene::setActorPairFlags, 
or set pairs of actor groups using NxScene::setActorGroupPairFlags
This is where I think the problem is. There are quite a few examples of doing this on the internet, but they are using a simple example, not something like the T3D engine.

here is a simplified version:
gScene = gPhysicsSDK->createScene(sceneDesc);
...
NxActorDesc BoxActorDesc
...
PhysXBox1 = gScene->createActor(BoxActorDesc);
PhysXBox2 = gScene->createActor(BoxActorDesc);
...
gScene->setActorPairFlags(*PhysXBox1, *PhysXBox2, NX_NOTIFY_ON_TOUCH);

I presume this will run the PxContactReporter::onContactNotify function if PhysXBox1 collides with PhysXBox2. If this is the case, this would need to be run for every combination of objects in your scene, which seems a bit crude for 100s of objects.

The alternative method is the setActorGroupPairFlags which looks more promising.

This function is given 2 groups of objects to check collisions against.

The questions I have now are, what groups are already used, where is a good place to assign groups, and where is a good place to run the setActorGroupPairFlags function?







#2
04/23/2012 (11:45 pm)
I found a solution, it may not be the best way, but it works.

All physx objects are in group 0 by default.
Players are put in group 29 with this line in pxPlayer.cpp
kineActor->setGroup( 29 );

I thought that triggers were in group 30 and debris 31 but this is not the case. They are in different groups types with these numbers (its confusing) but debris is not in group 31 for group collision reporting.

I can't see any other group numbers being used (although they may be there somewhere).

In pxWorld.cpp inside
bool PxWorld::_init( bool isServer, ProcessList *processList )
there is some setup code for physX.

At the bottom of the function I put
mScene->setActorGroupPairFlags(0,0,NX_NOTIFY_ON_START_TOUCH | NX_NOTIFY_ON_END_TOUCH);

This then triggered the
void PxContactReporter::onContactNotify( NxContactPair &pair, NxU32 events )
function when physicsShape objects first hit, and stopped hitting each other.