Фильтрация столкновений со слоями (PhysX 3.4)
Я хотел бы отфильтровать свои столкновения со слоями, как в Unity, но я действительно не понимаю, как это сделать. Я следую этому руководству: http://docs.nvidia.com/gameworks/content/gameworkslibrary/physx/guide/Manual/RigidBodyCollision.html
Все, что я хочу сделать, это отключить столкновения между объектами, которые имеют слой Cube и 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);
/*...*/
}
А вот как я устанавливаю фильтр шейдера:
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;
}
С этим кодом ни один из моих объектов не сталкивается... Я действительно не понимаю, что такое PxFilter.word0, word1 word2 и word3, кстати...
Заранее спасибо!
1 ответ
Это очень поздний ответ, просто ссылка для других.
На основании документации nvidia вы должны вернуть eSupress или убить enum.https://docs.nvidia.com/gameworks/content/gameworkslibrary/physx/apireference/files/structPxFilterFlag.html :
PxFilterFlags PhysicsWorldFilterShader(
PxFilterObjectAttributes attributes0, PxFilterData filterData0,
PxFilterObjectAttributes attributes1, PxFilterData filterData1,
PxPairFlags& pairFlags, const void* constantBlock, PxU32 constantBlockSize
)
{
// Checking if layers should be ignored
auto const layerMaskA = filterData0.word0;
auto const layerA = filterData0.word1;
auto const layerMaskB = filterData1.word0;
auto const layerB = filterData1.word1;
auto const aCollision = layerMaskA & layerB;
auto const bCollision = layerMaskB & layerA;
if (aCollision == 0 || bCollision == 0)
{
return PxFilterFlag::eSUPPRESS;
}
// all initial and persisting reports for everything, with per-point data
pairFlags = PxPairFlag::eSOLVE_CONTACT | PxPairFlag::eDETECT_DISCRETE_CONTACT | PxPairFlag::eTRIGGER_DEFAULT;
return PxFilterFlag::eDEFAULT;
}