2019-12-26 14:45:42 -05:00
// Copyright Epic Games, Inc. All Rights Reserved.
2018-12-12 11:25:29 -05:00
# include "GeometryCollection/GeometryCollectionSQAccelerator.h"
# include "Physics/Experimental/PhysScene_Chaos.h"
2019-06-08 17:15:34 -04:00
# include "Chaos/Box.h"
# include "Chaos/Capsule.h"
# include "Chaos/ImplicitObjectTransformed.h"
# include "Chaos/Sphere.h"
2018-12-12 11:25:29 -05:00
# include "Chaos/PBDRigidParticles.h"
# include "GeometryCollection/ManagedArray.h"
# include "GeometryCollection/GeometryCollectionComponent.h"
# include "GeometryCollection/GeometryCollectionActor.h"
# include "Components/BoxComponent.h"
# include "ChaosSolversModule.h"
# include "ChaosStats.h"
2019-08-02 09:01:58 -04:00
# include "PhysicsSolver.h"
# include "PhysicsProxy/GeometryCollectionPhysicsProxy.h"
2018-12-12 11:25:29 -05:00
2019-10-02 17:27:26 -04:00
# if !WITH_CHAOS_NEEDS_TO_BE_FIXED
2019-06-08 17:15:34 -04:00
DECLARE_CYCLE_STAT ( TEXT ( " LowLevelSweep " ) , STAT_LowLevelSweep , STATGROUP_Chaos ) ;
DECLARE_CYCLE_STAT ( TEXT ( " LowLevelRaycast " ) , STAT_LowLevelRaycast , STATGROUP_Chaos ) ;
DECLARE_CYCLE_STAT ( TEXT ( " LowLevelOverlap " ) , STAT_LowLevelOverlap , STATGROUP_Chaos ) ;
2019-08-02 09:01:58 -04:00
# if TODO_REIMPLEMENT_SCENEQUERY_CROSSENGINE
2021-03-18 15:20:03 -04:00
bool IsValidIndexAndTransform ( const FGeometryCollectionResults & PhysResult , const Chaos : : TPBDRigidParticles < Chaos : : FReal , 3 > & Particles , const TManagedArray < FTransform > & TransformArray , const TArray < bool > & DisabledFlags , const int32 RigidBodyIdx , const bool bCanBeDisabled )
2019-06-08 17:15:34 -04:00
{
if ( RigidBodyIdx = = - 1 )
{
//todo(ocohen): managed to avoid this invalid index, but need to investigate a bit more into whether we can always assume it's valid
return false ;
}
if ( PhysResult . BaseIndex = = - 1 )
{
//todo(mlentine): Why is this possible?
return false ;
}
const int32 LocalBodyIndex = RigidBodyIdx - PhysResult . BaseIndex ;
if ( LocalBodyIndex < 0 | | LocalBodyIndex > = PhysResult . NumParticlesAdded )
{
// Ignore collisions for other components - need to make this even faster (subset of potential intersections [maybe array view?])
return false ;
}
const FTransform & CurrentTransform = TransformArray [ LocalBodyIndex ] ;
const FVector CurrentTranslation = CurrentTransform . GetTranslation ( ) ;
//@todo(mlentine): In theory this is no longer needed
if ( ! bCanBeDisabled & & DisabledFlags [ LocalBodyIndex ] )
{
//disabled particles can actually have stale geometry in them and are clearly not useful anyway
return false ;
}
if ( static_cast < uint32 > ( RigidBodyIdx ) > = Particles . Size ( ) )
{
// @todo(mlentine): Is this a possible situation?
return false ;
}
if ( ! ( ensure ( ! FMath : : IsNaN ( CurrentTranslation [ 0 ] ) ) & & ensure ( ! FMath : : IsNaN ( CurrentTranslation [ 1 ] ) ) & & ensure ( ! FMath : : IsNaN ( CurrentTranslation [ 2 ] ) ) ) )
{
return false ;
}
return true ;
}
2021-03-18 15:20:03 -04:00
bool LowLevelRaycastSingleElement ( int32 InParticleIndex , const Chaos : : FPhysicsSolver * InSolver , const Chaos : : FClusterBuffer & ClusterBuffer , const FGeometryCollectionPhysicsProxy * InObject , const FVector & Start , const FVector & Dir , Chaos : : FReal DeltaMag , bool bCanBeDisabled , EHitFlags OutputFlags , FHitRaycast & OutHit )
2018-12-12 11:25:29 -05:00
{
using namespace Chaos ;
2019-06-08 17:15:34 -04:00
// Preconditions from Raycast - shouldn't get in here without valid case
checkSlow ( InSolver ) ;
checkSlow ( InObject ) ;
const FGeometryCollectionResults & PhysResult = InObject - > GetPhysicsResults ( ) . GetGameDataForRead ( ) ;
const TManagedArray < int32 > & RigidBodyIdArray = PhysResult . RigidBodyIds ;
const TManagedArray < FTransform > & TransformArray = PhysResult . Transforms ;
const TArray < bool > & DisabledFlags = PhysResult . DisabledStates ;
{
2021-03-18 15:20:03 -04:00
const TPBDRigidParticles < Chaos : : FReal , 3 > & Particles = InSolver - > GetRigidParticles ( ) ;
2019-06-08 17:15:34 -04:00
if ( ! IsValidIndexAndTransform ( PhysResult , Particles , TransformArray , DisabledFlags , InParticleIndex , bCanBeDisabled ) )
{
return false ;
}
const int32 LocalBodyIndex = InParticleIndex - PhysResult . BaseIndex ;
2021-03-18 15:20:03 -04:00
const FRigidTransform3 & TM = PhysResult . ParticleToWorldTransforms [ LocalBodyIndex ] ;
2019-06-08 17:15:34 -04:00
if ( ! ( ensure ( ! FMath : : IsNaN ( TM . GetTranslation ( ) . X ) ) & & ensure ( ! FMath : : IsNaN ( TM . GetTranslation ( ) . Y ) ) & & ensure ( ! FMath : : IsNaN ( TM . GetTranslation ( ) . Z ) ) ) )
{
return false ;
}
2021-02-03 14:57:28 -04:00
const FVec3 StartLocal = TM . InverseTransformPositionNoScale ( Start ) ;
const FVec3 DirLocal = TM . InverseTransformVectorNoScale ( Dir ) ;
const FVec3 EndLocal = StartLocal + DirLocal * DeltaMag ;
2019-06-08 17:15:34 -04:00
2019-10-31 17:28:08 -04:00
const FImplicitObject * Object = ClusterBuffer . GeometryPtrs [ InParticleIndex ] . Get ( ) ; //todo(ocohen): can this ever be null?
2019-06-08 17:15:34 -04:00
if ( ! Object )
{
return false ;
}
2021-02-03 14:57:28 -04:00
Pair < FVec3 , bool > Result = Object - > FindClosestIntersection ( StartLocal , EndLocal , /*Thickness=*/ 0.f ) ;
2019-06-08 17:15:34 -04:00
if ( Result . Second ) //todo(ocohen): once we do more than just a bool we need to get the closest point
{
# if WITH_PHYSX
//todo(ocohen): check output flags?
2021-03-18 15:20:03 -04:00
const Chaos : : FReal Distance = ( Result . First - StartLocal ) . Size ( ) ;
2019-06-08 17:15:34 -04:00
if ( OutHit . distance = = PX_MAX_REAL | | Distance < OutHit . distance )
{
OutHit . distance = Distance ; //todo(ocohen): assuming physx structs for now
OutHit . position = U2PVector ( TM . TransformPositionNoScale ( Result . First ) ) ;
2021-02-03 14:57:28 -04:00
const FVec3 LocalNormal = Object - > Normal ( Result . First ) ;
2019-06-08 17:15:34 -04:00
OutHit . normal = U2PVector ( TM . TransformVectorNoScale ( LocalNormal ) ) ;
SetFlags ( OutHit , EHitFlags : : Distance | EHitFlags : : Normal | EHitFlags : : Position ) ;
}
return true ;
# endif
}
}
return false ;
}
static TAutoConsoleVariable < int32 > CVarMaxSweepSteps (
TEXT ( " p.MaxSweepSteps " ) ,
3 ,
TEXT ( " Number of steps during a sweep " ) ,
ECVF_Default ) ;
2021-03-18 15:20:03 -04:00
bool LowLevelSweepSingleElement ( int32 InParticleIndex , const Chaos : : FPhysicsSolver * InSolver , const Chaos : : FClusterBuffer & ClusterBuffer , const FGeometryCollectionPhysicsProxy * InObject , const Chaos : : FImplicitObject & QueryGeom , const Chaos : : FParticles & CollisionParticles , const FTransform & StartPose , const FVector & Dir , Chaos : : FReal DeltaMag , const bool bCanBeDisabled , FHitSweep & OutHit )
2019-06-08 17:15:34 -04:00
{
using namespace Chaos ;
checkSlow ( InSolver ) ;
checkSlow ( InObject ) ;
const FGeometryCollectionResults & PhysResult = InObject - > GetPhysicsResults ( ) . GetGameDataForRead ( ) ;
const TManagedArray < int32 > & RigidBodyIdArray = PhysResult . RigidBodyIds ;
const TManagedArray < FTransform > & TransformArray = PhysResult . Transforms ;
const TArray < bool > & DisabledFlags = PhysResult . DisabledStates ;
2021-03-18 15:20:03 -04:00
const TPBDRigidParticles < Chaos : : FReal , 3 > & Particles = InSolver - > GetRigidParticles ( ) ;
2019-06-08 17:15:34 -04:00
if ( ! IsValidIndexAndTransform ( PhysResult , Particles , TransformArray , DisabledFlags , InParticleIndex , bCanBeDisabled ) )
{
return false ;
}
const int32 LocalBodyIndex = InParticleIndex - PhysResult . BaseIndex ;
2021-03-18 15:20:03 -04:00
const FRigidTransform3 & TM = PhysResult . ParticleToWorldTransforms [ LocalBodyIndex ] ;
2019-06-08 17:15:34 -04:00
2019-10-31 17:28:08 -04:00
const FImplicitObject * Object = ClusterBuffer . GeometryPtrs [ InParticleIndex ] . Get ( ) ;
2019-06-08 17:15:34 -04:00
if ( ! Object )
{
return false ;
}
2021-02-03 14:57:28 -04:00
const FVec3 DirLocal = TM . InverseTransformVectorNoScale ( Dir ) ;
2019-06-08 17:15:34 -04:00
2018-12-12 11:25:29 -05:00
bool bFound = false ;
2019-06-08 17:15:34 -04:00
for ( uint32 i = 0 ; i < CollisionParticles . Size ( ) ; + + i )
2018-12-12 11:25:29 -05:00
{
2021-02-03 14:57:28 -04:00
const FVec3 StartLocal = TM . InverseTransformPositionNoScale ( StartPose . TransformPositionNoScale ( CollisionParticles . X ( i ) ) ) ;
const FVec3 EndLocal = StartLocal + DirLocal * DeltaMag ;
2018-12-12 11:25:29 -05:00
2021-02-03 14:57:28 -04:00
Pair < FVec3 , bool > Result = Object - > FindClosestIntersection ( StartLocal , EndLocal , /*Thickness=*/ 0.f ) ;
2019-06-08 17:15:34 -04:00
if ( Result . Second )
2018-12-12 11:25:29 -05:00
{
# if WITH_PHYSX
2021-03-18 15:20:03 -04:00
const Chaos : : FReal Distance = ( Result . First - StartLocal ) . Size ( ) ;
2019-06-08 17:15:34 -04:00
if ( ! bFound | | Distance < OutHit . distance )
{
OutHit . distance = Distance ; //todo(ocohen): assuming physx structs for now
OutHit . position = U2PVector ( TM . TransformPositionNoScale ( Result . First ) ) ;
2021-02-03 14:57:28 -04:00
const FVec3 LocalNormal = Object - > Normal ( Result . First ) ;
2019-06-08 17:15:34 -04:00
OutHit . normal = U2PVector ( TM . TransformVectorNoScale ( LocalNormal ) ) ;
SetFlags ( OutHit , EHitFlags : : Distance | EHitFlags : : Normal | EHitFlags : : Position ) ;
2018-12-12 11:25:29 -05:00
}
2019-06-08 17:15:34 -04:00
bFound = true ;
# endif
2018-12-12 11:25:29 -05:00
}
}
return bFound ;
}
2021-02-18 18:13:28 -04:00
bool LowLevelOverlap ( const UGeometryCollectionComponent & GeomCollectionComponent , const TArray < int32 > & InPotentialIntersections , const Chaos : : FClusterBuffer & ClusterBuffer , const Chaos : : FImplicitObject & QueryGeom , const FTransform & GeomPose , FHitOverlap & OutHit )
2018-12-12 11:25:29 -05:00
{
2019-06-08 17:15:34 -04:00
using namespace Chaos ;
2018-12-12 11:25:29 -05:00
2019-06-08 17:15:34 -04:00
SCOPE_CYCLE_COUNTER ( STAT_LowLevelOverlap ) ;
2019-08-02 09:01:58 -04:00
const FGeometryCollectionPhysicsProxy * PhysObject = GeomCollectionComponent . GetPhysicsProxy ( ) ;
2019-06-08 17:15:34 -04:00
if ( ! ensure ( PhysObject ) )
{
return false ;
}
const FGeometryCollectionResults & PhysResult = PhysObject - > GetPhysicsResults ( ) . GetGameDataForRead ( ) ;
const TManagedArray < int32 > & RigidBodyIdArray = PhysResult . RigidBodyIds ;
const TManagedArray < FTransform > & TransformArray = PhysResult . Transforms ;
const TArray < bool > & DisabledFlags = PhysResult . DisabledStates ;
bool bFound = false ;
2019-08-02 09:01:58 -04:00
if ( Chaos : : FPhysicsSolver * Solver = GeomCollectionComponent . ChaosSolverActor ! = nullptr ? GeomCollectionComponent . ChaosSolverActor - > GetSolver ( ) : GeomCollectionComponent . GetOwner ( ) - > GetWorld ( ) - > PhysicsScene_Chaos - > GetSolver ( ) )
2019-06-08 17:15:34 -04:00
{
2021-03-18 15:20:03 -04:00
const TPBDRigidParticles < Chaos : : FReal , 3 > & Particles = Solver - > GetRigidParticles ( ) ; //todo(ocohen): should these just get passed in instead of hopping through scene?
2019-06-08 17:15:34 -04:00
check ( QueryGeom . HasBoundingBox ( ) ) ; // We do not support unbounded query objects
PhysicsParallelFor ( InPotentialIntersections . Num ( ) , [ & ] ( int32 PotentialIdx )
{
int32 RigidBodyIdx = InPotentialIntersections [ PotentialIdx ] ;
if ( ! IsValidIndexAndTransform ( PhysResult , Particles , TransformArray , DisabledFlags , RigidBodyIdx , false ) )
{
return ;
}
const int32 LocalBodyIndex = RigidBodyIdx - PhysResult . BaseIndex ;
2021-03-18 15:20:03 -04:00
const FRigidTransform3 & TM = PhysResult . ParticleToWorldTransforms [ LocalBodyIndex ] ;
2019-06-08 17:15:34 -04:00
2019-10-31 17:28:08 -04:00
const FImplicitObject * Object = ClusterBuffer . GeometryPtrs [ RigidBodyIdx ] . Get ( ) ;
2019-06-08 17:15:34 -04:00
if ( ! Object )
{
return ;
}
// Need to do narrow phase
2021-03-18 15:20:03 -04:00
Pair < FVec3 , bool > Result = QueryGeom . FindDeepestIntersection ( Object , Particles . CollisionParticles ( RigidBodyIdx ) . Get ( ) , FRigidTransform3 ( TM ) * FRigidTransform3 ( GeomPose ) . Inverse ( ) , 0 ) ;
2019-06-08 17:15:34 -04:00
if ( Result . Second )
{
bFound = true ;
}
} ) ;
}
return bFound ;
}
int32 UseSlowSQ = 0 ;
FAutoConsoleVariableRef CVarUseSlowSQ ( TEXT ( " p.UseSlowSQ " ) , UseSlowSQ , TEXT ( " " ) ) ;
2021-03-18 15:20:03 -04:00
void FGeometryCollectionSQAccelerator : : Raycast ( const FVector & Start , const FVector & Dir , const Chaos : : FReal DeltaMagnitude , ChaosInterface : : FSQHitBuffer < ChaosInterface : : FRaycastHit > & HitBuffer , EHitFlags OutputFlags , const FQueryFilterData & QueryFilterData , ICollisionQueryFilterCallbackBase & QueryCallback ) const
2019-06-08 17:15:34 -04:00
{
2018-12-12 11:25:29 -05:00
SCOPE_CYCLE_COUNTER ( STAT_GCRaycast ) ;
2019-06-08 17:15:34 -04:00
FChaosScopeSolverLock SolverScopeLock ;
using namespace Chaos ;
FChaosSolversModule * Module = FChaosSolversModule : : GetModule ( ) ;
2019-08-02 09:01:58 -04:00
TMap < const Chaos : : FPhysicsSolver * , TArray < int32 > > SolverIntersectionSets ;
2019-06-08 17:15:34 -04:00
2021-03-18 15:20:03 -04:00
Chaos : : TSpatialRay < Chaos : : FReal , 3 > Ray ( Start , Start + Dir * DeltaMagnitude ) ;
2018-12-12 11:25:29 -05:00
# if WITH_PHYSX
2019-06-08 17:15:34 -04:00
2019-08-02 09:01:58 -04:00
const TArray < Chaos : : FPhysicsSolver * > & Solvers = Module - > GetSolvers ( ) ;
2019-06-08 17:15:34 -04:00
2019-08-02 09:01:58 -04:00
for ( const Chaos : : FPhysicsSolver * Solver : Solvers )
2018-12-12 11:25:29 -05:00
{
2019-06-08 17:15:34 -04:00
if ( ! Solver )
2018-12-12 11:25:29 -05:00
{
2019-06-08 17:15:34 -04:00
continue ;
2018-12-12 11:25:29 -05:00
}
2019-06-08 17:15:34 -04:00
TArray < int32 > IntersectionSet = Solver - > GetSpatialAcceleration ( ) - > FindAllIntersections ( Ray ) ;
Solver - > ReleaseSpatialAcceleration ( ) ;
2021-02-18 18:13:28 -04:00
const Chaos : : FClusterBuffer & Buffer = Solver - > GetRigidClustering ( ) . GetBufferedData ( ) ;
2019-06-08 17:15:34 -04:00
2019-08-02 09:01:58 -04:00
const Chaos : : FPhysicsSolver : : FPhysicsProxyReverseMapping & ObjectMap = Solver - > GetPhysicsProxyReverseMapping_GameThread ( ) ;
2019-06-08 17:15:34 -04:00
FHitRaycast Hit ;
int32 IntersectionSetSize = IntersectionSet . Num ( ) ;
for ( int32 i = 0 ; i < IntersectionSet . Num ( ) ; + + i )
{
const int32 IntersectParticleIndex = IntersectionSet [ i ] ;
2019-08-02 09:01:58 -04:00
const PhysicsProxyWrapper & ObjectWrapper = ObjectMap . PhysicsProxyReverseMappingArray [ IntersectParticleIndex ] ;
if ( ! ObjectWrapper . PhysicsProxy )
2019-06-08 17:15:34 -04:00
{
2019-10-31 17:28:08 -04:00
const FImplicitObject * Object = Buffer . GeometryPtrs [ IntersectParticleIndex ] . Get ( ) ;
2019-06-08 17:15:34 -04:00
// Ignore the ground plane
if ( IntersectParticleIndex = = 0 & & Object - > GetType ( true ) = = ImplicitObjectType : : Plane )
{
continue ;
}
if ( Object & & ! UseSlowSQ & & Object - > IsUnderlyingUnion ( ) )
{
2021-03-18 15:20:03 -04:00
const FImplicitObjectUnion * Union = static_cast < const TImplicitObjectUnion < Chaos : : FReal , 3 > * > ( Object ) ;
2019-06-08 17:15:34 -04:00
//hack: this is terrible because we have no buffered transform so could be off, but most of the time these things are static
{
2021-03-18 15:20:03 -04:00
const FRigidTransform3 * TMPtr = Buffer . ClusterParentTransforms . Find ( IntersectParticleIndex ) ;
2019-06-08 17:15:34 -04:00
if ( ensure ( TMPtr ) )
{
if ( ! ( ensure ( ! FMath : : IsNaN ( TMPtr - > GetTranslation ( ) . X ) ) & & ensure ( ! FMath : : IsNaN ( TMPtr - > GetTranslation ( ) . Y ) ) & & ensure ( ! FMath : : IsNaN ( TMPtr - > GetTranslation ( ) . Z ) ) ) )
{
continue ;
}
2021-02-03 14:57:28 -04:00
const FVec3 StartLocal = TMPtr - > InverseTransformPositionNoScale ( Start ) ;
const FVec3 DirLocal = TMPtr - > InverseTransformVectorNoScale ( Dir ) ;
const FVec3 EndLocal = StartLocal + DirLocal * DeltaMagnitude ;
2021-03-18 15:20:03 -04:00
Chaos : : TSpatialRay < Chaos : : FReal , 3 > LocalRay ( StartLocal , EndLocal ) ;
2019-06-08 17:15:34 -04:00
const TArray < int32 > IntersectingChildren = Union - > FindAllIntersectingChildren ( LocalRay ) ;
IntersectionSet . Append ( IntersectingChildren ) ;
}
else
{
UE_LOG ( LogChaos , Warning , TEXT ( " SQ: Could not find a valid transform for a cluster parent for faster child intersections. " ) ) ;
}
}
}
else
{
if ( ensure ( Buffer . MChildren . Contains ( IntersectParticleIndex ) ) )
{
const TArray < uint32 > & Children = Buffer . MChildren [ IntersectParticleIndex ] ;
for ( const uint32 Child : Children )
{
IntersectionSet . Add ( Child ) ;
}
}
}
continue ;
}
2019-08-02 09:01:58 -04:00
if ( ObjectWrapper . Type = = EPhysicsProxyType : : GeometryCollectionType & & ensure ( ObjectWrapper . PhysicsProxy ) )
2019-06-08 17:15:34 -04:00
{
2019-08-02 09:01:58 -04:00
LowLevelRaycastSingleElement ( IntersectParticleIndex , Solver , Buffer , static_cast < FGeometryCollectionPhysicsProxy * > ( ObjectWrapper . PhysicsProxy ) , Start , Dir , DeltaMagnitude , i > = IntersectionSetSize , OutputFlags , Hit ) ;
2019-06-08 17:15:34 -04:00
// If we registered a hit
2019-08-02 09:01:58 -04:00
if ( Hit . distance ! = PX_MAX_REAL & & ensure ( ObjectWrapper . PhysicsProxy ) )
2019-06-08 17:15:34 -04:00
{
# if !WITH_IMMEDIATE_PHYSX && PHYSICS_INTERFACE_PHYSX
//todo(ocohen):hack placeholder while we convert over to non physx API
2019-08-02 09:01:58 -04:00
UGeometryCollectionComponent * Component = Cast < UGeometryCollectionComponent > ( ObjectWrapper . PhysicsProxy - > GetOwner ( ) ) ;
2019-06-08 17:15:34 -04:00
check ( Component ) ;
if ( Component - > IsRegistered ( ) )
{
const FPhysicsActorHandle & ActorHandle = Component - > DummyBodyInstance . GetPhysicsActorHandle ( ) ;
PxRigidActor * PRigidActor = ActorHandle . SyncActor ;
uint32 PNumShapes = PRigidActor - > getNbShapes ( ) ;
TArray < PxShape * > PShapes ;
PShapes . AddZeroed ( PNumShapes ) ;
PRigidActor - > getShapes ( PShapes . GetData ( ) , sizeof ( PShapes [ 0 ] ) * PNumShapes ) ;
SetActor ( Hit , ActorHandle . SyncActor ) ;
SetShape ( Hit , PShapes [ 0 ] ) ;
}
# else
check ( false ) ; //this can't actually return nullptr since higher up API assumes both shape and actor exists in the low level
SetActor ( Hit , nullptr ) ;
SetShape ( Hit , nullptr ) ; //todo(ocohen): what do we return for apeiron?
# endif
Insert ( HitBuffer , Hit , true ) ; //for now assume all blocking hits
}
}
}
Solver - > GetRigidClustering ( ) . ReleaseBufferedData ( ) ;
2019-08-02 09:01:58 -04:00
Solver - > ReleasePhysicsProxyReverseMapping ( ) ;
2019-06-08 17:15:34 -04:00
}
# endif
}
DECLARE_CYCLE_STAT ( TEXT ( " Sweep Broadphase " ) , STAT_SQSweepBroadPhase , STATGROUP_Chaos ) ;
DECLARE_CYCLE_STAT ( TEXT ( " Sweep Narrowphase " ) , STAT_SQSweepNarrowPhase , STATGROUP_Chaos ) ;
//@todo(mlentine): Avoid duplicated code between this and overlap
2021-03-18 15:20:03 -04:00
void FGeometryCollectionSQAccelerator : : Sweep ( const Chaos : : FImplicitObject & QueryGeom , const FTransform & StartTM , const FVector & Dir , const Chaos : : FReal DeltaMagnitude , ChaosInterface : : FSQHitBuffer < ChaosInterface : : FSweepHit > & HitBuffer , EHitFlags OutputFlags , const FQueryFilterData & QueryFilterData , ICollisionQueryFilterCallbackBase & QueryCallback ) const
2019-06-08 17:15:34 -04:00
{
SCOPE_CYCLE_COUNTER ( STAT_GCSweep ) ;
FChaosScopeSolverLock SolverScopeLock ;
using namespace Chaos ;
# if WITH_PHYSX
2019-08-02 09:01:58 -04:00
TMap < const Chaos : : FPhysicsSolver * , TArray < int32 > > SolverIntersectionSets ;
2019-06-08 17:15:34 -04:00
// Getter for intersections from the mapping above
2021-03-18 15:20:03 -04:00
auto GetIntersectionsFunc = [ & ] ( const Chaos : : FPhysicsSolver * InSolver , const Chaos : : FParticles & InCollisionParticles , Chaos : : FReal InDeltaMag , const FTransform & InPose ) - > TArray < int32 >
2019-06-08 17:15:34 -04:00
{
SCOPE_CYCLE_COUNTER ( STAT_SQSweepBroadPhase )
TArray < int32 > PotentialIntersections ;
if ( InSolver - > Enabled ( ) )
{
2021-03-18 15:20:03 -04:00
const Chaos : : ISpatialAcceleration < Chaos : : FReal , 3 > * SpacialAcceleration = InSolver - > GetSpatialAcceleration ( ) ;
2019-06-08 17:15:34 -04:00
const int32 NumCollisionParticles = InCollisionParticles . Size ( ) ;
for ( int32 ParticleIndex = 0 ; ParticleIndex < NumCollisionParticles ; + + ParticleIndex )
{
2021-02-03 14:57:28 -04:00
const Chaos : : FVec3 RayStart = InPose . TransformPositionNoScale ( InCollisionParticles . X ( ParticleIndex ) ) ;
const Chaos : : FVec3 RayEnd = RayStart + Dir * InDeltaMag ;
2019-06-08 17:15:34 -04:00
2021-03-18 15:20:03 -04:00
PotentialIntersections . Append ( SpacialAcceleration - > FindAllIntersections ( Chaos : : TSpatialRay < Chaos : : FReal , 3 > ( RayStart , RayEnd ) ) ) ;
2019-06-08 17:15:34 -04:00
}
InSolver - > ReleaseSpatialAcceleration ( ) ;
PotentialIntersections . Sort ( ) ;
for ( int32 i = PotentialIntersections . Num ( ) - 1 ; i > 0 ; i - - )
{
if ( PotentialIntersections [ i ] = = PotentialIntersections [ i - 1 ] )
{
PotentialIntersections . RemoveAtSwap ( i , 1 , false ) ;
}
}
}
return PotentialIntersections ;
} ;
// Need somewhere to store our translated shape, similar to the PhysX geom holder
struct FLocalImplicitStorage
{
FLocalImplicitStorage ( )
: Capsule ( FVector : : ZeroVector , FVector : : ZeroVector , 0.0f )
, Sphere ( FVector : : ZeroVector , 0.0f )
, Box ( FVector : : ZeroVector , FVector : : ZeroVector )
{ }
2021-03-05 19:27:14 -04:00
Chaos : : FCapsule Capsule ;
2021-03-18 15:20:03 -04:00
Chaos : : TSphere < Chaos : : FReal , 3 > Sphere ;
2021-02-18 18:13:28 -04:00
Chaos : : FAABB3 Box ;
2019-06-08 17:15:34 -04:00
} ;
FLocalImplicitStorage ImplicitStorage ;
2019-10-31 17:28:08 -04:00
Chaos : : FImplicitObject * Implicit = nullptr ;
2019-06-08 17:15:34 -04:00
bool bHit = false ;
FHitSweep Hit ;
PxGeometryHolder Holder ( QueryGeom ) ;
2021-02-18 18:13:28 -04:00
Chaos : : FParticles CollisionParticles ;
2019-06-08 17:15:34 -04:00
if ( Holder . getType ( ) = = PxGeometryType : : eCAPSULE )
{
physx : : PxCapsuleGeometry & PxCapsule = Holder . capsule ( ) ;
2021-03-18 15:20:03 -04:00
Chaos : : FReal Radius = PxCapsule . radius ;
Chaos : : FReal HalfHeight = PxCapsule . halfHeight ;
2021-02-03 14:57:28 -04:00
Chaos : : FVec3 x1 ( - HalfHeight , 0 , 0 ) ;
Chaos : : FVec3 x2 ( HalfHeight , 0 , 0 ) ;
2019-06-08 17:15:34 -04:00
2021-03-05 19:27:14 -04:00
Chaos : : FCapsule Capsule ( x1 , x2 , Radius ) ;
2019-06-08 17:15:34 -04:00
ImplicitStorage . Capsule = MoveTemp ( Capsule ) ;
Implicit = & ImplicitStorage . Capsule ;
{
CollisionParticles . AddParticles ( 14 ) ;
2021-02-03 14:57:28 -04:00
CollisionParticles . X ( 0 ) = Chaos : : FVec3 ( HalfHeight + Radius , 0 , 0 ) ;
CollisionParticles . X ( 1 ) = Chaos : : FVec3 ( - HalfHeight - Radius , 0 , 0 ) ;
CollisionParticles . X ( 2 ) = Chaos : : FVec3 ( HalfHeight , Radius , Radius ) ;
CollisionParticles . X ( 3 ) = Chaos : : FVec3 ( HalfHeight , - Radius , Radius ) ;
CollisionParticles . X ( 4 ) = Chaos : : FVec3 ( HalfHeight , - Radius , - Radius ) ;
CollisionParticles . X ( 5 ) = Chaos : : FVec3 ( HalfHeight , Radius , - Radius ) ;
CollisionParticles . X ( 6 ) = Chaos : : FVec3 ( 0 , Radius , Radius ) ;
CollisionParticles . X ( 7 ) = Chaos : : FVec3 ( 0 , - Radius , Radius ) ;
CollisionParticles . X ( 8 ) = Chaos : : FVec3 ( 0 , - Radius , - Radius ) ;
CollisionParticles . X ( 9 ) = Chaos : : FVec3 ( 0 , Radius , - Radius ) ;
CollisionParticles . X ( 10 ) = Chaos : : FVec3 ( - HalfHeight , Radius , Radius ) ;
CollisionParticles . X ( 11 ) = Chaos : : FVec3 ( - HalfHeight , - Radius , Radius ) ;
CollisionParticles . X ( 12 ) = Chaos : : FVec3 ( - HalfHeight , - Radius , - Radius ) ;
CollisionParticles . X ( 13 ) = Chaos : : FVec3 ( - HalfHeight , Radius , - Radius ) ;
2019-06-08 17:15:34 -04:00
}
}
else if ( Holder . getType ( ) = = PxGeometryType : : eSPHERE )
{
physx : : PxSphereGeometry & PxSphere = Holder . sphere ( ) ;
2021-03-18 15:20:03 -04:00
Chaos : : FReal Radius = PxSphere . radius ;
2019-06-08 17:15:34 -04:00
2021-03-18 15:20:03 -04:00
Chaos : : TSphere < Chaos : : FReal , 3 > Sphere ( Chaos : : FVec3 ( 0 ) , Radius ) ;
2019-06-08 17:15:34 -04:00
ImplicitStorage . Sphere = MoveTemp ( Sphere ) ;
Implicit = & ImplicitStorage . Sphere ;
{
CollisionParticles . AddParticles ( 6 ) ;
2021-02-03 14:57:28 -04:00
CollisionParticles . X ( 0 ) = Chaos : : FVec3 ( Radius , 0 , 0 ) ;
CollisionParticles . X ( 1 ) = Chaos : : FVec3 ( - Radius , 0 , 0 ) ;
CollisionParticles . X ( 2 ) = Chaos : : FVec3 ( 0 , Radius , Radius ) ;
CollisionParticles . X ( 3 ) = Chaos : : FVec3 ( 0 , - Radius , Radius ) ;
CollisionParticles . X ( 4 ) = Chaos : : FVec3 ( 0 , - Radius , - Radius ) ;
CollisionParticles . X ( 5 ) = Chaos : : FVec3 ( 0 , Radius , - Radius ) ;
2019-06-08 17:15:34 -04:00
}
}
else if ( Holder . getType ( ) = = PxGeometryType : : eBOX )
{
physx : : PxBoxGeometry & PxBox = Holder . box ( ) ;
2021-02-03 14:57:28 -04:00
Chaos : : FVec3 x1 ( - P2UVector ( PxBox . halfExtents ) ) ;
Chaos : : FVec3 x2 ( - x1 ) ;
2019-06-08 17:15:34 -04:00
2021-02-18 18:13:28 -04:00
Chaos : : FAABB3 Box ( x1 , x2 ) ;
2019-06-08 17:15:34 -04:00
ImplicitStorage . Box = MoveTemp ( Box ) ;
Implicit = & ImplicitStorage . Box ;
{
CollisionParticles . AddParticles ( 8 ) ;
2021-02-03 14:57:28 -04:00
CollisionParticles . X ( 0 ) = Chaos : : FVec3 ( x1 . X , x1 . Y , x1 . Z ) ;
CollisionParticles . X ( 1 ) = Chaos : : FVec3 ( x1 . X , x1 . Y , x2 . Z ) ;
CollisionParticles . X ( 2 ) = Chaos : : FVec3 ( x1 . X , x2 . Y , x1 . Z ) ;
CollisionParticles . X ( 3 ) = Chaos : : FVec3 ( x2 . X , x1 . Y , x1 . Z ) ;
CollisionParticles . X ( 4 ) = Chaos : : FVec3 ( x2 . X , x2 . Y , x2 . Z ) ;
CollisionParticles . X ( 5 ) = Chaos : : FVec3 ( x2 . X , x2 . Y , x1 . Z ) ;
CollisionParticles . X ( 6 ) = Chaos : : FVec3 ( x2 . X , x1 . Y , x2 . Z ) ;
CollisionParticles . X ( 7 ) = Chaos : : FVec3 ( x1 . X , x2 . Y , x2 . Z ) ;
2019-06-08 17:15:34 -04:00
}
}
else
{
// We don't support anything else for sweeps
ensureMsgf ( false , TEXT ( " Unsupported query type used for sweep " ) ) ;
return ;
}
2019-08-02 09:01:58 -04:00
const TArray < Chaos : : FPhysicsSolver * > & Solvers = FChaosSolversModule : : GetModule ( ) - > GetSolvers ( ) ;
2019-06-08 17:15:34 -04:00
2019-08-02 09:01:58 -04:00
for ( const Chaos : : FPhysicsSolver * Solver : Solvers )
2019-06-08 17:15:34 -04:00
{
if ( ! Solver )
{
continue ;
}
TArray < int32 > IntersectionSet = GetIntersectionsFunc ( Solver , CollisionParticles , DeltaMag , StartTM ) ;
2019-08-02 09:01:58 -04:00
const Chaos : : FPhysicsSolver : : FPhysicsProxyReverseMapping & ObjectMap = Solver - > GetPhysicsProxyReverseMapping_GameThread ( ) ;
2021-02-18 18:13:28 -04:00
const Chaos : : FClusterBuffer & Buffer = Solver - > GetRigidClustering ( ) . GetBufferedData ( ) ;
2019-06-08 17:15:34 -04:00
int32 IntersectionSetSize = IntersectionSet . Num ( ) ;
for ( int32 i = 0 ; i < IntersectionSet . Num ( ) ; + + i )
{
SCOPE_CYCLE_COUNTER ( STAT_SQSweepNarrowPhase )
const int32 ParticleIndex = IntersectionSet [ i ] ;
2019-08-02 09:01:58 -04:00
const PhysicsProxyWrapper & ObjectWrapper = ObjectMap . PhysicsProxyReverseMappingArray [ ParticleIndex ] ;
2019-06-08 17:15:34 -04:00
2019-08-02 09:01:58 -04:00
if ( ! ObjectWrapper . PhysicsProxy )
2019-06-08 17:15:34 -04:00
{
2019-10-31 17:28:08 -04:00
const FImplicitObject * Object = Buffer . GeometryPtrs [ ParticleIndex ] . Get ( ) ;
2019-06-08 17:15:34 -04:00
// Ignore ground plane
if ( ParticleIndex = = 0 & & Object - > GetType ( true ) = = ImplicitObjectType : : Plane )
{
continue ;
}
if ( Object & & ! UseSlowSQ & & Object - > IsUnderlyingUnion ( ) )
{
2021-03-18 15:20:03 -04:00
const FImplicitObjectUnion * Union = static_cast < const TImplicitObjectUnion < Chaos : : FReal , 3 > * > ( Object ) ;
2019-06-08 17:15:34 -04:00
//hack: this is terrible because we have no buffered transform so could be off, but most of the time these things are static
{
2021-03-18 15:20:03 -04:00
const FRigidTransform3 * TMPtr = Buffer . ClusterParentTransforms . Find ( ParticleIndex ) ;
2019-06-08 17:15:34 -04:00
if ( ensure ( TMPtr ) )
{
if ( ! ( ensure ( ! FMath : : IsNaN ( TMPtr - > GetTranslation ( ) . X ) ) & & ensure ( ! FMath : : IsNaN ( TMPtr - > GetTranslation ( ) . Y ) ) & & ensure ( ! FMath : : IsNaN ( TMPtr - > GetTranslation ( ) . Z ) ) ) )
{
continue ;
}
2021-02-03 14:57:28 -04:00
const FVec3 StartLocal = TMPtr - > InverseTransformPositionNoScale ( StartTM . GetLocation ( ) ) ;
const FVec3 DirLocal = TMPtr - > InverseTransformVectorNoScale ( Dir ) ;
const FVec3 EndLocal = StartLocal + DirLocal * DeltaMag ;
2021-03-18 15:20:03 -04:00
Chaos : : TSpatialRay < Chaos : : FReal , 3 > LocalRay ( StartLocal , EndLocal ) ;
2019-06-08 17:15:34 -04:00
const TArray < int32 > IntersectingChildren = Union - > FindAllIntersectingChildren ( LocalRay ) ;
IntersectionSet . Append ( IntersectingChildren ) ;
}
else
{
UE_LOG ( LogChaos , Warning , TEXT ( " SQ: Could not find a valid transform for a cluster parent for faster child intersections. " ) ) ;
}
}
}
else
{
if ( ensure ( Buffer . MChildren . Contains ( ParticleIndex ) ) )
{
const TArray < uint32 > & Children = Buffer . MChildren [ ParticleIndex ] ;
for ( const uint32 Child : Children )
{
IntersectionSet . Add ( Child ) ;
}
}
}
continue ;
}
2019-08-02 09:01:58 -04:00
if ( ObjectWrapper . Type = = EPhysicsProxyType : : GeometryCollectionType & & ensure ( ObjectWrapper . PhysicsProxy ) )
2019-06-08 17:15:34 -04:00
{
2019-08-02 09:01:58 -04:00
if ( LowLevelSweepSingleElement ( ParticleIndex , Solver , Buffer , static_cast < FGeometryCollectionPhysicsProxy * > ( ObjectWrapper . PhysicsProxy ) , * Implicit , CollisionParticles , StartTM , Dir , DeltaMag , i > = IntersectionSetSize , Hit ) )
2019-06-08 17:15:34 -04:00
{
//todo(mlentine): This is duplicated from above and should be merged
//todo(ocohen):hack placeholder while we convert over to non physx API
2019-08-02 09:01:58 -04:00
UGeometryCollectionComponent * Component = Cast < UGeometryCollectionComponent > ( ObjectWrapper . PhysicsProxy - > GetOwner ( ) ) ;
2019-06-08 17:15:34 -04:00
check ( Component ) ;
if ( Component - > IsRegistered ( ) )
{
2019-09-04 15:28:59 -04:00
# if !WITH_IMMEDIATE_PHYSX && PHYSICS_INTERFACE_PHYSX
2019-06-08 17:15:34 -04:00
const FPhysicsActorHandle & ActorHandle = Component - > DummyBodyInstance . GetPhysicsActorHandle ( ) ;
PxRigidActor * PRigidActor = ActorHandle . SyncActor ;
uint32 PNumShapes = PRigidActor - > getNbShapes ( ) ;
TArray < PxShape * > PShapes ;
PShapes . AddZeroed ( PNumShapes ) ;
PRigidActor - > getShapes ( PShapes . GetData ( ) , sizeof ( PShapes [ 0 ] ) * PNumShapes ) ;
SetActor ( Hit , ActorHandle . SyncActor ) ;
SetShape ( Hit , PShapes [ 0 ] ) ;
# else
check ( false ) ; //this can't actually return nullptr since higher up API assumes both shape and actor exists in the low level
SetActor ( Hit , nullptr ) ;
SetShape ( Hit , nullptr ) ; //todo(ocohen): what do we return for apeiron?
# endif
Insert ( HitBuffer , Hit , true ) ; //for now assume all blocking hits
}
}
}
}
Solver - > GetRigidClustering ( ) . ReleaseBufferedData ( ) ;
2019-08-02 09:01:58 -04:00
Solver - > ReleasePhysicsProxyReverseMapping ( ) ;
2018-12-12 11:25:29 -05:00
}
# endif
}
2021-02-18 18:13:28 -04:00
bool LowLevelOverlapSingleElement ( int32 InParticleIndex , const Chaos : : FPhysicsSolver * InSolver , const Chaos : : FClusterBuffer & ClusterBuffer , const FGeometryCollectionPhysicsProxy * InObject , const Chaos : : FImplicitObject & QueryGeom , const FTransform & InPose , FHitOverlap & OutHit )
2018-12-12 11:25:29 -05:00
{
2019-06-08 17:15:34 -04:00
using namespace Chaos ;
checkSlow ( InSolver ) ;
checkSlow ( InObject ) ;
const FGeometryCollectionResults & PhysResult = InObject - > GetPhysicsResults ( ) . GetGameDataForRead ( ) ;
const TManagedArray < int32 > & RigidBodyIdArray = PhysResult . RigidBodyIds ;
const TManagedArray < FTransform > & TransformArray = PhysResult . Transforms ;
const TArray < bool > & DisabledFlags = PhysResult . DisabledStates ;
2021-03-18 15:20:03 -04:00
const TPBDRigidParticles < Chaos : : FReal , 3 > & Particles = InSolver - > GetRigidParticles ( ) ;
2019-06-08 17:15:34 -04:00
if ( ! IsValidIndexAndTransform ( PhysResult , Particles , TransformArray , DisabledFlags , InParticleIndex , false ) )
{
return false ;
}
const int32 LocalBodyIndex = InParticleIndex - PhysResult . BaseIndex ;
2021-03-18 15:20:03 -04:00
const FRigidTransform3 & TM = PhysResult . ParticleToWorldTransforms [ LocalBodyIndex ] ;
2019-10-31 17:28:08 -04:00
const FImplicitObject * Object = ClusterBuffer . GeometryPtrs [ InParticleIndex ] . Get ( ) ;
2019-06-08 17:15:34 -04:00
if ( ! Object )
{
return false ;
}
2021-03-18 15:20:03 -04:00
Pair < FVec3 , bool > Result = QueryGeom . FindDeepestIntersection ( Object , Particles . CollisionParticles ( InParticleIndex ) . Get ( ) , FRigidTransform3 ( TM ) * FRigidTransform3 ( InPose ) . Inverse ( ) , 0 ) ;
2019-06-08 17:15:34 -04:00
return Result . Second ;
2018-12-12 11:25:29 -05:00
}
2019-08-02 09:01:58 -04:00
2019-10-31 17:28:08 -04:00
void FGeometryCollectionSQAccelerator : : Overlap ( const Chaos : : FImplicitObject & QueryGeom , const FTransform & GeomPose , ChaosInterface : : FSQHitBuffer < ChaosInterface : : FOverlapHit > & HitBuffer , const FQueryFilterData & QueryFilterData , ICollisionQueryFilterCallbackBase & QueryCallback ) const
2018-12-12 11:25:29 -05:00
{
2019-06-08 17:15:34 -04:00
return ; //todo: This is currently broken because it doesn'thandle cluster unions. Need to fix function - disabling entirely for now
SCOPE_CYCLE_COUNTER ( STAT_GCOverlap ) ;
FChaosScopeSolverLock SolverScopeLock ;
# if WITH_PHYSX
2019-08-02 09:01:58 -04:00
TMap < const Chaos : : FPhysicsSolver * , TArray < int32 > > SolverIntersectionSets ;
2019-06-08 17:15:34 -04:00
// Getter for intersections from the mapping above
2019-10-31 17:28:08 -04:00
auto GetIntersectionsFunc = [ & ] ( const Chaos : : FPhysicsSolver * InSolver , Chaos : : FImplicitObject * InGeometry , const FTransform & InPose ) - > TArray < int32 > *
2019-06-08 17:15:34 -04:00
{
TArray < int32 > * CurrentIntersections = SolverIntersectionSets . Find ( InSolver ) ;
if ( ! CurrentIntersections )
{
// This is safe to access here, it's buffered from the physics thread
SolverIntersectionSets . Add ( InSolver , InSolver - > GetSpatialAcceleration ( ) - > FindAllIntersections ( InGeometry - > BoundingBox ( ) . TransformedBox ( GeomPose ) ) ) ;
InSolver - > ReleaseSpatialAcceleration ( ) ;
}
return SolverIntersectionSets . Find ( InSolver ) ;
} ;
// Need somewhere to store our translated shape, similar to the PhysX geom holder
struct FLocalImplicitStorage
{
FLocalImplicitStorage ( )
: Capsule ( FVector : : ZeroVector , FVector : : ZeroVector , 0.0f )
, Sphere ( FVector : : ZeroVector , 0.0f )
, Box ( FVector : : ZeroVector , FVector : : ZeroVector )
{ }
2021-03-05 19:27:14 -04:00
Chaos : : FCapsule Capsule ;
2021-03-18 15:20:03 -04:00
Chaos : : TSphere < Chaos : : FReal , 3 > Sphere ;
2021-02-18 18:13:28 -04:00
Chaos : : FAABB3 Box ;
2019-06-08 17:15:34 -04:00
} ;
FLocalImplicitStorage ImplicitStorage ;
bool bHit = false ;
FHitOverlap Hit ;
PxGeometryHolder Holder ( QueryGeom ) ;
2019-10-31 17:28:08 -04:00
Chaos : : FImplicitObject * Implicit = nullptr ;
2019-06-08 17:15:34 -04:00
if ( Holder . getType ( ) = = PxGeometryType : : eCAPSULE )
{
physx : : PxCapsuleGeometry & PxCapsule = Holder . capsule ( ) ;
2021-03-18 15:20:03 -04:00
Chaos : : FReal Radius = PxCapsule . radius ;
Chaos : : FReal HalfHeight = PxCapsule . halfHeight - Radius ;
2021-02-03 14:57:28 -04:00
Chaos : : FVec3 x1 ( - HalfHeight , 0 , 0 ) ;
Chaos : : FVec3 x2 ( HalfHeight , 0 , 0 ) ;
2021-03-05 19:27:14 -04:00
Chaos : : FCapsule Capsule ( x1 , x2 , Radius ) ;
2019-06-08 17:15:34 -04:00
ImplicitStorage . Capsule = MoveTemp ( Capsule ) ;
Implicit = & ImplicitStorage . Capsule ;
}
else if ( Holder . getType ( ) = = PxGeometryType : : eSPHERE )
{
physx : : PxSphereGeometry & PxSphere = Holder . sphere ( ) ;
2021-03-18 15:20:03 -04:00
Chaos : : FReal Radius = PxSphere . radius ;
Chaos : : TSphere < Chaos : : FReal , 3 > Sphere ( Chaos : : FVec3 ( 0 ) , Radius ) ;
2019-06-08 17:15:34 -04:00
ImplicitStorage . Sphere = MoveTemp ( Sphere ) ;
Implicit = & ImplicitStorage . Sphere ;
}
else if ( Holder . getType ( ) = = PxGeometryType : : eBOX )
{
physx : : PxBoxGeometry & PxBox = Holder . box ( ) ;
2021-02-03 14:57:28 -04:00
Chaos : : FVec3 x1 ( - P2UVector ( PxBox . halfExtents ) ) ;
Chaos : : FVec3 x2 ( - x1 ) ;
2021-02-18 18:13:28 -04:00
Chaos : : FAABB3 Box ( x1 , x2 ) ;
2019-06-08 17:15:34 -04:00
ImplicitStorage . Box = MoveTemp ( Box ) ;
Implicit = & ImplicitStorage . Box ;
}
else
{
ensureMsgf ( false , TEXT ( " Unsupported query type used for overlap " ) ) ;
return ;
}
FChaosSolversModule * Module = FChaosSolversModule : : GetModule ( ) ;
2019-08-02 09:01:58 -04:00
const TArray < Chaos : : FPhysicsSolver * > Solvers = Module - > GetSolvers ( ) ;
2019-06-08 17:15:34 -04:00
2019-08-02 09:01:58 -04:00
for ( const Chaos : : FPhysicsSolver * Solver : Solvers )
2019-06-08 17:15:34 -04:00
{
// Collect all intersections for this solver
TArray < int32 > IntersectionSet = Solver - > GetSpatialAcceleration ( ) - > FindAllIntersections ( Implicit - > BoundingBox ( ) . TransformedBox ( GeomPose ) ) ;
Solver - > ReleaseSpatialAcceleration ( ) ;
2019-08-02 09:01:58 -04:00
const Chaos : : FPhysicsSolver : : FPhysicsProxyReverseMapping & ObjectMap = Solver - > GetPhysicsProxyReverseMapping_GameThread ( ) ;
2019-06-08 17:15:34 -04:00
2021-02-18 18:13:28 -04:00
const Chaos : : FClusterBuffer & ClusterBuffer = Solver - > GetRigidClustering ( ) . GetBufferedData ( ) ;
2019-06-08 17:15:34 -04:00
for ( int32 i = 0 ; i < IntersectionSet . Num ( ) ; + + i )
{
const int32 IntersectParticleIndex = IntersectionSet [ i ] ;
2019-08-02 09:01:58 -04:00
const PhysicsProxyWrapper & ObjectWrapper = ObjectMap . PhysicsProxyReverseMappingArray [ IntersectParticleIndex ] ;
2019-06-08 17:15:34 -04:00
2019-08-02 09:01:58 -04:00
if ( ObjectWrapper . Type = = EPhysicsProxyType : : GeometryCollectionType & & ensure ( ObjectWrapper . PhysicsProxy ) )
2019-06-08 17:15:34 -04:00
{
2019-08-02 09:01:58 -04:00
if ( LowLevelOverlapSingleElement ( IntersectParticleIndex , Solver , ClusterBuffer , static_cast < FGeometryCollectionPhysicsProxy * > ( ObjectWrapper . PhysicsProxy ) , * Implicit , GeomPose , Hit ) )
2019-06-08 17:15:34 -04:00
{
//todo(mlentine): This is duplicated from above and should be merged
//todo(ocohen):hack placeholder while we convert over to non physx API
2019-08-02 09:01:58 -04:00
UGeometryCollectionComponent * Component = Cast < UGeometryCollectionComponent > ( ObjectWrapper . PhysicsProxy - > GetOwner ( ) ) ;
2019-06-08 17:15:34 -04:00
check ( Component ) ;
if ( Component - > IsRegistered ( ) )
{
2019-09-04 15:28:59 -04:00
# if !WITH_IMMEDIATE_PHYSX && PHYSICS_INTERFACE_PHYSX
2019-06-08 17:15:34 -04:00
const FPhysicsActorHandle & ActorHandle = Component - > DummyBodyInstance . GetPhysicsActorHandle ( ) ;
PxRigidActor * PRigidActor = ActorHandle . SyncActor ;
uint32 PNumShapes = PRigidActor - > getNbShapes ( ) ;
TArray < PxShape * > PShapes ;
PShapes . AddZeroed ( PNumShapes ) ;
PRigidActor - > getShapes ( PShapes . GetData ( ) , sizeof ( PShapes [ 0 ] ) * PNumShapes ) ;
SetActor ( Hit , ActorHandle . SyncActor ) ;
SetShape ( Hit , PShapes [ 0 ] ) ;
# else
check ( false ) ; //this can't actually return nullptr since higher up API assumes both shape and actor exists in the low level
SetActor ( Hit , nullptr ) ;
SetShape ( Hit , nullptr ) ; //todo(ocohen): what do we return for apeiron?
# endif
InsertOverlap ( HitBuffer , Hit ) ;
}
}
}
}
Solver - > GetRigidClustering ( ) . ReleaseBufferedData ( ) ;
2019-08-02 09:01:58 -04:00
Solver - > ReleasePhysicsProxyReverseMapping ( ) ;
2019-06-08 17:15:34 -04:00
}
# endif
2018-12-12 11:25:29 -05:00
}
2019-08-02 09:01:58 -04:00
# endif // TODO_REIMPLEMENT_SCENEQUERY_CROSSENGINE
2018-12-12 11:25:29 -05:00
void FGeometryCollectionSQAccelerator : : AddComponent ( UGeometryCollectionComponent * Component )
{
2019-06-08 17:15:34 -04:00
if ( ensure ( Component ) )
{
// UE_LOG(LogTemp, Log, TEXT("SQAccel: Adding %s (Outer %s)"), *GetNameSafe(Component), *GetNameSafe(Component->GetOuter()));
Components . Add ( Component ) ;
}
2018-12-12 11:25:29 -05:00
}
void FGeometryCollectionSQAccelerator : : RemoveComponent ( UGeometryCollectionComponent * Component )
{
2019-06-08 17:15:34 -04:00
if ( ensure ( Component ) )
{
// UE_LOG(LogTemp, Log, TEXT("SQAccel: Removing %s (Outer %s)"), *GetNameSafe(Component), *GetNameSafe(Component->GetOuter()));
Components . Remove ( Component ) ;
}
2018-12-12 11:25:29 -05:00
}
2019-06-08 17:15:34 -04:00
# endif