13 bool bDoubleCheckPairs =
false;
17 if (!KeyPair.Key.Prim1.IsValid() || !KeyPair.Key.Prim2.IsValid() )
63 if (FPhysScene* PhysScene = GetWorld()->GetPhysicsScene())
68#elif PHYSICS_INTERFACE_PHYSX
69 if (PxScene* PScene = PhysScene->GetPxScene())
74 if (FCCDContactModifyCallbackVR* ContactCallback = (FCCDContactModifyCallbackVR*)PScene->getCCDContactModifyCallback())
76 FRWScopeLock(ContactCallback->RWAccessLock, FRWScopeLockType::SLT_Write);
78 for (
int i = ContactCallback->ContactsToIgnore.Num() - 1; i >= 0; --i)
81 (!ContactCallback->ContactsToIgnore[i].Prim1.IsValid() || !ContactCallback->ContactsToIgnore[i].Prim2.IsValid()) ||
82 (!ContactCallback->ContactsToIgnore[i].Actor1.IsValid() || !FPhysicsInterface::IsValid(ContactCallback->ContactsToIgnore[i].Actor1)) ||
83 (!ContactCallback->ContactsToIgnore[i].Actor2.IsValid() || !FPhysicsInterface::IsValid(ContactCallback->ContactsToIgnore[i].Actor2))
86 ContactCallback->ContactsToIgnore.RemoveAt(i);
93 if (FContactModifyCallbackVR* ContactCallback = (FContactModifyCallbackVR*)PScene->getContactModifyCallback())
95 FRWScopeLock(ContactCallback->RWAccessLock, FRWScopeLockType::SLT_Write);
97 for (
int i = ContactCallback->ContactsToIgnore.Num() - 1; i >= 0; --i)
100 (!ContactCallback->ContactsToIgnore[i].Prim1.IsValid() || !ContactCallback->ContactsToIgnore[i].Prim2.IsValid()) ||
101 (!ContactCallback->ContactsToIgnore[i].Actor1.IsValid() || !FPhysicsInterface::IsValid(ContactCallback->ContactsToIgnore[i].Actor1)) ||
102 (!ContactCallback->ContactsToIgnore[i].Actor2.IsValid() || !FPhysicsInterface::IsValid(ContactCallback->ContactsToIgnore[i].Actor2))
105 ContactCallback->ContactsToIgnore.RemoveAt(i);
113 PScene->unlockWrite();
119 for (
const TPair<FCollisionPrimPair, FCollisionIgnorePairArray>& KeyPair :
RemovedPairs)
142 if (KeyPair.Key.Prim1 == Prim1 || KeyPair.Key.Prim2 == Prim1)
154 if (FPhysScene* PhysScene = GetWorld()->GetPhysicsScene())
159#elif PHYSICS_INTERFACE_PHYSX
160 if (PxScene* PScene = PhysScene->GetPxScene())
165 if (FCCDContactModifyCallbackVR* ContactCallback = (FCCDContactModifyCallbackVR*)PScene->getCCDContactModifyCallback())
167 FRWScopeLock(ContactCallback->RWAccessLock, FRWScopeLockType::SLT_Write);
169 for (
int i = ContactCallback->ContactsToIgnore.Num() - 1; i >= 0; --i)
171 if (ContactCallback->ContactsToIgnore[i].Prim1 == Prim1 || ContactCallback->ContactsToIgnore[i].Prim2 == Prim1)
173 ContactCallback->ContactsToIgnore.RemoveAt(i);
178 if (FContactModifyCallbackVR* ContactCallback = (FContactModifyCallbackVR*)PScene->getContactModifyCallback())
180 FRWScopeLock(ContactCallback->RWAccessLock, FRWScopeLockType::SLT_Write);
182 for (
int i = ContactCallback->ContactsToIgnore.Num() - 1; i >= 0; --i)
184 if (ContactCallback->ContactsToIgnore[i].Prim1 == Prim1 || ContactCallback->ContactsToIgnore[i].Prim2 == Prim1)
186 ContactCallback->ContactsToIgnore.RemoveAt(i);
192 PScene->unlockWrite();
198 for (
const TPair<FCollisionPrimPair, FCollisionIgnorePairArray>& KeyPair :
RemovedPairs)
263 if (!Prim1 || !Prim2)
265 UE_LOG(VRE_CollisionIgnoreLog,
Error, TEXT(
"Set Objects Ignore Collision called with invalid object(s)!!"));
269 if (Prim1->GetCollisionEnabled() == ECollisionEnabled::NoCollision || Prim2->GetCollisionEnabled() == ECollisionEnabled::NoCollision)
271 UE_LOG(VRE_CollisionIgnoreLog,
Error, TEXT(
"Set Objects Ignore Collision called with one or more objects with no collision!! %s, %s"), *Prim1->GetName(), *Prim2->GetName());
275 if (Prim1->Mobility == EComponentMobility::Static || Prim2->Mobility == EComponentMobility::Static)
277 UE_LOG(VRE_CollisionIgnoreLog,
Error, TEXT(
"Set Objects Ignore Collision called with at least one static mobility object (cannot ignore collision with it)!!"));
278 if (bIgnoreCollision)
287 if (bIterateChildren1)
289 SkeleMesh = Cast<USkeletalMeshComponent>(Prim1);
292 if (bIterateChildren2)
294 SkeleMesh2 = Cast<USkeletalMeshComponent>(Prim2);
299 FBodyInstance* BInstance;
302 BodyPairStore(FBodyInstance* BI, FName BoneName)
309 TArray<BodyPairStore> ApplicableBodies;
313 UPhysicsAsset* PhysAsset = SkeleMesh ? SkeleMesh->GetPhysicsAsset() :
nullptr;
316 int32 NumBodiesFound = SkeleMesh->ForEachBodyBelow(OptionalBoneName1,
true,
false, [PhysAsset, &ApplicableBodies](FBodyInstance* BI)
318 const FName IterBodyName = PhysAsset->SkeletalBodySetups[BI->InstanceBodyIndex]->BoneName;
319 ApplicableBodies.Add(BodyPairStore(BI, IterBodyName));
325 FBodyInstance* Inst1 = Prim1->GetBodyInstance(OptionalBoneName1);
328 ApplicableBodies.Add(BodyPairStore(Inst1, OptionalBoneName1));
332 TArray<BodyPairStore> ApplicableBodies2;
335 UPhysicsAsset* PhysAsset = SkeleMesh2 ? SkeleMesh2->GetPhysicsAsset() :
nullptr;
338 int32 NumBodiesFound = SkeleMesh2->ForEachBodyBelow(OptionalBoneName2,
true,
false, [PhysAsset, &ApplicableBodies2](FBodyInstance* BI)
340 const FName IterBodyName = PhysAsset->SkeletalBodySetups[BI->InstanceBodyIndex]->BoneName;
341 ApplicableBodies2.Add(BodyPairStore(BI, IterBodyName));
347 FBodyInstance* Inst1 = Prim2->GetBodyInstance(OptionalBoneName2);
350 ApplicableBodies2.Add(BodyPairStore(Inst1, OptionalBoneName2));
356 newPrimPair.
Prim1 = Prim1;
357 newPrimPair.
Prim2 = Prim2;
377 for (
int i = 0; i < ApplicableBodies.Num(); ++i)
379 for (
int j = 0; j < ApplicableBodies2.Num(); ++j)
381 if (ApplicableBodies[i].BInstance && ApplicableBodies2[j].BInstance)
383 if (FPhysScene* PhysScene = Prim1->GetWorld()->GetPhysicsScene())
386 newContactPair.
Actor1 = ApplicableBodies[i].BInstance->ActorHandle;
387 newContactPair.
Actor2 = ApplicableBodies2[j].BInstance->ActorHandle;
388 newContactPair.
Prim1 = Prim1;
389 newContactPair.
Prim2 = Prim2;
392 newIgnorePair.
Actor1 = ApplicableBodies[i].BInstance->ActorHandle;
393 newIgnorePair.
BoneName1 = ApplicableBodies[i].BName;
394 newIgnorePair.
Actor2 = ApplicableBodies2[j].BInstance->ActorHandle;
395 newIgnorePair.
BoneName2 = ApplicableBodies2[j].BName;
398 Chaos::FUniqueIdx ID0 = ApplicableBodies[i].BInstance->ActorHandle->GetParticle_LowLevel()->UniqueIdx();
399 Chaos::FUniqueIdx ID1 = ApplicableBodies2[j].BInstance->ActorHandle->GetParticle_LowLevel()->UniqueIdx();
401 Chaos::FIgnoreCollisionManager& IgnoreCollisionManager = PhysScene->GetSolver()->GetEvolution()->GetBroadPhase().GetIgnoreCollisionManager();
403 FPhysicsCommand::ExecuteWrite(PhysScene, [&]()
405 using namespace Chaos;
407 if (bIgnoreCollision)
409 if (!IgnoreCollisionManager.IgnoresCollision(ID0, ID1))
411 TPBDRigidParticleHandle<FReal, 3>* ParticleHandle0 = ApplicableBodies[i].BInstance->ActorHandle->GetHandle_LowLevel()->CastToRigidParticle();
412 TPBDRigidParticleHandle<FReal, 3>* ParticleHandle1 = ApplicableBodies2[j].BInstance->ActorHandle->GetHandle_LowLevel()->CastToRigidParticle();
414 if (ParticleHandle0 && ParticleHandle1)
416 ParticleHandle0->AddCollisionConstraintFlag(Chaos::ECollisionConstraintFlags::CCF_BroadPhaseIgnoreCollisions);
417 IgnoreCollisionManager.AddIgnoreCollisionsFor(ID0, ID1);
419 ParticleHandle1->AddCollisionConstraintFlag(Chaos::ECollisionConstraintFlags::CCF_BroadPhaseIgnoreCollisions);
420 IgnoreCollisionManager.AddIgnoreCollisionsFor(ID1, ID0);
422 if (CollisionTrackedPairs.Contains(newPrimPair))
424 CollisionTrackedPairs[newPrimPair].PairArray.AddUnique(newIgnorePair);
437 if (IgnoreCollisionManager.IgnoresCollision(ID0, ID1))
439 TPBDRigidParticleHandle<FReal, 3>* ParticleHandle0 = ApplicableBodies[i].BInstance->ActorHandle->GetHandle_LowLevel()->CastToRigidParticle();
440 TPBDRigidParticleHandle<FReal, 3>* ParticleHandle1 = ApplicableBodies2[j].BInstance->ActorHandle->GetHandle_LowLevel()->CastToRigidParticle();
442 if (ParticleHandle0 && ParticleHandle1)
444 IgnoreCollisionManager.RemoveIgnoreCollisionsFor(ID0, ID1);
445 IgnoreCollisionManager.RemoveIgnoreCollisionsFor(ID1, ID0);
447 if (IgnoreCollisionManager.NumIgnoredCollision(ID0) < 1)
449 ParticleHandle0->RemoveCollisionConstraintFlag(Chaos::ECollisionConstraintFlags::CCF_BroadPhaseIgnoreCollisions);
452 if (IgnoreCollisionManager.NumIgnoredCollision(ID1) < 1)
454 ParticleHandle1->RemoveCollisionConstraintFlag(Chaos::ECollisionConstraintFlags::CCF_BroadPhaseIgnoreCollisions);
469 RemovedPairs[newPrimPair].PairArray.AddUnique(newIgnorePair);
474#elif PHYSICS_INTERFACE_PHYSX
475 if (PxScene* PScene = PhysScene->GetPxScene())
480 if (FCCDContactModifyCallbackVR* ContactCallback = (FCCDContactModifyCallbackVR*)PScene->getCCDContactModifyCallback())
482 FRWScopeLock(ContactCallback->RWAccessLock, FRWScopeLockType::SLT_Write);
484 if (bIgnoreCollision)
491 ContactCallback->ContactsToIgnore.AddUnique(newContactPair);
493 if (ApplicableBodies[i].BInstance->bContactModification != bIgnoreCollision)
494 ApplicableBodies[i].BInstance->SetContactModification(
true);
496 if (ApplicableBodies2[j].BInstance->bContactModification != bIgnoreCollision)
497 ApplicableBodies2[j].BInstance->SetContactModification(
true);
501 bool bHadPrimPair =
false;
503 ContactCallback->ContactsToIgnore.Remove(newContactPair);
525 RemovedPairs[newPrimPair].PairArray.AddUnique(newIgnorePair);
530 if (FContactModifyCallbackVR* ContactCallback = (FContactModifyCallbackVR*)PScene->getContactModifyCallback())
532 FRWScopeLock(ContactCallback->RWAccessLock, FRWScopeLockType::SLT_Write);
534 if (bIgnoreCollision)
536 ContactCallback->ContactsToIgnore.AddUnique(newContactPair);
543 if (ApplicableBodies[i].BInstance->bContactModification != bIgnoreCollision)
544 ApplicableBodies[i].BInstance->SetContactModification(
true);
546 if (ApplicableBodies2[j].BInstance->bContactModification != bIgnoreCollision)
547 ApplicableBodies2[j].BInstance->SetContactModification(
true);
552 bool bHadPrimPair =
false;
554 ContactCallback->ContactsToIgnore.Remove(newContactPair);
576 RemovedPairs[newPrimPair].PairArray.AddUnique(newIgnorePair);
582 PScene->unlockWrite();