How to filter collisions with layers ? (PhysX 3.4)

Hi everyone,

I would like to filter my collisions with layers like in Unity, but I really don’t understand how to do it. I’m following this tutorial : http://docs.nvidia.com/gameworks/content/gameworkslibrary/physx/guide/Manual/RigidBodyCollision.html#collision-filtering
All I want to do is disable the collisions between the objects that have the layer Cube and Plane…

Graph.cpp :

bool Graph::Init()
{
/*...*/

        cubeCollider->SetLayer(Physics::PhysicLayer::Cube);
	planeCollider->SetLayer(Physics::PhysicLayer::Plane);
	sphereCollider->SetLayer(Physics::PhysicLayer::Sphere);
	capsuleCollider->SetLayer(Physics::PhysicLayer::Capsule);

	_physX->SetCollisionFiltering(Physics::PhysicLayer::Cube, Physics::PhysicLayer::Plane);

/*...*/
}

And here is how I set the filter shader :

PhysX.cpp :

void PhysX::SetCollisionFiltering(PhysicLayer p_one, PhysicLayer p_two)
{
// I don't really know what to do here...

	PxFilterData filterData;

	filterData.word0 =  p_one;
	filterData.word1 =  p_two;

	// no collision between objects with layer ONE and objects with layer TWO ? 
	for (unsigned int i = 0; i < _colliders.size(); ++i)
	{
		if (_colliders[i]->GetLayer() == p_one || _colliders[i]->GetLayer() == p_two)
			_colliders[i]->GetShape()->setSimulationFilterData(filterData);
	}
}

physx::PxFilterFlags CreateFilterShader(PxFilterObjectAttributes p_attributes0, PxFilterData p_filterData0, 
										PxFilterObjectAttributes p_attributes1, PxFilterData p_filterData1, 
										PxPairFlags& p_pairFlags, const void* p_constantBlock, PxU32 constantBlockSize)

{
        // Trigger
	if (PxFilterObjectIsTrigger(p_attributes0) || PxFilterObjectIsTrigger(p_attributes1))
	{
		p_pairFlags = PxPairFlag::eDETECT_DISCRETE_CONTACT
			| PxPairFlag::eSOLVE_CONTACT
			| PxPairFlag::eNOTIFY_TOUCH_FOUND
			| PxPairFlag::eNOTIFY_TOUCH_LOST;
	}
        // Normal Collision
	else
	{
                //  Not sure
		if ((p_filterData0.word0 & p_filterData1.word1) && (p_filterData1.word0 & p_filterData0.word1))
		{
			p_pairFlags = PxPairFlag::eDETECT_DISCRETE_CONTACT
				| PxPairFlag::eSOLVE_CONTACT
				| PxPairFlag::eNOTIFY_CONTACT_POINTS
				| PxPairFlag::eNOTIFY_THRESHOLD_FORCE_FOUND
				| PxPairFlag::eNOTIFY_THRESHOLD_FORCE_LOST
				| PxPairFlag::eNOTIFY_THRESHOLD_FORCE_PERSISTS

				| PxPairFlag::eNOTIFY_TOUCH_FOUND
				| PxPairFlag::eNOTIFY_TOUCH_LOST
				| PxPairFlag::eNOTIFY_TOUCH_PERSISTS;
		}
	}

	return PxFilterFlag::eDEFAULT;
}

With this code, none of my objects collide… I don’t really understand what are PxFilter.word0, word1 word2 and word3 by the way…

Thanks in advance !

It really all depends on the values of p_one and p_two.

Let’s just think about the following bitwise compare that you coded up: (p_filterData0.word0 & p_filterData1.word1)

If you set filterData.word0 to be p_one for all actors and filterData.word1 to be p_two for all actors then we have the following: p_one & p_two

I don’t know the values of p_one and p_two but if p_one has value 1 and p_two has value 2 then p_one & p_two will resolve to zero and collision will be rejected. The result of the bitwise operation really depends on the values p_one and p_two and that isn’t clear from the code you posted.

PxFilterData is just a data structure containing four 32-bit integers. That’s a total of 128 bits to set any way you want. You can encode these 128 bits with flags, types, scene pointers, ids of associated class instances etc. You can literally put anything you want in there. You can then write your own filter shader that uses your knowledge of the layout of those 128 bits. filterData.word0 etc have no actual meaning - they only mean what you want them to mean. It’s entirely up to you. The only meaning they have is that they will be passed to your filter shader and can be used to accept or reject shape pairs using custom logic.

You can do more than just accept or reject shape pairs, though. The idea here is that you set PxPairFlag as you want it to be set. If you look at the filter data and decide that you want to detect and resolve contact then you would set PxPairFlag::eDETECT_DISCRETE_CONTACT | PxPairFlag::eSOLVE_CONTACT. If you wanted to track contact points on, say, the player then you might encode the player’s filter data with a special flag and then set PxPairFlag::eNOTIFY_CONTACT_POINTS every time either of the shapes is a player. You can set any PxPairFlag in any combination you like using any logical combination of both filter data values.