tancen
(tancen)
September 15, 2021, 3:05pm
1
I have a class MyContactModifyCallback, which inherits PxContactModifyCallback, I don’t know how to make it work in the ue4 project.
class MyContactModifyCallback : public PxContactModifyCallback
{
public:
virtual void onContactModify(PxContactModifyPair* const pairs, PxU32 count)
{
UE_LOG(LogTemp, Error, TEXT("bbbbbbbbbbb"))
for (PxU32 i = 0; i < count; i++)
{
auto p = pairs[i];
for (PxU32 j = 0; j < p.contacts.size(); j++)
p.contacts.ignore(j);
}
}
};
I tried to set it like this in GameMode.InitGame, but it didn’t work.
void AtestGameMode::InitGame(const FString& MapName, const FString& Options, FString& ErrorMessage)
{
AGameModeBase::InitGame(MapName, Options, ErrorMessage);
auto s = this->GetWorld()->GetPhysicsScene();
printf("%p", s);
s->GetPxScene()->setContactModifyCallback(new MyContactModifyCallback());
}
Emaer
(Emaer)
September 16, 2021, 9:57am
3
Im not too familiar with PhysX, but docs say:
You can enable the use of this contact modification callback by raising the flag [PxPairFlag::eMODIFY_CONTACTS] in the filter shader/callback (see
PxSimulationFilterShader] for a pair of rigid body objects.
PhysX doc
tancen
(tancen)
September 16, 2021, 1:21pm
4
Thanks, But I still don’t know how do I get it to work in UE4
tancen
(tancen)
September 27, 2021, 1:40pm
5
Finally, I find a way to make it worked.
// Fill out your copyright notice in the Description page of Project Settings.
#pragma optimize("", off)
#include "MyWorldSettings.h"
#include <PhysXPublicCore.h>
#include "Physics/PhysicsFiltering.h"
PxFilterFlags PxSimulationFilterShaderProc(PxFilterObjectAttributes attributes0, PxFilterData filterData0,
PxFilterObjectAttributes attributes1, PxFilterData filterData1,
PxPairFlags& pairFlags, const void* constantBlock, PxU32 constantBlockSize)
{
pairFlags = physx::PxPairFlag::eCONTACT_DEFAULT;
pairFlags |= physx::PxPairFlag::eDETECT_CCD_CONTACT;
pairFlags |= physx::PxPairFlag::eNOTIFY_CONTACT_POINTS;
pairFlags |= physx::PxPairFlag::eMODIFY_CONTACTS; //necessary
PxFilterFlags ret = PxFilterFlag::eDEFAULT;
return ret;
}
class MyContactModifyCallback : public FContactModifyCallback
{
public:
void onContactModify(PxContactModifyPair* const pairs, PxU32 count)
{
for (PxU32 i = 0; i < count; i++)
{
PxContactModifyPair& pair = pairs[i];
for (PxU32 j = 0; j < pair.contacts.size(); j++)
{
// code your filter codes
//pair.contacts.ignore(j);
}
}
}
};
class MyContactModifyCallbackFactory : public IContactModifyCallbackFactory
{
public:
FContactModifyCallback* Create(FPhysScene_PhysX* PhysScene)
{
return new MyContactModifyCallback();
}
void Destroy(FContactModifyCallback* Callback)
{
delete Callback;
}
};
AMyWorldSettings::AMyWorldSettings(const FObjectInitializer& ObjectInitializer)
: AWorldSettings(ObjectInitializer)
{
GSimulationFilterShader = PxSimulationFilterShaderProc;
FPhysScene_PhysX::ContactModifyCallbackFactory = TSharedPtr<IContactModifyCallbackFactory>(new MyContactModifyCallbackFactory());
}
This example is taking effect only if the following conditions are reached.
’ Edit → Project Settings → General Settings → Default Classes → World Settings Class ’ be set of ‘AMyWorldSettings’ .
‘Simulate Physics’ be set of true.
Physics Collision enabled.
Add module ‘PhysicsCore’ in xxx.Build.cs.
1 Like
Thank you, this is great stuff!
I wanted to add that the function outlined here, PxSimulationFilterShaderProc()
, which sets up the pair flags etc. should probably be an exact copy of PhysXSimFilterShader()
in the engine (not just setting the 4 pair flags as outlined here) so collisions behave “normally”. Then, the “modify contacts” flag needs to be added of course.