2020-08-11 01:36:57 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "Chaos/ChaosEngineInterface.h"
# include "PhysicalMaterials/PhysicalMaterial.h"
# include "PhysicsSettingsCore.h"
# include "PhysicsPublicCore.h"
# include "BodyInstanceCore.h"
# include "Chaos/ChaosScene.h"
2020-11-24 18:42:39 -04:00
# include "Chaos/KinematicTargets.h"
# include "PhysicsInterfaceDeclaresCore.h"
2022-12-07 19:57:03 -05:00
# include "PhysicsObjectPhysicsCoreInterface.h"
2020-08-11 01:36:57 -04:00
FPhysicsDelegatesCore : : FOnUpdatePhysXMaterial FPhysicsDelegatesCore : : OnUpdatePhysXMaterial ;
# include "ChaosInterfaceWrapperCore.h"
# include "Chaos/TriangleMeshImplicitObject.h"
# include "Chaos/Sphere.h"
# include "Chaos/Capsule.h"
# include "Chaos/Convex.h"
# include "CollisionShape.h"
2021-02-03 14:57:28 -04:00
# include "Chaos/ParticleHandleFwd.h"
2020-08-11 01:36:57 -04:00
# include "Chaos/PBDJointConstraintData.h"
2020-09-24 00:43:27 -04:00
# include "Chaos/PBDSuspensionConstraintData.h"
# include "Chaos/Collision/CollisionConstraintFlags.h"
# include "PhysicsProxy/SingleParticlePhysicsProxy.h"
2022-04-27 07:14:48 -04:00
# include "Chaos/ImplicitObject.h"
2023-07-31 17:46:47 -04:00
# include "Chaos/ImplicitObjectUnion.h"
2022-12-07 19:57:03 -05:00
# include "Chaos/PhysicsObjectInterface.h"
2020-08-11 01:36:57 -04:00
# include "PBDRigidsSolver.h"
2021-02-03 14:57:28 -04:00
# include "PhysicsProxy/SingleParticlePhysicsProxy.h"
2022-04-27 07:14:48 -04:00
# include "Chaos/CastingUtilities.h"
2024-03-25 13:40:21 -04:00
# include "Math/UnitConversion.h"
2020-08-11 01:36:57 -04:00
2023-02-23 05:05:35 -05:00
namespace Chaos
{
extern CHAOS_API int32 AccelerationStructureSplitStaticAndDynamic ;
extern CHAOS_API int32 AccelerationStructureIsolateQueryOnlyObjects ;
2023-04-27 13:26:51 -04:00
extern CHAOS_API int32 SyncKinematicOnGameThread ;
2023-02-23 05:05:35 -05:00
}
2020-09-01 14:07:48 -04:00
bool bEnableChaosJointConstraints = true ;
2020-08-11 01:36:57 -04:00
FAutoConsoleVariableRef CVarEnableChaosJointConstraints ( TEXT ( " p.ChaosSolverEnableJointConstraints " ) , bEnableChaosJointConstraints , TEXT ( " Enable Joint Constraints defined within the Physics Asset Editor " ) ) ;
2020-12-15 14:10:39 -04:00
bool bEnableChaosCollisionManager = true ;
2020-11-24 18:42:39 -04:00
FAutoConsoleVariableRef CVarEnableChaosCollisionManager ( TEXT ( " p.Chaos.Collision.EnableCollisionManager " ) , bEnableChaosCollisionManager , TEXT ( " Enable Chaos's Collision Manager for ignoring collisions between rigid bodies. [def:1] " ) ) ;
2020-08-11 01:36:57 -04:00
bool FPhysicsConstraintReference_Chaos : : IsValid ( ) const
{
return Constraint ! = nullptr ? Constraint - > IsValid ( ) : false ;
}
const Chaos : : FImplicitObject & FPhysicsShapeReference_Chaos : : GetGeometry ( ) const
{
check ( IsValid ( ) ) ; return * Shape - > GetGeometry ( ) ;
}
FPhysicsGeometryCollection_Chaos : : ~ FPhysicsGeometryCollection_Chaos ( ) = default ;
FPhysicsGeometryCollection_Chaos : : FPhysicsGeometryCollection_Chaos ( FPhysicsGeometryCollection_Chaos & & Steal ) = default ;
ECollisionShapeType FPhysicsGeometryCollection_Chaos : : GetType ( ) const
{
2022-11-02 14:19:06 -04:00
return ChaosInterface : : GetImplicitType ( Geom ) ;
2020-08-11 01:36:57 -04:00
}
const Chaos : : FImplicitObject & FPhysicsGeometryCollection_Chaos : : GetGeometry ( ) const
{
return Geom ;
}
2022-04-27 07:14:48 -04:00
template < typename InnerType >
const InnerType & GetInnerGeometryChecked ( const Chaos : : FImplicitObject & InGeometry )
{
const Chaos : : FImplicitObject & InnerObject = Chaos : : Utilities : : CastHelper ( InGeometry ,
[ ] ( const Chaos : : FImplicitObject & CastGeom ) - > const Chaos : : FImplicitObject &
{
return CastGeom ;
} ) ;
return InnerObject . GetObjectChecked < InnerType > ( ) ;
}
2021-03-18 15:20:03 -04:00
const Chaos : : TBox < Chaos : : FReal , 3 > & FPhysicsGeometryCollection_Chaos : : GetBoxGeometry ( ) const
2020-08-11 01:36:57 -04:00
{
2022-04-27 07:14:48 -04:00
return GetInnerGeometryChecked < Chaos : : TBox < Chaos : : FReal , 3 > > ( Geom ) ;
2020-08-11 01:36:57 -04:00
}
2021-03-18 15:20:03 -04:00
const Chaos : : TSphere < Chaos : : FReal , 3 > & FPhysicsGeometryCollection_Chaos : : GetSphereGeometry ( ) const
2020-08-11 01:36:57 -04:00
{
2022-04-27 07:14:48 -04:00
return GetInnerGeometryChecked < Chaos : : TSphere < Chaos : : FReal , 3 > > ( Geom ) ;
2020-08-11 01:36:57 -04:00
}
2021-03-05 19:27:14 -04:00
const Chaos : : FCapsule & FPhysicsGeometryCollection_Chaos : : GetCapsuleGeometry ( ) const
2020-08-11 01:36:57 -04:00
{
2022-04-27 07:14:48 -04:00
return GetInnerGeometryChecked < Chaos : : FCapsule > ( Geom ) ;
2020-08-11 01:36:57 -04:00
}
const Chaos : : FConvex & FPhysicsGeometryCollection_Chaos : : GetConvexGeometry ( ) const
{
2022-04-27 07:14:48 -04:00
return GetInnerGeometryChecked < Chaos : : FConvex > ( Geom ) ;
2020-08-11 01:36:57 -04:00
}
const Chaos : : FTriangleMeshImplicitObject & FPhysicsGeometryCollection_Chaos : : GetTriMeshGeometry ( ) const
{
2022-04-27 07:14:48 -04:00
return GetInnerGeometryChecked < Chaos : : FTriangleMeshImplicitObject > ( Geom ) ;
2020-08-11 01:36:57 -04:00
}
FPhysicsGeometryCollection_Chaos : : FPhysicsGeometryCollection_Chaos ( const FPhysicsShapeReference_Chaos & InShape )
: Geom ( InShape . GetGeometry ( ) )
{
}
2023-05-17 19:11:33 -04:00
FPhysicsGeometryCollection_Chaos : : FPhysicsGeometryCollection_Chaos ( const FPhysicsGeometry & InGeom )
: Geom ( InGeom )
{
}
2020-08-11 01:36:57 -04:00
FPhysicsShapeAdapter_Chaos : : FPhysicsShapeAdapter_Chaos ( const FQuat & Rot , const FCollisionShape & CollisionShape )
: GeometryRotation ( Rot )
{
switch ( CollisionShape . ShapeType )
{
case ECollisionShape : : Capsule :
{
const float CapsuleRadius = CollisionShape . GetCapsuleRadius ( ) ;
const float CapsuleHalfHeight = CollisionShape . GetCapsuleHalfHeight ( ) ;
if ( CapsuleRadius < CapsuleHalfHeight )
{
const float UseHalfHeight = FMath : : Max ( CollisionShape . GetCapsuleAxisHalfLength ( ) , FCollisionShape : : MinCapsuleAxisHalfHeight ( ) ) ;
const FVector Bot = FVector ( 0.f , 0.f , - UseHalfHeight ) ;
const FVector Top = FVector ( 0.f , 0.f , UseHalfHeight ) ;
const float UseRadius = FMath : : Max ( CapsuleRadius , FCollisionShape : : MinCapsuleRadius ( ) ) ;
2023-07-31 17:46:47 -04:00
Geometry = TRefCountPtr < FPhysicsGeometry > ( new Chaos : : FCapsule ( Bot , Top , UseRadius ) ) ;
2020-08-11 01:36:57 -04:00
} else
{
// Use a sphere instead.
const float UseRadius = FMath : : Max ( CapsuleRadius , FCollisionShape : : MinSphereRadius ( ) ) ;
2023-07-31 17:46:47 -04:00
Geometry = TRefCountPtr < FPhysicsGeometry > ( new Chaos : : TSphere < Chaos : : FReal , 3 > ( Chaos : : FVec3 ( 0 ) , UseRadius ) ) ;
2020-08-11 01:36:57 -04:00
}
break ;
}
case ECollisionShape : : Box :
{
2021-02-03 14:57:28 -04:00
Chaos : : FVec3 HalfExtents = CollisionShape . GetBox ( ) ;
2020-08-11 01:36:57 -04:00
HalfExtents . X = FMath : : Max ( HalfExtents . X , FCollisionShape : : MinBoxExtent ( ) ) ;
HalfExtents . Y = FMath : : Max ( HalfExtents . Y , FCollisionShape : : MinBoxExtent ( ) ) ;
HalfExtents . Z = FMath : : Max ( HalfExtents . Z , FCollisionShape : : MinBoxExtent ( ) ) ;
2023-07-31 17:46:47 -04:00
Geometry = TRefCountPtr < FPhysicsGeometry > ( new Chaos : : TBox < Chaos : : FReal , 3 > ( - HalfExtents , HalfExtents ) ) ;
2020-08-11 01:36:57 -04:00
break ;
}
case ECollisionShape : : Sphere :
{
const float UseRadius = FMath : : Max ( CollisionShape . GetSphereRadius ( ) , FCollisionShape : : MinSphereRadius ( ) ) ;
2023-07-31 17:46:47 -04:00
Geometry = TRefCountPtr < FPhysicsGeometry > ( new Chaos : : TSphere < Chaos : : FReal , 3 > ( Chaos : : FVec3 ( 0 ) , UseRadius ) ) ;
2020-08-11 01:36:57 -04:00
break ;
}
default :
ensure ( false ) ;
break ;
}
}
FPhysicsShapeAdapter_Chaos : : ~ FPhysicsShapeAdapter_Chaos ( ) = default ;
const FPhysicsGeometry & FPhysicsShapeAdapter_Chaos : : GetGeometry ( ) const
{
return * Geometry ;
}
FTransform FPhysicsShapeAdapter_Chaos : : GetGeomPose ( const FVector & Pos ) const
{
return FTransform ( GeometryRotation , Pos ) ;
}
const FQuat & FPhysicsShapeAdapter_Chaos : : GetGeomOrientation ( ) const
{
return GeometryRotation ;
}
void FChaosEngineInterface : : AddActorToSolver ( FPhysicsActorHandle & Handle , Chaos : : FPhysicsSolver * Solver )
{
Solver - > RegisterObject ( Handle ) ;
}
void FChaosEngineInterface : : RemoveActorFromSolver ( FPhysicsActorHandle & Handle , Chaos : : FPhysicsSolver * Solver )
{
2021-02-03 14:57:28 -04:00
// Should we stop passing solver in? (need to check it's not null regardless in case proxy was never registered)
if ( Solver & & Handle & & Handle - > GetSolverBase ( ) = = Solver )
2020-08-11 01:36:57 -04:00
{
Solver - > UnregisterObject ( Handle ) ;
}
2021-02-03 14:57:28 -04:00
else
{
delete Handle ;
}
2020-08-11 01:36:57 -04:00
}
// Aggregate is not relevant for Chaos yet
FPhysicsAggregateReference_Chaos FChaosEngineInterface : : CreateAggregate ( int32 MaxBodies )
{
// #todo : Implement
FPhysicsAggregateReference_Chaos NewAggregate ;
return NewAggregate ;
}
void FChaosEngineInterface : : ReleaseAggregate ( FPhysicsAggregateReference_Chaos & InAggregate ) { }
int32 FChaosEngineInterface : : GetNumActorsInAggregate ( const FPhysicsAggregateReference_Chaos & InAggregate ) { return 0 ; }
void FChaosEngineInterface : : AddActorToAggregate_AssumesLocked ( const FPhysicsAggregateReference_Chaos & InAggregate , const FPhysicsActorHandle & InActor ) { }
Chaos : : FChaosPhysicsMaterial : : ECombineMode UToCCombineMode ( EFrictionCombineMode : : Type Mode )
{
using namespace Chaos ;
switch ( Mode )
{
case EFrictionCombineMode : : Average : return FChaosPhysicsMaterial : : ECombineMode : : Avg ;
case EFrictionCombineMode : : Min : return FChaosPhysicsMaterial : : ECombineMode : : Min ;
case EFrictionCombineMode : : Multiply : return FChaosPhysicsMaterial : : ECombineMode : : Multiply ;
case EFrictionCombineMode : : Max : return FChaosPhysicsMaterial : : ECombineMode : : Max ;
default : ensure ( false ) ;
}
return FChaosPhysicsMaterial : : ECombineMode : : Avg ;
}
FPhysicsMaterialHandle FChaosEngineInterface : : CreateMaterial ( const UPhysicalMaterial * InMaterial )
{
Chaos : : FMaterialHandle NewHandle = Chaos : : FPhysicalMaterialManager : : Get ( ) . Create ( ) ;
return NewHandle ;
}
void FChaosEngineInterface : : UpdateMaterial ( FPhysicsMaterialHandle & InHandle , UPhysicalMaterial * InMaterial )
{
if ( Chaos : : FChaosPhysicsMaterial * Material = InHandle . Get ( ) )
{
Material - > Friction = InMaterial - > Friction ;
2020-09-01 14:07:48 -04:00
Material - > StaticFriction = InMaterial - > StaticFriction ;
2020-08-11 01:36:57 -04:00
Material - > FrictionCombineMode = UToCCombineMode ( InMaterial - > FrictionCombineMode ) ;
Material - > Restitution = InMaterial - > Restitution ;
Material - > RestitutionCombineMode = UToCCombineMode ( InMaterial - > RestitutionCombineMode ) ;
2023-08-08 15:22:55 -04:00
Material - > Density = InMaterial - > Density ;
2020-08-11 01:36:57 -04:00
Material - > SleepingLinearThreshold = InMaterial - > SleepLinearVelocityThreshold ;
Material - > SleepingAngularThreshold = InMaterial - > SleepAngularVelocityThreshold ;
Material - > SleepCounterThreshold = InMaterial - > SleepCounterThreshold ;
2023-04-28 15:34:17 -04:00
Material - > Strength . TensileStrength = Chaos : : MegaPascalToKgPerCmS2 ( InMaterial - > Strength . TensileStrength ) ;
Material - > Strength . CompressionStrength = Chaos : : MegaPascalToKgPerCmS2 ( InMaterial - > Strength . CompressionStrength ) ;
Material - > Strength . ShearStrength = Chaos : : MegaPascalToKgPerCmS2 ( InMaterial - > Strength . ShearStrength ) ;
2023-08-08 11:31:47 -04:00
Material - > DamageModifier . DamageThresholdMultiplier = InMaterial - > DamageModifier . DamageThresholdMultiplier ;
2024-03-25 13:40:21 -04:00
Material - > BaseFrictionImpulse = InMaterial - > BaseFrictionImpulse ;
Material - > SoftCollisionMode = ( Chaos : : EChaosPhysicsMaterialSoftCollisionMode ) InMaterial - > SoftCollisionMode ;
Material - > SoftCollisionThickness = InMaterial - > SoftCollisionThickness ;
2020-08-11 01:36:57 -04:00
}
Chaos : : FPhysicalMaterialManager : : Get ( ) . UpdateMaterial ( InHandle ) ;
}
void FChaosEngineInterface : : ReleaseMaterial ( FPhysicsMaterialHandle & InHandle )
{
Chaos : : FPhysicalMaterialManager : : Get ( ) . Destroy ( InHandle ) ;
}
void FChaosEngineInterface : : SetUserData ( const FPhysicsShapeHandle & InShape , void * InUserData )
{
if ( CHAOS_ENSURE ( InShape . Shape ) )
{
InShape . Shape - > SetUserData ( InUserData ) ;
}
}
void FChaosEngineInterface : : SetUserData ( FPhysicsMaterialHandle & InHandle , void * InUserData )
{
if ( Chaos : : FChaosPhysicsMaterial * Material = InHandle . Get ( ) )
{
Material - > UserData = InUserData ;
}
Chaos : : FPhysicalMaterialManager : : Get ( ) . UpdateMaterial ( InHandle ) ;
}
void FChaosEngineInterface : : ReleaseMaterialMask ( FPhysicsMaterialMaskHandle & InHandle )
{
Chaos : : FPhysicalMaterialManager : : Get ( ) . Destroy ( InHandle ) ;
}
void * FChaosEngineInterface : : GetUserData ( const FPhysicsShapeHandle & InShape )
{
if ( ensure ( InShape . Shape ) )
{
return InShape . Shape - > GetUserData ( ) ;
}
return nullptr ;
}
int32 FChaosEngineInterface : : GetNumShapes ( const FPhysicsActorHandle & InHandle )
{
// #todo : Implement
2021-02-03 14:57:28 -04:00
return InHandle - > GetGameThreadAPI ( ) . ShapesArray ( ) . Num ( ) ;
2020-08-11 01:36:57 -04:00
}
void FChaosEngineInterface : : ReleaseShape ( const FPhysicsShapeHandle & InShape )
{
check ( ! IsValid ( InShape . ActorRef ) ) ;
//no need to delete because ownership is on actor. Is this an invalid assumption with the current API?
//delete InShape.Shape;
}
void FChaosEngineInterface : : AttachShape ( const FPhysicsActorHandle & InActor , const FPhysicsShapeHandle & InNewShape )
{
2020-11-24 18:42:39 -04:00
// #todo : Implement - this path is never used welding actually goes through FPhysInterface_Chaos::AddGeometry
2020-08-11 01:36:57 -04:00
CHAOS_ENSURE ( false ) ;
}
void FChaosEngineInterface : : DetachShape ( const FPhysicsActorHandle & InActor , FPhysicsShapeHandle & InShape , bool bWakeTouching )
{
2020-11-24 18:42:39 -04:00
if ( CHAOS_ENSURE ( InShape . Shape ) )
{
2021-02-03 14:57:28 -04:00
InActor - > GetGameThreadAPI ( ) . RemoveShape ( InShape . Shape , bWakeTouching ) ;
2020-11-24 18:42:39 -04:00
}
2020-08-11 01:36:57 -04:00
}
2022-04-29 13:53:51 -04:00
void FChaosEngineInterface : : SetSmoothEdgeCollisionsEnabled_AssumesLocked ( const FPhysicsActorHandle & InActor , const bool bSmoothEdgeCollisionsEnabled )
2022-01-28 19:50:28 -05:00
{
InActor - > GetGameThreadAPI ( ) . SetSmoothEdgeCollisionsEnabled ( bSmoothEdgeCollisionsEnabled ) ;
}
2020-09-24 00:43:27 -04:00
void FChaosEngineInterface : : AddDisabledCollisionsFor_AssumesLocked ( const TMap < FPhysicsActorHandle , TArray < FPhysicsActorHandle > > & InMap )
{
2020-11-24 18:42:39 -04:00
if ( bEnableChaosCollisionManager )
2020-09-24 00:43:27 -04:00
{
2020-11-24 18:42:39 -04:00
for ( auto Elem : InMap )
2020-09-24 00:43:27 -04:00
{
2020-11-24 18:42:39 -04:00
FPhysicsActorHandle & ActorReference = Elem . Key ;
2021-02-03 14:57:28 -04:00
Chaos : : FUniqueIdx ActorIndex = ActorReference - > GetGameThreadAPI ( ) . UniqueIdx ( ) ;
2020-12-15 14:10:39 -04:00
2021-02-03 14:57:28 -04:00
Chaos : : FPhysicsSolver * Solver = ActorReference - > GetSolver < Chaos : : FPhysicsSolver > ( ) ;
2020-11-24 18:42:39 -04:00
Chaos : : FIgnoreCollisionManager & CollisionManager = Solver - > GetEvolution ( ) - > GetBroadPhase ( ) . GetIgnoreCollisionManager ( ) ;
int32 ExternalTimestamp = Solver - > GetMarshallingManager ( ) . GetExternalTimestamp_External ( ) ;
2020-12-15 14:10:39 -04:00
Chaos : : FIgnoreCollisionManager : : FPendingMap & ActivationMap = CollisionManager . GetPendingActivationsForGameThread ( ExternalTimestamp ) ;
if ( ActivationMap . Contains ( ActorIndex ) )
2020-11-24 18:42:39 -04:00
{
2020-12-15 14:10:39 -04:00
ActivationMap . Remove ( ActorIndex ) ;
2020-11-24 18:42:39 -04:00
}
2020-12-15 14:10:39 -04:00
TArray < Chaos : : FUniqueIdx > DisabledCollisions ;
DisabledCollisions . Reserve ( Elem . Value . Num ( ) ) ;
2021-03-05 19:27:14 -04:00
if ( Chaos : : FPBDRigidParticle * Rigid0 = ActorReference - > GetParticle_LowLevel ( ) - > CastToRigidParticle ( ) )
2020-12-15 14:10:39 -04:00
{
for ( auto Handle1 : Elem . Value )
{
2021-03-05 19:27:14 -04:00
if ( Chaos : : FPBDRigidParticle * Rigid1 = Handle1 - > GetParticle_LowLevel ( ) - > CastToRigidParticle ( ) )
2020-12-15 14:10:39 -04:00
{
2021-02-03 14:57:28 -04:00
DisabledCollisions . Add ( Handle1 - > GetGameThreadAPI ( ) . UniqueIdx ( ) ) ;
2020-12-15 14:10:39 -04:00
}
}
}
ActivationMap . Add ( ActorIndex , DisabledCollisions ) ;
2020-09-24 00:43:27 -04:00
}
}
}
void FChaosEngineInterface : : RemoveDisabledCollisionsFor_AssumesLocked ( TArray < FPhysicsActorHandle > & InPhysicsActors )
{
2020-11-24 18:42:39 -04:00
if ( bEnableChaosCollisionManager )
2020-09-24 00:43:27 -04:00
{
2020-12-15 14:10:39 -04:00
for ( FPhysicsActorHandle & ActorReference : InPhysicsActors )
2020-09-24 00:43:27 -04:00
{
2021-02-03 14:57:28 -04:00
Chaos : : FUniqueIdx ActorIndex = ActorReference - > GetGameThreadAPI ( ) . UniqueIdx ( ) ;
2020-12-15 14:10:39 -04:00
2021-02-03 14:57:28 -04:00
Chaos : : FPhysicsSolver * Solver = ActorReference - > GetSolver < Chaos : : FPhysicsSolver > ( ) ;
2020-11-24 18:42:39 -04:00
Chaos : : FIgnoreCollisionManager & CollisionManager = Solver - > GetEvolution ( ) - > GetBroadPhase ( ) . GetIgnoreCollisionManager ( ) ;
int32 ExternalTimestamp = Solver - > GetMarshallingManager ( ) . GetExternalTimestamp_External ( ) ;
2020-12-15 14:10:39 -04:00
2021-01-20 21:05:15 -04:00
Chaos : : FIgnoreCollisionManager : : FDeactivationSet & DeactivationMap = CollisionManager . GetPendingDeactivationsForGameThread ( ExternalTimestamp ) ;
2021-02-03 14:57:28 -04:00
DeactivationMap . Add ( ActorReference - > GetGameThreadAPI ( ) . UniqueIdx ( ) ) ;
2020-09-24 00:43:27 -04:00
}
}
}
2021-02-24 20:32:57 -04:00
void FChaosEngineInterface : : SetDisabled ( const FPhysicsActorHandle & InPhysicsActor , bool bSetDisabled )
{
InPhysicsActor - > GetGameThreadAPI ( ) . SetDisabled ( bSetDisabled ) ;
}
bool FChaosEngineInterface : : IsDisabled ( const FPhysicsActorHandle & InPhysicsActor )
{
return InPhysicsActor - > GetGameThreadAPI ( ) . Disabled ( ) ;
}
2020-08-11 01:36:57 -04:00
void FChaosEngineInterface : : SetActorUserData_AssumesLocked ( FPhysicsActorHandle & InActorReference , FPhysicsUserData * InUserData )
{
2021-02-03 14:57:28 -04:00
InActorReference - > GetGameThreadAPI ( ) . SetUserData ( InUserData ) ;
2020-08-11 01:36:57 -04:00
}
bool FChaosEngineInterface : : IsRigidBody ( const FPhysicsActorHandle & InActorReference )
{
return ! IsStatic ( InActorReference ) ;
}
bool FChaosEngineInterface : : IsDynamic ( const FPhysicsActorHandle & InActorReference )
{
return ! IsStatic ( InActorReference ) ;
}
bool FChaosEngineInterface : : IsStatic ( const FPhysicsActorHandle & InActorReference )
{
2022-11-22 08:25:33 -05:00
if ( FChaosEngineInterface : : IsValid ( InActorReference ) )
{
return InActorReference - > GetGameThreadAPI ( ) . ObjectState ( ) = = Chaos : : EObjectStateType : : Static ;
}
return false ;
2020-08-11 01:36:57 -04:00
}
bool FChaosEngineInterface : : IsKinematic ( const FPhysicsActorHandle & InActorReference )
{
2021-02-03 14:57:28 -04:00
return InActorReference - > GetGameThreadAPI ( ) . ObjectState ( ) = = Chaos : : EObjectStateType : : Kinematic ;
2020-08-11 01:36:57 -04:00
}
bool FChaosEngineInterface : : IsKinematic_AssumesLocked ( const FPhysicsActorHandle & InActorReference )
{
return IsKinematic ( InActorReference ) ;
}
bool FChaosEngineInterface : : IsSleeping ( const FPhysicsActorHandle & InActorReference )
{
2021-02-03 14:57:28 -04:00
return InActorReference - > GetGameThreadAPI ( ) . ObjectState ( ) = = Chaos : : EObjectStateType : : Sleeping ;
2020-08-11 01:36:57 -04:00
}
bool FChaosEngineInterface : : IsCcdEnabled ( const FPhysicsActorHandle & InActorReference )
{
2021-02-18 18:13:28 -04:00
return InActorReference - > GetGameThreadAPI ( ) . CCDEnabled ( ) ;
2020-08-11 01:36:57 -04:00
}
bool FChaosEngineInterface : : CanSimulate_AssumesLocked ( const FPhysicsActorHandle & InActorReference )
{
// #todo : Implement
return true ;
}
float FChaosEngineInterface : : GetMass_AssumesLocked ( const FPhysicsActorHandle & InActorReference )
{
2021-02-03 14:57:28 -04:00
return InActorReference - > GetGameThreadAPI ( ) . M ( ) ;
2020-08-11 01:36:57 -04:00
}
void FChaosEngineInterface : : SetSendsSleepNotifies_AssumesLocked ( const FPhysicsActorHandle & InActorReference , bool bSendSleepNotifies )
{
// # todo: Implement
//check(bSendSleepNotifies == false);
}
void FChaosEngineInterface : : PutToSleep_AssumesLocked ( const FPhysicsActorHandle & InActorReference )
{
2021-02-18 18:13:28 -04:00
// NOTE: We want to set the state whether or not it's asleep - if we currently think we're
// asleep but the physics thread has queued up a wake event, then we still need to call
// SetObjectState, so that this manual call will take priority.
Chaos : : FRigidBodyHandle_External & BodyHandle_External = InActorReference - > GetGameThreadAPI ( ) ;
if ( BodyHandle_External . ObjectState ( ) = = Chaos : : EObjectStateType : : Dynamic | | BodyHandle_External . ObjectState ( ) = = Chaos : : EObjectStateType : : Sleeping )
2020-08-11 01:36:57 -04:00
{
2021-02-03 14:57:28 -04:00
InActorReference - > GetGameThreadAPI ( ) . SetObjectState ( Chaos : : EObjectStateType : : Sleeping ) ;
2020-08-11 01:36:57 -04:00
}
}
void FChaosEngineInterface : : WakeUp_AssumesLocked ( const FPhysicsActorHandle & InActorReference )
{
2021-02-18 18:13:28 -04:00
// NOTE: We want to set the state whether or not it's asleep - if we currently think we're
// dynamic but the physics thread has queued up a sleep event, then we still need to call
// SetObjectState, so that this manual call will take priority.
2021-02-03 14:57:28 -04:00
Chaos : : FRigidBodyHandle_External & BodyHandle_External = InActorReference - > GetGameThreadAPI ( ) ;
2021-02-18 18:13:28 -04:00
if ( BodyHandle_External . ObjectState ( ) = = Chaos : : EObjectStateType : : Dynamic | | BodyHandle_External . ObjectState ( ) = = Chaos : : EObjectStateType : : Sleeping )
2020-08-11 01:36:57 -04:00
{
2021-02-03 14:57:28 -04:00
BodyHandle_External . SetObjectState ( Chaos : : EObjectStateType : : Dynamic ) ;
BodyHandle_External . ClearEvents ( ) ;
2020-08-11 01:36:57 -04:00
}
}
void FChaosEngineInterface : : SetIsKinematic_AssumesLocked ( const FPhysicsActorHandle & InActorReference , bool bIsKinematic )
{
2021-03-05 19:27:14 -04:00
using namespace Chaos ;
2020-08-11 01:36:57 -04:00
{
2021-03-05 19:27:14 -04:00
const EObjectStateType NewState
2020-08-11 01:36:57 -04:00
= bIsKinematic
2021-03-05 19:27:14 -04:00
? EObjectStateType : : Kinematic
: EObjectStateType : : Dynamic ;
2020-08-11 01:36:57 -04:00
bool AllowedToChangeToNewState = false ;
2021-02-03 14:57:28 -04:00
switch ( InActorReference - > GetGameThreadAPI ( ) . ObjectState ( ) )
2020-08-11 01:36:57 -04:00
{
2021-03-05 19:27:14 -04:00
case EObjectStateType : : Kinematic :
2020-08-11 01:36:57 -04:00
// from kinematic we can only go dynamic
2021-03-05 19:27:14 -04:00
if ( NewState = = EObjectStateType : : Dynamic )
2020-08-11 01:36:57 -04:00
{
AllowedToChangeToNewState = true ;
}
break ;
2021-03-05 19:27:14 -04:00
case EObjectStateType : : Dynamic :
2020-08-11 01:36:57 -04:00
// from dynamic we can go to sleeping or to kinematic
2021-03-05 19:27:14 -04:00
if ( NewState = = EObjectStateType : : Kinematic )
2020-08-11 01:36:57 -04:00
{
AllowedToChangeToNewState = true ;
}
break ;
2021-03-05 19:27:14 -04:00
case EObjectStateType : : Sleeping :
2020-09-01 14:07:48 -04:00
// this case was not allowed from CL 10506092, but it needs to in order for
// FBodyInstance::SetInstanceSimulatePhysics to work on dynamic bodies which
// have fallen asleep.
2021-03-05 19:27:14 -04:00
if ( NewState = = EObjectStateType : : Kinematic )
2020-09-01 14:07:48 -04:00
{
AllowedToChangeToNewState = true ;
}
2020-08-11 01:36:57 -04:00
break ;
}
if ( AllowedToChangeToNewState )
{
2021-02-03 14:57:28 -04:00
InActorReference - > GetGameThreadAPI ( ) . SetObjectState ( NewState ) ;
2021-03-05 19:27:14 -04:00
//we mark as full resim only if going from kinematic to simulated
//going from simulated to kinematic we assume user is doing some optimization so we leave it up to them
if ( NewState = = EObjectStateType : : Dynamic )
{
InActorReference - > GetGameThreadAPI ( ) . SetResimType ( EResimType : : FullResim ) ;
}
2021-04-09 09:45:06 -04:00
else if ( NewState = = Chaos : : EObjectStateType : : Kinematic )
{
// Reset velocity on a state change here
InActorReference - > GetGameThreadAPI ( ) . SetV ( Chaos : : FVec3 ( ( Chaos : : FReal ) 0 ) ) ;
InActorReference - > GetGameThreadAPI ( ) . SetW ( Chaos : : FVec3 ( ( Chaos : : FReal ) 0 ) ) ;
}
2020-08-11 01:36:57 -04:00
}
}
}
void FChaosEngineInterface : : SetCcdEnabled_AssumesLocked ( const FPhysicsActorHandle & InActorReference , bool bIsCcdEnabled )
{
2021-02-18 18:13:28 -04:00
InActorReference - > GetGameThreadAPI ( ) . SetCCDEnabled ( bIsCcdEnabled ) ;
2020-08-11 01:36:57 -04:00
}
2024-02-16 15:22:54 -05:00
void FChaosEngineInterface : : SetMACDEnabled_AssumesLocked ( const FPhysicsActorHandle & InActorReference , bool bIsMACDEnabled )
{
InActorReference - > GetGameThreadAPI ( ) . SetMACDEnabled ( bIsMACDEnabled ) ;
}
2020-08-11 01:36:57 -04:00
void FChaosEngineInterface : : SetIgnoreAnalyticCollisions_AssumesLocked ( const FPhysicsActorHandle & InActorReference , bool bIgnoreAnalyticCollisions )
{
2021-02-03 14:57:28 -04:00
InActorReference - > GetGameThreadAPI ( ) . SetIgnoreAnalyticCollisions ( bIgnoreAnalyticCollisions ) ;
2020-08-11 01:36:57 -04:00
}
FTransform FChaosEngineInterface : : GetGlobalPose_AssumesLocked ( const FPhysicsActorHandle & InActorReference )
{
2021-03-05 19:27:14 -04:00
return Chaos : : FRigidTransform3 ( InActorReference - > GetGameThreadAPI ( ) . X ( ) , InActorReference - > GetGameThreadAPI ( ) . R ( ) ) ;
2020-08-11 01:36:57 -04:00
}
FTransform FChaosEngineInterface : : GetTransform_AssumesLocked ( const FPhysicsActorHandle & InRef , bool bForceGlobalPose /*= false*/ )
{
if ( ! bForceGlobalPose )
{
if ( IsDynamic ( InRef ) )
{
if ( HasKinematicTarget_AssumesLocked ( InRef ) )
{
return GetKinematicTarget_AssumesLocked ( InRef ) ;
}
}
}
return GetGlobalPose_AssumesLocked ( InRef ) ;
}
bool FChaosEngineInterface : : HasKinematicTarget_AssumesLocked ( const FPhysicsActorHandle & InActorReference )
{
return IsStatic ( InActorReference ) ;
}
FTransform FChaosEngineInterface : : GetKinematicTarget_AssumesLocked ( const FPhysicsActorHandle & InActorReference )
{
// #todo : Implement
//for now just use global pose
return FChaosEngineInterface : : GetGlobalPose_AssumesLocked ( InActorReference ) ;
}
FVector FChaosEngineInterface : : GetLinearVelocity_AssumesLocked ( const FPhysicsActorHandle & InActorReference )
{
if ( ensure ( FChaosEngineInterface : : IsValid ( InActorReference ) ) )
{
2021-02-03 14:57:28 -04:00
return InActorReference - > GetGameThreadAPI ( ) . V ( ) ;
2020-08-11 01:36:57 -04:00
}
return FVector ( 0 ) ;
}
void FChaosEngineInterface : : SetLinearVelocity_AssumesLocked ( const FPhysicsActorHandle & InActorReference , const FVector & InNewVelocity , bool bAutoWake )
{
// TODO: Implement bAutoWake == false.
// For now we don't support auto-awake == false.
// This feature is meant to detect when velocity change small
// and the velocity is nearly zero, and to not wake up the
// body in that case.
ensure ( bAutoWake ) ;
if ( ensure ( FChaosEngineInterface : : IsValid ( InActorReference ) ) )
{
2021-02-03 14:57:28 -04:00
InActorReference - > GetGameThreadAPI ( ) . SetV ( InNewVelocity ) ;
2020-08-11 01:36:57 -04:00
}
}
FVector FChaosEngineInterface : : GetAngularVelocity_AssumesLocked ( const FPhysicsActorHandle & InActorReference )
{
if ( ensure ( FChaosEngineInterface : : IsValid ( InActorReference ) ) )
{
2021-02-03 14:57:28 -04:00
return InActorReference - > GetGameThreadAPI ( ) . W ( ) ;
2020-08-11 01:36:57 -04:00
}
return FVector ( 0 ) ;
}
void FChaosEngineInterface : : SetAngularVelocity_AssumesLocked ( const FPhysicsActorHandle & InActorReference , const FVector & InNewAngularVelocity , bool bAutoWake )
{
// TODO: Implement bAutoWake == false.
ensure ( bAutoWake ) ;
if ( ensure ( FChaosEngineInterface : : IsValid ( InActorReference ) ) )
{
2021-02-03 14:57:28 -04:00
InActorReference - > GetGameThreadAPI ( ) . SetW ( InNewAngularVelocity ) ;
2020-08-11 01:36:57 -04:00
}
}
float FChaosEngineInterface : : GetMaxAngularVelocity_AssumesLocked ( const FPhysicsActorHandle & InActorReference )
{
2021-04-06 10:45:16 -04:00
if ( ensure ( FChaosEngineInterface : : IsValid ( InActorReference ) ) )
{
return FMath : : Sqrt ( InActorReference - > GetGameThreadAPI ( ) . GetMaxAngularSpeedSq ( ) ) ;
}
return TNumericLimits < float > : : Max ( ) ;
2020-08-11 01:36:57 -04:00
}
2021-04-06 10:45:16 -04:00
float FChaosEngineInterface : : GetMaxLinearVelocity_AssumesLocked ( const FPhysicsActorHandle & InActorReference )
2020-08-11 01:36:57 -04:00
{
2021-04-06 10:45:16 -04:00
if ( ensure ( FChaosEngineInterface : : IsValid ( InActorReference ) ) )
{
return FMath : : Sqrt ( InActorReference - > GetGameThreadAPI ( ) . GetMaxLinearSpeedSq ( ) ) ;
}
return TNumericLimits < float > : : Max ( ) ;
}
void FChaosEngineInterface : : SetMaxAngularVelocity_AssumesLocked ( const FPhysicsActorHandle & InActorReference , float InMaxAngularVelocityRadians )
{
// We're about to square the input so we clamp to this maximum
static const float MaxInput = FMath : : Sqrt ( TNumericLimits < float > : : Max ( ) ) ;
if ( ensure ( FChaosEngineInterface : : IsValid ( InActorReference ) ) )
{
InActorReference - > GetGameThreadAPI ( ) . SetMaxAngularSpeedSq ( InMaxAngularVelocityRadians > MaxInput ? TNumericLimits < float > : : Max ( ) : InMaxAngularVelocityRadians * InMaxAngularVelocityRadians ) ;
}
}
void FChaosEngineInterface : : SetMaxLinearVelocity_AssumesLocked ( const FPhysicsActorHandle & InActorReference , float InMaxLinearVelocity )
{
// We're about to square the input so we clamp to this maximum
static const float MaxInput = FMath : : Sqrt ( TNumericLimits < float > : : Max ( ) ) ;
if ( ensure ( FChaosEngineInterface : : IsValid ( InActorReference ) ) )
{
InActorReference - > GetGameThreadAPI ( ) . SetMaxLinearSpeedSq ( InMaxLinearVelocity > MaxInput ? TNumericLimits < float > : : Max ( ) : InMaxLinearVelocity * InMaxLinearVelocity ) ;
}
2020-08-11 01:36:57 -04:00
}
float FChaosEngineInterface : : GetMaxDepenetrationVelocity_AssumesLocked ( const FPhysicsActorHandle & InActorReference )
{
2023-10-16 19:00:25 -04:00
if ( ensure ( FChaosEngineInterface : : IsValid ( InActorReference ) ) )
{
return FMath : : Sqrt ( InActorReference - > GetGameThreadAPI ( ) . GetInitialOverlapDepenetrationVelocity ( ) ) ;
}
return 0 ;
2020-08-11 01:36:57 -04:00
}
void FChaosEngineInterface : : SetMaxDepenetrationVelocity_AssumesLocked ( const FPhysicsActorHandle & InActorReference , float InMaxDepenetrationVelocity )
{
2023-10-16 19:00:25 -04:00
if ( ensure ( FChaosEngineInterface : : IsValid ( InActorReference ) ) )
{
InActorReference - > GetGameThreadAPI ( ) . SetInitialOverlapDepenetrationVelocity ( InMaxDepenetrationVelocity ) ;
}
2020-08-11 01:36:57 -04:00
}
FVector FChaosEngineInterface : : GetWorldVelocityAtPoint_AssumesLocked ( const FPhysicsActorHandle & InActorReference , const FVector & InPoint )
{
if ( ensure ( FChaosEngineInterface : : IsValid ( InActorReference ) ) )
{
2021-02-03 14:57:28 -04:00
const Chaos : : FRigidBodyHandle_External & Body_External = InActorReference - > GetGameThreadAPI ( ) ;
2022-08-12 08:17:15 -04:00
if ( Body_External . CanTreatAsKinematic ( ) )
2020-08-11 01:36:57 -04:00
{
2021-02-03 14:57:28 -04:00
const bool bIsRigid = Body_External . CanTreatAsRigid ( ) ;
2021-05-05 15:07:25 -04:00
const Chaos : : FVec3 COM = bIsRigid ? Chaos : : FParticleUtilitiesGT : : GetCoMWorldPosition ( & Body_External ) : ( Chaos : : FVec3 ) Chaos : : FParticleUtilitiesGT : : GetActorWorldTransform ( & Body_External ) . GetTranslation ( ) ;
2020-08-11 01:36:57 -04:00
const Chaos : : FVec3 Diff = InPoint - COM ;
2021-02-03 14:57:28 -04:00
return Body_External . V ( ) - Chaos : : FVec3 : : CrossProduct ( Diff , Body_External . W ( ) ) ;
2020-08-11 01:36:57 -04:00
}
}
return FVector ( 0 ) ;
}
2021-02-03 14:57:28 -04:00
FVector FChaosEngineInterface : : GetWorldVelocityAtPoint_AssumesLocked ( const Chaos : : FRigidBodyHandle_Internal * Body_Internal , const FVector & InPoint )
2020-10-09 22:42:26 -04:00
{
2021-05-05 15:07:25 -04:00
const Chaos : : FVec3 COM = Body_Internal - > CanTreatAsRigid ( ) ? Chaos : : FParticleUtilitiesGT : : GetCoMWorldPosition ( Body_Internal ) : ( Chaos : : FVec3 ) Chaos : : FParticleUtilitiesGT : : GetActorWorldTransform ( Body_Internal ) . GetTranslation ( ) ;
2020-10-09 22:42:26 -04:00
const Chaos : : FVec3 Diff = InPoint - COM ;
2021-02-03 14:57:28 -04:00
return Body_Internal - > V ( ) - Chaos : : FVec3 : : CrossProduct ( Diff , Body_Internal - > W ( ) ) ;
2020-10-09 22:42:26 -04:00
}
2020-08-11 01:36:57 -04:00
FTransform FChaosEngineInterface : : GetComTransform_AssumesLocked ( const FPhysicsActorHandle & InActorReference )
{
if ( ensure ( FChaosEngineInterface : : IsValid ( InActorReference ) ) )
{
2021-02-03 14:57:28 -04:00
return Chaos : : FParticleUtilitiesGT : : GetCoMWorldTransform ( & InActorReference - > GetGameThreadAPI ( ) ) ;
2020-08-11 01:36:57 -04:00
}
return FTransform ( ) ;
}
FTransform FChaosEngineInterface : : GetComTransformLocal_AssumesLocked ( const FPhysicsActorHandle & InActorReference )
{
if ( ensure ( FChaosEngineInterface : : IsValid ( InActorReference ) ) )
{
2021-02-03 14:57:28 -04:00
return FTransform ( InActorReference - > GetGameThreadAPI ( ) . RotationOfMass ( ) , InActorReference - > GetGameThreadAPI ( ) . CenterOfMass ( ) ) ;
2020-08-11 01:36:57 -04:00
}
return FTransform ( ) ;
}
FVector FChaosEngineInterface : : GetLocalInertiaTensor_AssumesLocked ( const FPhysicsActorHandle & InActorReference )
{
2022-03-04 03:51:07 -05:00
return FVector ( InActorReference - > GetGameThreadAPI ( ) . I ( ) ) ;
2020-08-11 01:36:57 -04:00
}
FBox FChaosEngineInterface : : GetBounds_AssumesLocked ( const FPhysicsActorHandle & InActorReference )
{
using namespace Chaos ;
2021-02-03 14:57:28 -04:00
const Chaos : : FRigidBodyHandle_External & Body_External = InActorReference - > GetGameThreadAPI ( ) ;
2021-06-22 00:27:54 -04:00
const FTransform WorldTM ( Body_External . R ( ) , Body_External . X ( ) ) ;
return GetBounds_AssumesLocked ( InActorReference , WorldTM ) ;
}
FBox FChaosEngineInterface : : GetBounds_AssumesLocked ( const FPhysicsActorHandle & InActorReference , const FTransform & InTransform )
{
using namespace Chaos ;
const Chaos : : FRigidBodyHandle_External & Body_External = InActorReference - > GetGameThreadAPI ( ) ;
2023-07-31 17:46:47 -04:00
if ( const FImplicitObjectRef Geometry = Body_External . GetGeometry ( ) )
2020-08-11 01:36:57 -04:00
{
2021-06-22 00:27:54 -04:00
if ( Geometry - > HasBoundingBox ( ) )
2020-08-11 01:36:57 -04:00
{
2020-10-22 19:19:16 -04:00
const FAABB3 LocalBounds = Geometry - > BoundingBox ( ) ;
2021-06-22 00:27:54 -04:00
const FRigidTransform3 WorldTM ( InTransform ) ;
2020-10-22 19:19:16 -04:00
const FAABB3 WorldBounds = LocalBounds . TransformedAABB ( WorldTM ) ;
2021-06-22 00:27:54 -04:00
return FBox ( WorldBounds . Min ( ) , WorldBounds . Max ( ) ) ;
2020-08-11 01:36:57 -04:00
}
}
return FBox ( EForceInit : : ForceInitToZero ) ;
}
void FChaosEngineInterface : : SetLinearDamping_AssumesLocked ( const FPhysicsActorHandle & InActorReference , float InDrag )
{
if ( ensure ( FChaosEngineInterface : : IsValid ( InActorReference ) ) )
{
2021-02-03 14:57:28 -04:00
InActorReference - > GetGameThreadAPI ( ) . SetLinearEtherDrag ( InDrag ) ;
2020-08-11 01:36:57 -04:00
}
}
void FChaosEngineInterface : : SetAngularDamping_AssumesLocked ( const FPhysicsActorHandle & InActorReference , float InDamping )
{
if ( ensure ( FChaosEngineInterface : : IsValid ( InActorReference ) ) )
{
2021-02-03 14:57:28 -04:00
InActorReference - > GetGameThreadAPI ( ) . SetAngularEtherDrag ( InDamping ) ;
2020-08-11 01:36:57 -04:00
}
}
2023-03-03 11:22:01 -05:00
template < typename BodyHandleType >
struct FChaosStateOps
2020-08-11 01:36:57 -04:00
{
2023-03-03 11:22:01 -05:00
static void AddImpulse ( BodyHandleType & BodyHandle , const FVector & InForce )
2020-08-11 01:36:57 -04:00
{
2023-03-03 11:22:01 -05:00
BodyHandle . SetLinearImpulse ( BodyHandle . LinearImpulse ( ) + InForce , /*bIsVelocity=*/ false ) ;
2020-08-11 01:36:57 -04:00
}
2023-03-03 11:22:01 -05:00
static void AddAngularImpulseInRadians ( BodyHandleType & BodyHandle , const FVector & InTorque )
2020-08-11 01:36:57 -04:00
{
2023-03-03 11:22:01 -05:00
BodyHandle . SetAngularImpulse ( BodyHandle . AngularImpulse ( ) + InTorque , /*bIsVelocity=*/ false ) ;
2020-08-11 01:36:57 -04:00
}
2023-03-03 11:22:01 -05:00
static void AddVelocity ( BodyHandleType & BodyHandle , const FVector & InVelocityDelta )
2020-08-11 01:36:57 -04:00
{
2023-03-03 11:22:01 -05:00
AddImpulse ( BodyHandle , BodyHandle . M ( ) * InVelocityDelta ) ;
2020-08-11 01:36:57 -04:00
}
2023-03-03 11:22:01 -05:00
static void AddAngularVelocityInRadians ( BodyHandleType & BodyHandle , const FVector & InAngularVelocityDeltaRad )
2020-08-11 01:36:57 -04:00
{
2023-03-03 11:22:01 -05:00
const Chaos : : FMatrix33 WorldI = Chaos : : FParticleUtilitiesXR : : GetWorldInertia ( & BodyHandle ) ;
AddAngularImpulseInRadians ( BodyHandle , WorldI * InAngularVelocityDeltaRad ) ;
2021-04-29 19:32:06 -04:00
}
2020-08-11 01:36:57 -04:00
2023-03-03 11:22:01 -05:00
static void AddImpulseAtLocation ( BodyHandleType & BodyHandle , const FVector & InImpulse , const FVector & InLocation )
2020-08-11 01:36:57 -04:00
{
2023-03-03 11:22:01 -05:00
const Chaos : : FVec3 WorldCOM = Chaos : : FParticleUtilitiesGT : : GetCoMWorldPosition ( & BodyHandle ) ;
const Chaos : : FVec3 AngularImpulse = Chaos : : FVec3 : : CrossProduct ( InLocation - WorldCOM , InImpulse ) ;
AddImpulse ( BodyHandle , InImpulse ) ;
AddAngularImpulseInRadians ( BodyHandle , AngularImpulse ) ;
2021-04-29 19:32:06 -04:00
}
2020-08-11 01:36:57 -04:00
2023-03-03 11:22:01 -05:00
static void AddVelocityChangeImpulseAtLocation ( BodyHandleType & BodyHandle , const FVector & InVelocityDelta , const FVector & InLocation )
2022-01-06 14:18:54 -05:00
{
2023-03-03 11:22:01 -05:00
AddImpulseAtLocation ( BodyHandle , BodyHandle . M ( ) * InVelocityDelta , InLocation ) ;
2022-01-06 14:18:54 -05:00
}
2023-03-03 11:22:01 -05:00
static void AddRadialImpulse ( BodyHandleType & BodyHandle , const FVector & InOrigin , float InRadius , float InStrength , ERadialImpulseFalloff InFalloff , bool bInVelChange )
2020-11-24 18:42:39 -04:00
{
2023-03-03 11:22:01 -05:00
const Chaos : : FVec3 WorldCOM = Chaos : : FParticleUtilitiesGT : : GetCoMWorldPosition ( & BodyHandle ) ;
const Chaos : : FVec3 OriginToActor = WorldCOM - InOrigin ;
const Chaos : : FReal OriginToActorDistance = OriginToActor . Size ( ) ;
if ( OriginToActorDistance < InRadius )
2020-11-24 18:42:39 -04:00
{
2023-03-03 11:22:01 -05:00
Chaos : : FVec3 FinalImpulse = FVector : : ZeroVector ;
if ( OriginToActorDistance > 0 )
{
const Chaos : : FVec3 OriginToActorNorm = OriginToActor / OriginToActorDistance ;
2020-11-24 18:42:39 -04:00
2023-03-03 11:22:01 -05:00
if ( InFalloff = = ERadialImpulseFalloff : : RIF_Constant )
2023-03-02 12:12:37 -05:00
{
2023-03-03 11:22:01 -05:00
FinalImpulse = OriginToActorNorm * InStrength ;
}
else if ( InFalloff = = ERadialImpulseFalloff : : RIF_Linear )
{
const Chaos : : FReal DistanceOverlapping = InRadius - OriginToActorDistance ;
if ( DistanceOverlapping > 0 )
{
2021-04-29 19:32:06 -04:00
FinalImpulse = OriginToActorNorm * FMath : : Lerp ( 0.0f , InStrength , DistanceOverlapping / InRadius ) ;
2023-03-03 11:22:01 -05:00
}
}
else
{
// Unimplemented falloff type
ensure ( false ) ;
2020-11-24 18:42:39 -04:00
}
}
else
{
2023-03-03 11:22:01 -05:00
// Sphere and actor center are coincident, just pick a direction and apply maximum strength impulse.
2021-03-03 12:28:33 -04:00
FinalImpulse = FVector : : ForwardVector * InStrength ;
}
2023-03-03 11:22:01 -05:00
if ( bInVelChange )
2021-03-03 12:28:33 -04:00
{
2023-03-03 11:22:01 -05:00
AddVelocity ( BodyHandle , FinalImpulse ) ;
2021-03-03 12:28:33 -04:00
}
else
{
2023-03-03 11:22:01 -05:00
AddImpulse ( BodyHandle , FinalImpulse ) ;
2020-11-24 18:42:39 -04:00
}
}
}
2023-03-03 11:22:01 -05:00
static void AddForce ( BodyHandleType & BodyHandle , const FVector & Force , bool bAllowSubstepping , bool bAccelChange )
{
Chaos : : EObjectStateType ObjectState = BodyHandle . ObjectState ( ) ;
BodyHandle . SetObjectState ( Chaos : : EObjectStateType : : Dynamic ) ;
if ( bAccelChange )
{
const Chaos : : FReal Mass = BodyHandle . M ( ) ;
const Chaos : : FVec3 Acceleration = Force * Mass ;
BodyHandle . AddForce ( Acceleration ) ;
}
else
{
BodyHandle . AddForce ( Force ) ;
}
}
static void AddForceAtPosition ( BodyHandleType & BodyHandle , const FVector & Force , const FVector & Position , bool bAllowSubstepping , bool bIsLocalForce /*= false*/ )
{
Chaos : : EObjectStateType ObjectState = BodyHandle . ObjectState ( ) ;
const Chaos : : FVec3 WorldCOM = Chaos : : FParticleUtilitiesGT : : GetCoMWorldPosition ( & BodyHandle ) ;
BodyHandle . SetObjectState ( Chaos : : EObjectStateType : : Dynamic ) ;
if ( bIsLocalForce )
{
const Chaos : : FRigidTransform3 CurrentTransform = Chaos : : FParticleUtilitiesGT : : GetActorWorldTransform ( & BodyHandle ) ;
const Chaos : : FVec3 WorldPosition = CurrentTransform . TransformPosition ( Position ) ;
const Chaos : : FVec3 WorldForce = CurrentTransform . TransformVector ( Force ) ;
const Chaos : : FVec3 WorldTorque = Chaos : : FVec3 : : CrossProduct ( WorldPosition - WorldCOM , WorldForce ) ;
BodyHandle . AddForce ( WorldForce ) ;
BodyHandle . AddTorque ( WorldTorque ) ;
}
else
{
const Chaos : : FVec3 WorldTorque = Chaos : : FVec3 : : CrossProduct ( Position - WorldCOM , Force ) ;
BodyHandle . AddForce ( Force ) ;
BodyHandle . AddTorque ( WorldTorque ) ;
}
}
static void AddRadialForce ( BodyHandleType & BodyHandle , const FVector & Origin , const float Radius , const float Strength , const uint8 Falloff , bool bAccelChange , bool bAllowSubstepping )
{
Chaos : : EObjectStateType ObjectState = BodyHandle . ObjectState ( ) ;
if ( CHAOS_ENSURE ( ObjectState = = Chaos : : EObjectStateType : : Dynamic | | ObjectState = = Chaos : : EObjectStateType : : Sleeping ) )
{
const Chaos : : FVec3 WorldCOM = Chaos : : FParticleUtilitiesGT : : GetCoMWorldPosition ( & BodyHandle ) ;
Chaos : : FVec3 Direction = WorldCOM - Origin ;
const Chaos : : FReal Distance = Direction . Size ( ) ;
if ( Distance > Radius )
{
return ;
}
BodyHandle . SetObjectState ( Chaos : : EObjectStateType : : Dynamic ) ;
if ( Distance < 1e-4 )
{
Direction = Chaos : : FVec3 ( 1 , 0 , 0 ) ;
}
else
{
Direction = Direction . GetUnsafeNormal ( ) ;
}
Chaos : : FVec3 Force ( 0 , 0 , 0 ) ;
CHAOS_ENSURE ( Falloff < RIF_MAX ) ;
if ( Falloff = = ERadialImpulseFalloff : : RIF_Constant )
{
Force = Strength * Direction ;
}
if ( Falloff = = ERadialImpulseFalloff : : RIF_Linear )
{
Force = ( Radius - Distance ) / Radius * Strength * Direction ;
}
if ( bAccelChange )
{
const Chaos : : FReal Mass = BodyHandle . M ( ) ;
const Chaos : : FVec3 Acceleration = Force * Mass ;
BodyHandle . AddForce ( Acceleration ) ;
}
else
{
BodyHandle . AddForce ( Force ) ;
}
}
}
static void AddTorque ( BodyHandleType & BodyHandle , const FVector & Torque , bool bAllowSubstepping , bool bAccelChange )
{
Chaos : : EObjectStateType ObjectState = BodyHandle . ObjectState ( ) ;
if ( CHAOS_ENSURE ( ObjectState = = Chaos : : EObjectStateType : : Dynamic | | ObjectState = = Chaos : : EObjectStateType : : Sleeping ) )
{
if ( bAccelChange )
{
BodyHandle . AddTorque ( Chaos : : FParticleUtilitiesXR : : GetWorldInertia ( & BodyHandle ) * Torque ) ;
}
else
{
BodyHandle . AddTorque ( Torque ) ;
}
}
}
} ;
void FChaosEngineInterface : : AddImpulse_AssumesLocked ( const FPhysicsActorHandle & InActorReference , const FVector & InForce , bool bIsInternal )
{
if ( ensure ( FChaosEngineInterface : : IsValid ( InActorReference ) ) )
{
if ( bIsInternal )
{
FChaosStateOps < Chaos : : FRigidBodyHandle_Internal > : : AddImpulse ( * InActorReference - > GetPhysicsThreadAPI ( ) , InForce ) ;
}
else
{
FChaosStateOps < Chaos : : FRigidBodyHandle_External > : : AddImpulse ( InActorReference - > GetGameThreadAPI ( ) , InForce ) ;
}
}
}
void FChaosEngineInterface : : AddAngularImpulseInRadians_AssumesLocked ( const FPhysicsActorHandle & InActorReference , const FVector & InTorque , bool bIsInternal )
{
if ( ensure ( FChaosEngineInterface : : IsValid ( InActorReference ) ) )
{
if ( bIsInternal )
{
FChaosStateOps < Chaos : : FRigidBodyHandle_Internal > : : AddAngularImpulseInRadians ( * InActorReference - > GetPhysicsThreadAPI ( ) , InTorque ) ;
}
else
{
FChaosStateOps < Chaos : : FRigidBodyHandle_External > : : AddAngularImpulseInRadians ( InActorReference - > GetGameThreadAPI ( ) , InTorque ) ;
}
}
}
void FChaosEngineInterface : : AddVelocity_AssumesLocked ( const FPhysicsActorHandle & InActorReference , const FVector & InVelocityDelta , bool bIsInternal )
{
if ( ensure ( FChaosEngineInterface : : IsValid ( InActorReference ) ) )
{
if ( bIsInternal )
{
FChaosStateOps < Chaos : : FRigidBodyHandle_Internal > : : AddVelocity ( * InActorReference - > GetPhysicsThreadAPI ( ) , InVelocityDelta ) ;
}
else
{
FChaosStateOps < Chaos : : FRigidBodyHandle_External > : : AddVelocity ( InActorReference - > GetGameThreadAPI ( ) , InVelocityDelta ) ;
}
}
}
void FChaosEngineInterface : : AddAngularVelocityInRadians_AssumesLocked ( const FPhysicsActorHandle & InActorReference , const FVector & InAngularVelocityDeltaRad , bool bIsInternal )
{
if ( ensure ( FChaosEngineInterface : : IsValid ( InActorReference ) ) )
{
if ( bIsInternal )
{
FChaosStateOps < Chaos : : FRigidBodyHandle_Internal > : : AddAngularVelocityInRadians ( * InActorReference - > GetPhysicsThreadAPI ( ) , InAngularVelocityDeltaRad ) ;
}
else
{
FChaosStateOps < Chaos : : FRigidBodyHandle_External > : : AddAngularVelocityInRadians ( InActorReference - > GetGameThreadAPI ( ) , InAngularVelocityDeltaRad ) ;
}
}
}
void FChaosEngineInterface : : AddImpulseAtLocation_AssumesLocked ( const FPhysicsActorHandle & InActorReference , const FVector & InImpulse , const FVector & InLocation , bool bIsInternal )
{
if ( ensure ( FChaosEngineInterface : : IsValid ( InActorReference ) ) )
{
if ( bIsInternal )
{
FChaosStateOps < Chaos : : FRigidBodyHandle_Internal > : : AddImpulseAtLocation ( * InActorReference - > GetPhysicsThreadAPI ( ) , InImpulse , InLocation ) ;
//UE_LOG(LogTemp, Warning, TEXT("AddImpulseAtLocation_AssumesLocked Impulse = %s | State = %d"), *InImpulse.ToString(), InActorReference->GetPhysicsThreadAPI()->ObjectState());
}
else
{
FChaosStateOps < Chaos : : FRigidBodyHandle_External > : : AddImpulseAtLocation ( InActorReference - > GetGameThreadAPI ( ) , InImpulse , InLocation ) ;
}
}
}
void FChaosEngineInterface : : AddVelocityChangeImpulseAtLocation_AssumesLocked ( const FPhysicsActorHandle & InActorReference , const FVector & InVelocityDelta , const FVector & InLocation , bool bIsInternal )
{
if ( ensure ( FChaosEngineInterface : : IsValid ( InActorReference ) ) )
{
if ( bIsInternal )
{
FChaosStateOps < Chaos : : FRigidBodyHandle_Internal > : : AddVelocityChangeImpulseAtLocation ( * InActorReference - > GetPhysicsThreadAPI ( ) , InVelocityDelta , InLocation ) ;
}
else
{
FChaosStateOps < Chaos : : FRigidBodyHandle_External > : : AddVelocityChangeImpulseAtLocation ( InActorReference - > GetGameThreadAPI ( ) , InVelocityDelta , InLocation ) ;
}
}
}
void FChaosEngineInterface : : AddRadialImpulse_AssumesLocked ( const FPhysicsActorHandle & InActorReference , const FVector & InOrigin , float InRadius , float InStrength , ERadialImpulseFalloff InFalloff , bool bInVelChange , bool bIsInternal )
{
if ( ensure ( FChaosEngineInterface : : IsValid ( InActorReference ) ) & & ensure ( InActorReference - > GetGameThreadAPI ( ) . CanTreatAsRigid ( ) ) )
{
if ( bIsInternal )
{
FChaosStateOps < Chaos : : FRigidBodyHandle_Internal > : : AddRadialImpulse ( * InActorReference - > GetPhysicsThreadAPI ( ) , InOrigin , InRadius , InStrength , InFalloff , bInVelChange ) ;
}
else
{
FChaosStateOps < Chaos : : FRigidBodyHandle_External > : : AddRadialImpulse ( InActorReference - > GetGameThreadAPI ( ) , InOrigin , InRadius , InStrength , InFalloff , bInVelChange ) ;
}
}
}
void FChaosEngineInterface : : AddForce_AssumesLocked ( const FPhysicsActorHandle & InActorReference , const FVector & Force , bool bAllowSubstepping , bool bAccelChange , bool bIsInternal )
{
if ( ensure ( FChaosEngineInterface : : IsValid ( InActorReference ) ) )
{
if ( bIsInternal )
{
FChaosStateOps < Chaos : : FRigidBodyHandle_Internal > : : AddForce ( * InActorReference - > GetPhysicsThreadAPI ( ) , Force , bAllowSubstepping , bAccelChange ) ;
}
else
{
FChaosStateOps < Chaos : : FRigidBodyHandle_External > : : AddForce ( InActorReference - > GetGameThreadAPI ( ) , Force , bAllowSubstepping , bAccelChange ) ;
}
}
}
void FChaosEngineInterface : : AddForceAtPosition_AssumesLocked ( const FPhysicsActorHandle & InActorReference , const FVector & Force , const FVector & Position , bool bAllowSubstepping , bool bIsLocalForce , bool bIsInternal )
{
if ( ensure ( FChaosEngineInterface : : IsValid ( InActorReference ) ) )
{
if ( bIsInternal )
{
FChaosStateOps < Chaos : : FRigidBodyHandle_Internal > : : AddForceAtPosition ( * InActorReference - > GetPhysicsThreadAPI ( ) , Force , Position , bAllowSubstepping , bIsLocalForce ) ;
//UE_LOG(LogTemp, Warning, TEXT("AddForceAtPosition_AssumesLocked Force = %s | State = %d"), *Force.ToString(), InActorReference->GetPhysicsThreadAPI()->ObjectState());
}
else
{
FChaosStateOps < Chaos : : FRigidBodyHandle_External > : : AddForceAtPosition ( InActorReference - > GetGameThreadAPI ( ) , Force , Position , bAllowSubstepping , bIsLocalForce ) ;
}
}
}
void FChaosEngineInterface : : AddRadialForce_AssumesLocked ( const FPhysicsActorHandle & InActorReference , const FVector & Origin , const float Radius , const float Strength , const uint8 Falloff , bool bAccelChange , bool bAllowSubstepping , bool bIsInternal )
{
if ( ensure ( FChaosEngineInterface : : IsValid ( InActorReference ) ) )
{
if ( bIsInternal )
{
FChaosStateOps < Chaos : : FRigidBodyHandle_Internal > : : AddRadialForce ( * InActorReference - > GetPhysicsThreadAPI ( ) , Origin , Radius , Strength , Falloff , bAccelChange , bAllowSubstepping ) ;
}
else
{
FChaosStateOps < Chaos : : FRigidBodyHandle_External > : : AddRadialForce ( InActorReference - > GetGameThreadAPI ( ) , Origin , Radius , Strength , Falloff , bAccelChange , bAllowSubstepping ) ;
}
}
}
void FChaosEngineInterface : : AddTorque_AssumesLocked ( const FPhysicsActorHandle & InActorReference , const FVector & Torque , bool bAllowSubstepping , bool bAccelChange , bool bIsInternal )
{
if ( ensure ( FChaosEngineInterface : : IsValid ( InActorReference ) ) )
{
if ( bIsInternal )
{
FChaosStateOps < Chaos : : FRigidBodyHandle_Internal > : : AddTorque ( * InActorReference - > GetPhysicsThreadAPI ( ) , Torque , bAllowSubstepping , bAccelChange ) ;
}
else
{
FChaosStateOps < Chaos : : FRigidBodyHandle_External > : : AddTorque ( InActorReference - > GetGameThreadAPI ( ) , Torque , bAllowSubstepping , bAccelChange ) ;
}
}
2020-08-11 01:36:57 -04:00
}
bool FChaosEngineInterface : : IsGravityEnabled_AssumesLocked ( const FPhysicsActorHandle & InActorReference )
{
2021-02-03 14:57:28 -04:00
return InActorReference - > GetGameThreadAPI ( ) . GravityEnabled ( ) ;
2020-08-11 01:36:57 -04:00
}
void FChaosEngineInterface : : SetGravityEnabled_AssumesLocked ( const FPhysicsActorHandle & InActorReference , bool bEnabled )
{
2021-02-03 14:57:28 -04:00
InActorReference - > GetGameThreadAPI ( ) . SetGravityEnabled ( bEnabled ) ;
2020-08-11 01:36:57 -04:00
}
2023-04-27 13:26:51 -04:00
bool FChaosEngineInterface : : GetUpdateKinematicFromSimulation_AssumesLocked ( const FPhysicsActorHandle & InActorReference )
{
return InActorReference - > GetGameThreadAPI ( ) . UpdateKinematicFromSimulation ( ) ;
}
void FChaosEngineInterface : : SetUpdateKinematicFromSimulation_AssumesLocked ( const FPhysicsActorHandle & InActorReference , bool bUpdateKinematicFromSimulation )
{
InActorReference - > GetGameThreadAPI ( ) . SetUpdateKinematicFromSimulation ( bUpdateKinematicFromSimulation ) ;
}
2020-09-24 00:43:27 -04:00
void FChaosEngineInterface : : SetOneWayInteraction_AssumesLocked ( const FPhysicsActorHandle & InHandle , bool InOneWayInteraction )
{
2021-02-03 14:57:28 -04:00
InHandle - > GetGameThreadAPI ( ) . SetOneWayInteraction ( InOneWayInteraction ) ;
2020-09-24 00:43:27 -04:00
}
2020-08-11 01:36:57 -04:00
float FChaosEngineInterface : : GetSleepEnergyThreshold_AssumesLocked ( const FPhysicsActorHandle & InActorReference )
{
return 0 ;
}
void FChaosEngineInterface : : SetSleepEnergyThreshold_AssumesLocked ( const FPhysicsActorHandle & InActorReference , float InEnergyThreshold )
{
}
2024-01-12 19:37:04 -05:00
void FChaosEngineInterface : : SetSleepThresholdMultiplier_AssumesLocked ( const FPhysicsActorHandle & InActorReference , float InThresholdMultiplier )
{
return InActorReference - > GetGameThreadAPI ( ) . SetSleepThresholdMultiplier ( InThresholdMultiplier ) ;
}
2020-08-11 01:36:57 -04:00
void FChaosEngineInterface : : SetMass_AssumesLocked ( FPhysicsActorHandle & InActorReference , float InMass )
{
2021-02-03 14:57:28 -04:00
Chaos : : FRigidBodyHandle_External & Body_External = InActorReference - > GetGameThreadAPI ( ) ;
Body_External . SetM ( InMass ) ;
2021-04-29 19:32:06 -04:00
if ( CHAOS_ENSURE ( ! FMath : : IsNearlyZero ( InMass ) ) )
{
2021-02-03 14:57:28 -04:00
Body_External . SetInvM ( 1. / InMass ) ;
2021-04-29 19:32:06 -04:00
} else
{
2021-02-03 14:57:28 -04:00
Body_External . SetInvM ( 0 ) ;
2020-08-11 01:36:57 -04:00
}
}
void FChaosEngineInterface : : SetMassSpaceInertiaTensor_AssumesLocked ( FPhysicsActorHandle & InActorReference , const FVector & InTensor )
{
2021-04-29 19:32:06 -04:00
if ( CHAOS_ENSURE ( ! FMath : : IsNearlyZero ( InTensor . X ) ) & & CHAOS_ENSURE ( ! FMath : : IsNearlyZero ( InTensor . Y ) ) & & CHAOS_ENSURE ( ! FMath : : IsNearlyZero ( InTensor . Z ) ) )
{
2021-02-03 14:57:28 -04:00
Chaos : : FRigidBodyHandle_External & Body_External = InActorReference - > GetGameThreadAPI ( ) ;
2022-03-04 03:47:40 -05:00
Body_External . SetI ( Chaos : : TVec3 < Chaos : : FRealSingle > ( InTensor . X , InTensor . Y , InTensor . Z ) ) ;
Body_External . SetInvI ( Chaos : : TVec3 < Chaos : : FRealSingle > ( 1. / InTensor . X , 1. / InTensor . Y , 1. / InTensor . Z ) ) ;
2020-08-11 01:36:57 -04:00
}
}
void FChaosEngineInterface : : SetComLocalPose_AssumesLocked ( const FPhysicsActorHandle & InHandle , const FTransform & InComLocalPose )
{
2021-02-03 14:57:28 -04:00
Chaos : : FRigidBodyHandle_External & Body_External = InHandle - > GetGameThreadAPI ( ) ;
Body_External . SetCenterOfMass ( InComLocalPose . GetLocation ( ) ) ;
Body_External . SetRotationOfMass ( InComLocalPose . GetRotation ( ) ) ;
2020-08-11 01:36:57 -04:00
}
2022-04-29 13:53:51 -04:00
bool FChaosEngineInterface : : IsInertiaConditioningEnabled_AssumesLocked ( const FPhysicsActorHandle & InActorReference )
{
return InActorReference - > GetGameThreadAPI ( ) . InertiaConditioningEnabled ( ) ;
}
void FChaosEngineInterface : : SetInertiaConditioningEnabled_AssumesLocked ( const FPhysicsActorHandle & InActorReference , bool bEnabled )
{
InActorReference - > GetGameThreadAPI ( ) . SetInertiaConditioningEnabled ( bEnabled ) ;
}
2020-08-11 01:36:57 -04:00
void FChaosEngineInterface : : SetIsSimulationShape ( const FPhysicsShapeHandle & InShape , bool bIsSimShape )
{
InShape . Shape - > SetSimEnabled ( bIsSimShape ) ;
}
2022-06-22 18:59:24 -04:00
void FChaosEngineInterface : : SetIsProbeShape ( const FPhysicsShapeHandle & InShape , bool bIsProbeShape )
{
InShape . Shape - > SetIsProbe ( bIsProbeShape ) ;
}
2020-08-11 01:36:57 -04:00
void FChaosEngineInterface : : SetIsQueryShape ( const FPhysicsShapeHandle & InShape , bool bIsQueryShape )
{
InShape . Shape - > SetQueryEnabled ( bIsQueryShape ) ;
}
float FChaosEngineInterface : : GetStabilizationEnergyThreshold_AssumesLocked ( const FPhysicsActorHandle & InHandle )
{
// #todo : Implement
return 0.0f ;
}
void FChaosEngineInterface : : SetStabilizationEnergyThreshold_AssumesLocked ( const FPhysicsActorHandle & InHandle , float InThreshold )
{
// #todo : Implement
}
uint32 FChaosEngineInterface : : GetSolverPositionIterationCount_AssumesLocked ( const FPhysicsActorHandle & InHandle )
{
// #todo : Implement
return 0 ;
}
void FChaosEngineInterface : : SetSolverPositionIterationCount_AssumesLocked ( const FPhysicsActorHandle & InHandle , uint32 InSolverIterationCount )
{
// #todo : Implement
}
uint32 FChaosEngineInterface : : GetSolverVelocityIterationCount_AssumesLocked ( const FPhysicsActorHandle & InHandle )
{
// #todo : Implement
return 0 ;
}
void FChaosEngineInterface : : SetSolverVelocityIterationCount_AssumesLocked ( const FPhysicsActorHandle & InHandle , uint32 InSolverIterationCount )
{
// #todo : Implement
}
float FChaosEngineInterface : : GetWakeCounter_AssumesLocked ( const FPhysicsActorHandle & InHandle )
{
// #todo : Implement
return 0.0f ;
}
void FChaosEngineInterface : : SetWakeCounter_AssumesLocked ( const FPhysicsActorHandle & InHandle , float InWakeCounter )
{
// #todo : Implement
}
void FChaosEngineInterface : : SetInitialized_AssumesLocked ( const FPhysicsActorHandle & InHandle , bool InInitialized )
{
2021-02-03 14:57:28 -04:00
//why is this needed?
2021-03-05 19:27:14 -04:00
Chaos : : FPBDRigidParticle * Rigid = InHandle - > GetParticle_LowLevel ( ) - > CastToRigidParticle ( ) ;
2020-08-11 01:36:57 -04:00
if ( Rigid )
{
Rigid - > SetInitialized ( InInitialized ) ;
}
}
SIZE_T FChaosEngineInterface : : GetResourceSizeEx ( const FPhysicsActorHandle & InActorRef )
{
return sizeof ( FPhysicsActorHandle ) ;
}
// Constraints
2022-12-07 19:57:03 -05:00
FPhysicsConstraintHandle FChaosEngineInterface : : CreateConstraint ( Chaos : : FPhysicsObject * Body1 , Chaos : : FPhysicsObject * Body2 , const FTransform & InLocalFrame1 , const FTransform & InLocalFrame2 )
2020-08-11 01:36:57 -04:00
{
FPhysicsConstraintHandle ConstraintRef ;
2022-12-07 19:57:03 -05:00
if ( bEnableChaosJointConstraints )
2020-08-11 01:36:57 -04:00
{
2022-12-07 19:57:03 -05:00
Chaos : : FPhysicsSolver * Solver1 = Chaos : : FPhysicsObjectInterface : : GetSolver ( { & Body1 , 1 } ) ;
Chaos : : FPhysicsSolver * Solver2 = Chaos : : FPhysicsObjectInterface : : GetSolver ( { & Body2 , 1 } ) ;
2020-08-11 01:36:57 -04:00
2022-12-07 19:57:03 -05:00
if ( Body1 & & Body2 & & Solver1 & & Solver2 )
2020-11-24 18:42:39 -04:00
{
2021-12-13 13:05:20 -05:00
LLM_SCOPE ( ELLMTag : : ChaosConstraint ) ;
2020-11-24 18:42:39 -04:00
2022-12-07 19:57:03 -05:00
auto * JointConstraint = new Chaos : : FJointConstraint ( ) ;
ConstraintRef . Constraint = JointConstraint ;
JointConstraint - > SetPhysicsBodies ( { Body1 , Body2 } ) ;
JointConstraint - > SetJointTransforms ( { InLocalFrame1 , InLocalFrame2 } ) ;
checkSlow ( Solver1 = = Solver2 ) ;
Solver1 - > RegisterObject ( JointConstraint ) ;
}
else if ( Body1 | | Body2 )
{
LLM_SCOPE ( ELLMTag : : ChaosConstraint ) ;
Chaos : : FPhysicsObject * ValidObject = Body1 ;
Chaos : : FPhysicsSolver * ValidSolver = Solver1 ;
2020-11-24 18:42:39 -04:00
bool bSwapped = false ;
2022-12-07 19:57:03 -05:00
if ( ! ValidObject | | ! ValidSolver )
2020-11-24 18:42:39 -04:00
{
bSwapped = true ;
2022-12-07 19:57:03 -05:00
ValidObject = Body2 ;
ValidSolver = Solver2 ;
2020-11-24 18:42:39 -04:00
}
2022-12-07 19:57:03 -05:00
if ( ValidSolver )
2020-11-24 18:42:39 -04:00
{
2022-12-07 19:57:03 -05:00
FChaosScene * Scene = PhysicsObjectPhysicsCoreInterface : : GetScene ( { & ValidObject , 1 } ) ;
2021-02-08 15:59:34 -04:00
// Create kinematic actor to attach to joint
FPhysicsActorHandle KinematicEndPoint ;
FActorCreationParams Params ;
Params . bSimulatePhysics = false ;
Params . bQueryOnly = false ;
Params . Scene = Scene ;
Params . bStatic = false ;
Params . InitialTM = FTransform : : Identity ;
FChaosEngineInterface : : CreateActor ( Params , KinematicEndPoint ) ;
// Chaos requires our particles have geometry.
2023-07-31 17:46:47 -04:00
auto Sphere = MakeImplicitObjectPtr < Chaos : : FImplicitSphere3 > ( FVector ( 0 , 0 , 0 ) , 0 ) ;
KinematicEndPoint - > GetGameThreadAPI ( ) . SetGeometry ( Sphere ) ;
2021-02-08 15:59:34 -04:00
KinematicEndPoint - > GetGameThreadAPI ( ) . SetUserData ( nullptr ) ;
auto * JointConstraint = new Chaos : : FJointConstraint ( ) ;
JointConstraint - > SetKinematicEndPoint ( KinematicEndPoint , Scene - > GetSolver ( ) ) ;
ConstraintRef . Constraint = JointConstraint ;
2022-12-07 19:57:03 -05:00
// Disable collision on shape to ensure it is not added to acceleration structure.
for ( const TUniquePtr < Chaos : : FPerShapeData > & Shape : KinematicEndPoint - > GetGameThreadAPI ( ) . ShapesArray ( ) )
{
Chaos : : FCollisionData CollisionData = Shape - > GetCollisionData ( ) ;
CollisionData . bQueryCollision = false ;
CollisionData . bSimCollision = false ;
Shape - > SetCollisionData ( CollisionData ) ;
}
2021-06-22 00:27:54 -04:00
2022-12-07 19:57:03 -05:00
JointConstraint - > SetPhysicsBodies ( { ValidObject , KinematicEndPoint - > GetPhysicsObject ( ) } ) ;
2021-02-08 15:59:34 -04:00
2021-09-17 16:57:27 -04:00
Chaos : : FTransformPair TransformPair = { InLocalFrame1 , InLocalFrame2 } ;
2021-02-08 15:59:34 -04:00
if ( bSwapped )
{
Swap ( TransformPair [ 0 ] , TransformPair [ 1 ] ) ;
}
JointConstraint - > SetJointTransforms ( TransformPair ) ;
2022-12-07 19:57:03 -05:00
checkSlow ( ValidSolver = = KinematicEndPoint - > GetSolver < Chaos : : FPhysicsSolver > ( ) ) ;
ValidSolver - > RegisterObject ( JointConstraint ) ;
2020-11-24 18:42:39 -04:00
}
}
2020-08-11 01:36:57 -04:00
}
2022-12-07 19:57:03 -05:00
2020-08-11 01:36:57 -04:00
return ConstraintRef ;
}
2022-12-07 19:57:03 -05:00
FPhysicsConstraintHandle FChaosEngineInterface : : CreateConstraint ( const FPhysicsActorHandle & InActorRef1 , const FPhysicsActorHandle & InActorRef2 , const FTransform & InLocalFrame1 , const FTransform & InLocalFrame2 )
{
Chaos : : FPhysicsObject * Body1 = InActorRef1 ? InActorRef1 - > GetPhysicsObject ( ) : nullptr ;
Chaos : : FPhysicsObject * Body2 = InActorRef2 ? InActorRef2 - > GetPhysicsObject ( ) : nullptr ;
return FChaosEngineInterface : : CreateConstraint ( Body1 , Body2 , InLocalFrame1 , InLocalFrame2 ) ;
}
2020-09-24 00:43:27 -04:00
FPhysicsConstraintHandle FChaosEngineInterface : : CreateSuspension ( const FPhysicsActorHandle & InActorRef , const FVector & InLocalFrame )
2023-09-21 04:14:21 -04:00
{
Chaos : : FPhysicsObject * Body = InActorRef ? InActorRef - > GetPhysicsObject ( ) : nullptr ;
return FChaosEngineInterface : : CreateSuspension ( Body , InLocalFrame ) ;
}
FPhysicsConstraintHandle FChaosEngineInterface : : CreateSuspension ( Chaos : : FPhysicsObject * Body , const FVector & InLocalFrame )
2020-09-24 00:43:27 -04:00
{
FPhysicsConstraintHandle ConstraintRef ;
if ( bEnableChaosJointConstraints )
{
2023-09-21 04:14:21 -04:00
if ( Body )
2020-09-24 00:43:27 -04:00
{
2023-09-21 04:14:21 -04:00
Chaos : : FPhysicsSolver * Solver = Chaos : : FPhysicsObjectInterface : : GetSolver ( { & Body , 1 } ) ;
if ( Solver )
2020-09-24 00:43:27 -04:00
{
2021-12-13 13:05:20 -05:00
LLM_SCOPE ( ELLMTag : : ChaosConstraint ) ;
2020-09-24 00:43:27 -04:00
auto * SuspensionConstraint = new Chaos : : FSuspensionConstraint ( ) ;
ConstraintRef . Constraint = SuspensionConstraint ;
2023-09-21 04:14:21 -04:00
SuspensionConstraint - > SetPhysicsBody ( Body ) ;
2021-09-22 15:51:55 -04:00
SuspensionConstraint - > SetLocation ( InLocalFrame ) ;
2020-09-24 00:43:27 -04:00
Solver - > RegisterObject ( SuspensionConstraint ) ;
}
}
}
return ConstraintRef ;
}
2020-08-11 01:36:57 -04:00
void FChaosEngineInterface : : SetConstraintUserData ( const FPhysicsConstraintHandle & InConstraintRef , void * InUserData )
{
2020-09-24 00:43:27 -04:00
if ( InConstraintRef . IsValid ( ) & & InConstraintRef . Constraint - > IsType ( Chaos : : EConstraintType : : JointConstraintType ) )
2020-08-11 01:36:57 -04:00
{
2020-09-24 00:43:27 -04:00
if ( Chaos : : FJointConstraint * Constraint = static_cast < Chaos : : FJointConstraint * > ( InConstraintRef . Constraint ) )
2020-08-11 01:36:57 -04:00
{
Constraint - > SetUserData ( InUserData ) ;
}
}
}
void FChaosEngineInterface : : ReleaseConstraint ( FPhysicsConstraintHandle & InConstraintRef )
{
2021-08-31 14:32:41 -04:00
using namespace Chaos ;
2020-08-11 01:36:57 -04:00
if ( bEnableChaosJointConstraints )
{
2020-09-24 00:43:27 -04:00
if ( InConstraintRef . IsValid ( ) & & InConstraintRef . Constraint - > IsType ( Chaos : : EConstraintType : : JointConstraintType ) )
2020-08-11 01:36:57 -04:00
{
2021-08-31 14:32:41 -04:00
if ( FJointConstraint * Constraint = static_cast < FJointConstraint * > ( InConstraintRef . Constraint ) )
2020-08-11 01:36:57 -04:00
{
if ( FJointConstraintPhysicsProxy * Proxy = Constraint - > GetProxy < FJointConstraintPhysicsProxy > ( ) )
{
2021-08-31 14:32:41 -04:00
check ( Proxy - > GetSolver < FPhysicsSolver > ( ) ) ;
FPhysicsSolver * Solver = Proxy - > GetSolver < FPhysicsSolver > ( ) ;
2021-09-06 12:23:53 -04:00
// TODO: we should probably figure out a way to call this from within UnregisterObject, to match
// what RegisterObject does
if ( FChaosScene * Scene = FChaosEngineInterface : : GetCurrentScene ( Constraint - > GetKinematicEndPoint ( ) ) )
{
Scene - > RemoveActorFromAccelerationStructure ( Constraint - > GetKinematicEndPoint ( ) ) ;
}
2020-09-24 00:43:27 -04:00
Solver - > UnregisterObject ( Constraint ) ;
2020-08-11 01:36:57 -04:00
2020-09-24 00:43:27 -04:00
InConstraintRef . Constraint = nullptr ; // freed by the joint constraint physics proxy
2020-08-11 01:36:57 -04:00
}
}
}
2021-08-31 14:32:41 -04:00
else if ( InConstraintRef . IsValid ( ) & & InConstraintRef . Constraint - > IsType ( EConstraintType : : SuspensionConstraintType ) )
2020-09-24 00:43:27 -04:00
{
2021-08-31 14:32:41 -04:00
if ( Chaos : : FSuspensionConstraint * Constraint = static_cast < FSuspensionConstraint * > ( InConstraintRef . Constraint ) )
2020-09-24 00:43:27 -04:00
{
if ( FSuspensionConstraintPhysicsProxy * Proxy = Constraint - > GetProxy < FSuspensionConstraintPhysicsProxy > ( ) )
{
2021-08-31 14:32:41 -04:00
check ( Proxy - > GetSolver < FPhysicsSolver > ( ) ) ;
FPhysicsSolver * Solver = Proxy - > GetSolver < FPhysicsSolver > ( ) ;
2020-09-24 00:43:27 -04:00
Solver - > UnregisterObject ( Constraint ) ;
InConstraintRef . Constraint = nullptr ; // freed by the joint constraint physics proxy
}
}
}
2020-08-11 01:36:57 -04:00
}
}
FTransform FChaosEngineInterface : : GetLocalPose ( const FPhysicsConstraintHandle & InConstraintRef , EConstraintFrame : : Type InFrame )
{
2020-09-24 00:43:27 -04:00
if ( InConstraintRef . IsValid ( ) & & InConstraintRef . Constraint - > IsType ( Chaos : : EConstraintType : : JointConstraintType ) )
2020-08-11 01:36:57 -04:00
{
2020-09-24 00:43:27 -04:00
if ( Chaos : : FJointConstraint * Constraint = static_cast < Chaos : : FJointConstraint * > ( InConstraintRef . Constraint ) )
2020-08-11 01:36:57 -04:00
{
2021-09-17 16:57:27 -04:00
const Chaos : : FTransformPair & M = Constraint - > GetJointTransforms ( ) ;
2020-08-11 01:36:57 -04:00
if ( InFrame = = EConstraintFrame : : Frame1 )
{
return M [ 0 ] ;
}
else if ( InFrame = = EConstraintFrame : : Frame2 )
{
return M [ 1 ] ;
}
}
}
return FTransform : : Identity ;
}
2021-02-03 14:57:28 -04:00
Chaos : : FGeometryParticle *
2020-09-24 00:43:27 -04:00
GetParticleFromProxy ( IPhysicsProxyBase * ProxyBase )
2020-08-11 01:36:57 -04:00
{
2020-09-24 00:43:27 -04:00
if ( ProxyBase )
2020-08-11 01:36:57 -04:00
{
2021-02-03 14:57:28 -04:00
if ( ProxyBase - > GetType ( ) = = EPhysicsProxyType : : SingleParticleProxy )
2020-08-11 01:36:57 -04:00
{
2021-09-22 15:51:55 -04:00
return ( ( Chaos : : FSingleParticlePhysicsProxy * ) ProxyBase ) - > GetParticle_LowLevel ( ) ;
2020-09-24 00:43:27 -04:00
}
}
return nullptr ;
}
FTransform FChaosEngineInterface : : GetGlobalPose ( const FPhysicsConstraintHandle & InConstraintRef , EConstraintFrame : : Type InFrame )
{
if ( InConstraintRef . IsValid ( ) & & InConstraintRef . Constraint - > IsType ( Chaos : : EConstraintType : : JointConstraintType ) )
{
if ( Chaos : : FJointConstraint * Constraint = static_cast < Chaos : : FJointConstraint * > ( InConstraintRef . Constraint ) )
{
2021-09-07 15:17:01 -04:00
Chaos : : FProxyBasePair BasePairs = Constraint - > GetParticleProxies ( ) ;
2021-09-17 16:57:27 -04:00
const Chaos : : FTransformPair & M = Constraint - > GetJointTransforms ( ) ;
2020-08-11 01:36:57 -04:00
if ( InFrame = = EConstraintFrame : : Frame1 )
{
2021-02-03 14:57:28 -04:00
if ( Chaos : : FGeometryParticle * Particle = GetParticleFromProxy ( BasePairs [ 0 ] ) )
2020-09-24 00:43:27 -04:00
{
return FTransform ( Particle - > R ( ) , Particle - > X ( ) ) * M [ 0 ] ;
}
2020-08-11 01:36:57 -04:00
}
else if ( InFrame = = EConstraintFrame : : Frame2 )
{
2021-02-03 14:57:28 -04:00
if ( Chaos : : FGeometryParticle * Particle = GetParticleFromProxy ( BasePairs [ 1 ] ) )
2020-09-24 00:43:27 -04:00
{
return FTransform ( Particle - > R ( ) , Particle - > X ( ) ) * M [ 1 ] ;
}
2020-08-11 01:36:57 -04:00
}
}
}
return FTransform : : Identity ;
}
FVector FChaosEngineInterface : : GetLocation ( const FPhysicsConstraintHandle & InConstraintRef )
{
2020-09-24 00:43:27 -04:00
if ( InConstraintRef . IsValid ( ) & & InConstraintRef . Constraint - > IsType ( Chaos : : EConstraintType : : JointConstraintType ) )
2020-08-11 01:36:57 -04:00
{
2020-09-24 00:43:27 -04:00
if ( Chaos : : FJointConstraint * Constraint = static_cast < Chaos : : FJointConstraint * > ( InConstraintRef . Constraint ) )
2020-08-11 01:36:57 -04:00
{
return 0.5 * ( GetGlobalPose ( InConstraintRef , EConstraintFrame : : Frame1 ) . GetTranslation ( ) + GetGlobalPose ( InConstraintRef , EConstraintFrame : : Frame2 ) . GetTranslation ( ) ) ;
}
}
return FVector : : ZeroVector ;
}
2020-09-01 14:07:48 -04:00
void FChaosEngineInterface : : GetForce ( const FPhysicsConstraintHandle & InConstraintRef , FVector & OutLinForce , FVector & OutAngForce )
2020-08-11 01:36:57 -04:00
{
2020-09-01 14:07:48 -04:00
OutLinForce = FVector : : ZeroVector ;
OutAngForce = FVector : : ZeroVector ;
2020-09-24 00:43:27 -04:00
if ( InConstraintRef . IsValid ( ) & & InConstraintRef . Constraint - > IsType ( Chaos : : EConstraintType : : JointConstraintType ) )
2020-09-01 14:07:48 -04:00
{
2020-09-24 00:43:27 -04:00
if ( Chaos : : FJointConstraint * Constraint = static_cast < Chaos : : FJointConstraint * > ( InConstraintRef . Constraint ) )
2020-09-01 14:07:48 -04:00
{
OutLinForce = Constraint - > GetOutputData ( ) . Force ;
OutAngForce = Constraint - > GetOutputData ( ) . Torque ;
}
}
2020-08-11 01:36:57 -04:00
}
void FChaosEngineInterface : : GetDriveLinearVelocity ( const FPhysicsConstraintHandle & InConstraintRef , FVector & OutLinVelocity )
{
2020-09-01 14:07:48 -04:00
OutLinVelocity = FVector : : ZeroVector ;
2020-09-24 00:43:27 -04:00
if ( InConstraintRef . IsValid ( ) & & InConstraintRef . Constraint - > IsType ( Chaos : : EConstraintType : : JointConstraintType ) )
2020-09-01 14:07:48 -04:00
{
2020-09-24 00:43:27 -04:00
if ( Chaos : : FJointConstraint * Constraint = static_cast < Chaos : : FJointConstraint * > ( InConstraintRef . Constraint ) )
2020-09-01 14:07:48 -04:00
{
OutLinVelocity = Constraint - > GetLinearDriveVelocityTarget ( ) ;
}
}
2020-08-11 01:36:57 -04:00
}
void FChaosEngineInterface : : GetDriveAngularVelocity ( const FPhysicsConstraintHandle & InConstraintRef , FVector & OutAngVelocity )
{
2020-09-01 14:07:48 -04:00
OutAngVelocity = FVector : : ZeroVector ;
2020-09-24 00:43:27 -04:00
if ( InConstraintRef . IsValid ( ) & & InConstraintRef . Constraint - > IsType ( Chaos : : EConstraintType : : JointConstraintType ) )
2020-09-01 14:07:48 -04:00
{
2020-09-24 00:43:27 -04:00
if ( Chaos : : FJointConstraint * Constraint = static_cast < Chaos : : FJointConstraint * > ( InConstraintRef . Constraint ) )
2020-09-01 14:07:48 -04:00
{
OutAngVelocity = Constraint - > GetAngularDriveVelocityTarget ( ) ;
}
}
2020-08-11 01:36:57 -04:00
}
float FChaosEngineInterface : : GetCurrentSwing1 ( const FPhysicsConstraintHandle & InConstraintRef )
{
return GetLocalPose ( InConstraintRef , EConstraintFrame : : Frame2 ) . GetRotation ( ) . Euler ( ) . X ;
}
float FChaosEngineInterface : : GetCurrentSwing2 ( const FPhysicsConstraintHandle & InConstraintRef )
{
return GetLocalPose ( InConstraintRef , EConstraintFrame : : Frame2 ) . GetRotation ( ) . Euler ( ) . Y ;
}
float FChaosEngineInterface : : GetCurrentTwist ( const FPhysicsConstraintHandle & InConstraintRef )
{
return GetLocalPose ( InConstraintRef , EConstraintFrame : : Frame2 ) . GetRotation ( ) . Euler ( ) . Z ;
}
void FChaosEngineInterface : : SetCanVisualize ( const FPhysicsConstraintHandle & InConstraintRef , bool bInCanVisualize )
{
// @todo(chaos) : Joint Constraints : Debug Tools
}
void FChaosEngineInterface : : SetCollisionEnabled ( const FPhysicsConstraintHandle & InConstraintRef , bool bInCollisionEnabled )
{
2020-09-24 00:43:27 -04:00
if ( InConstraintRef . IsValid ( ) & & InConstraintRef . Constraint - > IsType ( Chaos : : EConstraintType : : JointConstraintType ) )
2020-08-11 01:36:57 -04:00
{
2020-09-24 00:43:27 -04:00
if ( Chaos : : FJointConstraint * Constraint = static_cast < Chaos : : FJointConstraint * > ( InConstraintRef . Constraint ) )
2020-08-11 01:36:57 -04:00
{
Constraint - > SetCollisionEnabled ( bInCollisionEnabled ) ;
}
}
}
2022-05-03 11:54:26 -04:00
void FChaosEngineInterface : : SetProjectionEnabled_AssumesLocked ( const FPhysicsConstraintHandle & InConstraintRef , bool bInProjectionEnabled , float InLinearAlpha , float InAngularAlpha , float InLinearTolerance , float InAngularToleranceDeg )
2020-08-11 01:36:57 -04:00
{
2020-09-24 00:43:27 -04:00
if ( InConstraintRef . IsValid ( ) & & InConstraintRef . Constraint - > IsType ( Chaos : : EConstraintType : : JointConstraintType ) )
2020-08-11 01:36:57 -04:00
{
2020-09-24 00:43:27 -04:00
if ( Chaos : : FJointConstraint * Constraint = static_cast < Chaos : : FJointConstraint * > ( InConstraintRef . Constraint ) )
2020-08-11 01:36:57 -04:00
{
Constraint - > SetProjectionEnabled ( bInProjectionEnabled ) ;
2020-09-01 14:07:48 -04:00
Constraint - > SetProjectionLinearAlpha ( InLinearAlpha ) ;
Constraint - > SetProjectionAngularAlpha ( InAngularAlpha ) ;
2022-05-03 11:54:26 -04:00
Constraint - > SetProjectionLinearTolerance ( InLinearTolerance ) ;
Constraint - > SetProjectionAngularTolerance ( FMath : : DegreesToRadians ( InAngularToleranceDeg ) ) ;
2020-08-11 01:36:57 -04:00
}
}
}
2022-02-25 19:46:14 -05:00
void FChaosEngineInterface : : SetShockPropagationEnabled_AssumesLocked ( const FPhysicsConstraintHandle & InConstraintRef , bool bInShockPropagationEnabled , float InShockPropagationAlpha )
2022-02-11 14:42:03 -05:00
{
if ( InConstraintRef . IsValid ( ) & & InConstraintRef . Constraint - > IsType ( Chaos : : EConstraintType : : JointConstraintType ) )
{
if ( Chaos : : FJointConstraint * Constraint = static_cast < Chaos : : FJointConstraint * > ( InConstraintRef . Constraint ) )
{
2022-02-25 19:46:14 -05:00
Constraint - > SetShockPropagationEnabled ( bInShockPropagationEnabled ) ;
2022-02-11 14:42:03 -05:00
Constraint - > SetShockPropagationAlpha ( InShockPropagationAlpha ) ;
}
}
}
2020-08-11 01:36:57 -04:00
void FChaosEngineInterface : : SetParentDominates_AssumesLocked ( const FPhysicsConstraintHandle & InConstraintRef , bool bInParentDominates )
{
2020-09-24 00:43:27 -04:00
if ( InConstraintRef . IsValid ( ) & & InConstraintRef . Constraint - > IsType ( Chaos : : EConstraintType : : JointConstraintType ) )
2020-08-11 01:36:57 -04:00
{
2020-09-24 00:43:27 -04:00
if ( Chaos : : FJointConstraint * Constraint = static_cast < Chaos : : FJointConstraint * > ( InConstraintRef . Constraint ) )
2020-08-11 01:36:57 -04:00
{
if ( bInParentDominates )
{
Constraint - > SetParentInvMassScale ( 0.f ) ;
} else
{
Constraint - > SetParentInvMassScale ( 1.f ) ;
}
}
}
}
2022-11-01 16:40:37 -04:00
void FChaosEngineInterface : : SetMassConditioningEnabled_AssumesLocked ( const FPhysicsConstraintHandle & InConstraintRef , bool bInMassConditioningEnabled )
{
if ( InConstraintRef . IsValid ( ) & & InConstraintRef . Constraint - > IsType ( Chaos : : EConstraintType : : JointConstraintType ) )
{
if ( Chaos : : FJointConstraint * Constraint = static_cast < Chaos : : FJointConstraint * > ( InConstraintRef . Constraint ) )
{
Constraint - > SetMassConditioningEnabled ( bInMassConditioningEnabled ) ;
}
}
}
2020-08-11 01:36:57 -04:00
void FChaosEngineInterface : : SetBreakForces_AssumesLocked ( const FPhysicsConstraintHandle & InConstraintRef , float InLinearBreakForce , float InAngularBreakTorque )
{
2020-09-24 00:43:27 -04:00
if ( InConstraintRef . IsValid ( ) & & InConstraintRef . Constraint - > IsType ( Chaos : : EConstraintType : : JointConstraintType ) )
2020-08-11 01:36:57 -04:00
{
2020-09-24 00:43:27 -04:00
if ( Chaos : : FJointConstraint * Constraint = static_cast < Chaos : : FJointConstraint * > ( InConstraintRef . Constraint ) )
2020-08-11 01:36:57 -04:00
{
Constraint - > SetLinearBreakForce ( InLinearBreakForce ) ;
Constraint - > SetAngularBreakTorque ( InAngularBreakTorque ) ;
}
}
}
2021-07-02 13:30:22 -04:00
void FChaosEngineInterface : : SetPlasticityLimits_AssumesLocked ( const FPhysicsConstraintHandle & InConstraintRef , float InLinearPlasticityLimit , float InAngularPlasticityLimit , EConstraintPlasticityType InLinearPlasticityType )
2021-01-12 20:32:56 -04:00
{
if ( InConstraintRef . IsValid ( ) & & InConstraintRef . Constraint - > IsType ( Chaos : : EConstraintType : : JointConstraintType ) )
{
if ( Chaos : : FJointConstraint * Constraint = static_cast < Chaos : : FJointConstraint * > ( InConstraintRef . Constraint ) )
{
2021-07-02 13:30:22 -04:00
Constraint - > SetLinearPlasticityType ( ( Chaos : : EPlasticityType ) InLinearPlasticityType ) ;
2021-01-12 20:32:56 -04:00
Constraint - > SetLinearPlasticityLimit ( InLinearPlasticityLimit ) ;
Constraint - > SetAngularPlasticityLimit ( InAngularPlasticityLimit ) ;
}
}
}
2021-09-03 20:11:35 -04:00
void FChaosEngineInterface : : SetContactTransferScale_AssumesLocked ( const FPhysicsConstraintHandle & InConstraintRef , float InContactTransferScale )
{
if ( InConstraintRef . IsValid ( ) & & InConstraintRef . Constraint - > IsType ( Chaos : : EConstraintType : : JointConstraintType ) )
{
if ( Chaos : : FJointConstraint * Constraint = static_cast < Chaos : : FJointConstraint * > ( InConstraintRef . Constraint ) )
{
Constraint - > SetContactTransferScale ( InContactTransferScale ) ;
}
}
}
2020-08-11 01:36:57 -04:00
void FChaosEngineInterface : : SetLocalPose ( const FPhysicsConstraintHandle & InConstraintRef , const FTransform & InPose , EConstraintFrame : : Type InFrame )
{
2021-05-31 13:50:42 -04:00
if ( InConstraintRef . IsValid ( ) & & InConstraintRef . Constraint - > IsType ( Chaos : : EConstraintType : : JointConstraintType ) )
{
if ( Chaos : : FJointConstraint * Constraint = static_cast < Chaos : : FJointConstraint * > ( InConstraintRef . Constraint ) )
{
2021-09-17 16:57:27 -04:00
Chaos : : FTransformPair JointTransforms = Constraint - > GetJointTransforms ( ) ;
2021-05-31 13:50:42 -04:00
if ( InFrame = = EConstraintFrame : : Frame1 )
{
JointTransforms [ 0 ] = InPose ;
}
else
{
JointTransforms [ 1 ] = InPose ;
}
Constraint - > SetJointTransforms ( JointTransforms ) ;
}
}
2020-08-11 01:36:57 -04:00
}
void FChaosEngineInterface : : SetDrivePosition ( const FPhysicsConstraintHandle & InConstraintRef , const FVector & InPosition )
{
2020-09-24 00:43:27 -04:00
if ( InConstraintRef . IsValid ( ) & & InConstraintRef . Constraint - > IsType ( Chaos : : EConstraintType : : JointConstraintType ) )
2020-08-11 01:36:57 -04:00
{
2020-09-24 00:43:27 -04:00
if ( Chaos : : FJointConstraint * Constraint = static_cast < Chaos : : FJointConstraint * > ( InConstraintRef . Constraint ) )
2020-08-11 01:36:57 -04:00
{
Constraint - > SetLinearDrivePositionTarget ( InPosition ) ;
}
}
}
void FChaosEngineInterface : : SetDriveOrientation ( const FPhysicsConstraintHandle & InConstraintRef , const FQuat & InOrientation )
{
2020-09-24 00:43:27 -04:00
if ( InConstraintRef . IsValid ( ) & & InConstraintRef . Constraint - > IsType ( Chaos : : EConstraintType : : JointConstraintType ) )
2020-08-11 01:36:57 -04:00
{
2020-09-24 00:43:27 -04:00
if ( Chaos : : FJointConstraint * Constraint = static_cast < Chaos : : FJointConstraint * > ( InConstraintRef . Constraint ) )
2020-08-11 01:36:57 -04:00
{
Constraint - > SetAngularDrivePositionTarget ( InOrientation ) ;
}
}
}
void FChaosEngineInterface : : SetDriveLinearVelocity ( const FPhysicsConstraintHandle & InConstraintRef , const FVector & InLinVelocity )
{
2020-09-24 00:43:27 -04:00
if ( InConstraintRef . IsValid ( ) & & InConstraintRef . Constraint - > IsType ( Chaos : : EConstraintType : : JointConstraintType ) )
2020-08-11 01:36:57 -04:00
{
2020-09-24 00:43:27 -04:00
if ( Chaos : : FJointConstraint * Constraint = static_cast < Chaos : : FJointConstraint * > ( InConstraintRef . Constraint ) )
2020-08-11 01:36:57 -04:00
{
Constraint - > SetLinearDriveVelocityTarget ( InLinVelocity ) ;
}
}
}
void FChaosEngineInterface : : SetDriveAngularVelocity ( const FPhysicsConstraintHandle & InConstraintRef , const FVector & InAngVelocity )
{
2020-09-24 00:43:27 -04:00
if ( InConstraintRef . IsValid ( ) & & InConstraintRef . Constraint - > IsType ( Chaos : : EConstraintType : : JointConstraintType ) )
2020-08-11 01:36:57 -04:00
{
2020-09-24 00:43:27 -04:00
if ( Chaos : : FJointConstraint * Constraint = static_cast < Chaos : : FJointConstraint * > ( InConstraintRef . Constraint ) )
2020-08-11 01:36:57 -04:00
{
Constraint - > SetAngularDriveVelocityTarget ( InAngVelocity ) ;
}
}
}
void FChaosEngineInterface : : SetTwistLimit ( const FPhysicsConstraintHandle & InConstraintRef , float InLowerLimit , float InUpperLimit , float InContactDistance )
{
2020-09-24 00:43:27 -04:00
if ( InConstraintRef . IsValid ( ) & & InConstraintRef . Constraint - > IsType ( Chaos : : EConstraintType : : JointConstraintType ) )
2020-08-11 01:36:57 -04:00
{
2020-09-24 00:43:27 -04:00
if ( Chaos : : FJointConstraint * Constraint = static_cast < Chaos : : FJointConstraint * > ( InConstraintRef . Constraint ) )
2020-08-11 01:36:57 -04:00
{
2020-09-01 14:07:48 -04:00
Chaos : : FVec3 Limit = Constraint - > GetAngularLimits ( ) ;
Limit [ ( int32 ) Chaos : : EJointAngularConstraintIndex : : Twist ] = FMath : : DegreesToRadians ( InUpperLimit - InLowerLimit ) ;
Constraint - > SetAngularLimits ( Limit ) ;
Constraint - > SetTwistContactDistance ( InContactDistance ) ;
2020-08-11 01:36:57 -04:00
}
}
}
void FChaosEngineInterface : : SetSwingLimit ( const FPhysicsConstraintHandle & InConstraintRef , float InYLimit , float InZLimit , float InContactDistance )
{
2020-09-24 00:43:27 -04:00
if ( InConstraintRef . IsValid ( ) & & InConstraintRef . Constraint - > IsType ( Chaos : : EConstraintType : : JointConstraintType ) )
2020-08-11 01:36:57 -04:00
{
2020-09-24 00:43:27 -04:00
if ( Chaos : : FJointConstraint * Constraint = static_cast < Chaos : : FJointConstraint * > ( InConstraintRef . Constraint ) )
2020-08-11 01:36:57 -04:00
{
2020-09-01 14:07:48 -04:00
Chaos : : FVec3 Limit = Constraint - > GetAngularLimits ( ) ;
Limit [ ( int32 ) Chaos : : EJointAngularConstraintIndex : : Swing1 ] = FMath : : DegreesToRadians ( InYLimit ) ;
Limit [ ( int32 ) Chaos : : EJointAngularConstraintIndex : : Swing2 ] = FMath : : DegreesToRadians ( InZLimit ) ;
Constraint - > SetAngularLimits ( Limit ) ;
Constraint - > SetSwingContactDistance ( InContactDistance ) ;
2020-08-11 01:36:57 -04:00
}
}
}
void FChaosEngineInterface : : SetLinearLimit ( const FPhysicsConstraintHandle & InConstraintRef , float InLinearLimit )
{
2020-09-24 00:43:27 -04:00
if ( InConstraintRef . IsValid ( ) & & InConstraintRef . Constraint - > IsType ( Chaos : : EConstraintType : : JointConstraintType ) )
2020-08-11 01:36:57 -04:00
{
2020-09-24 00:43:27 -04:00
if ( Chaos : : FJointConstraint * Constraint = static_cast < Chaos : : FJointConstraint * > ( InConstraintRef . Constraint ) )
2020-08-11 01:36:57 -04:00
{
Constraint - > SetLinearLimit ( InLinearLimit ) ;
}
}
}
bool FChaosEngineInterface : : IsBroken ( const FPhysicsConstraintHandle & InConstraintRef )
{
2020-09-24 00:43:27 -04:00
if ( InConstraintRef . IsValid ( ) & & InConstraintRef . Constraint - > IsType ( Chaos : : EConstraintType : : JointConstraintType ) )
2020-09-01 14:07:48 -04:00
{
2020-09-24 00:43:27 -04:00
if ( Chaos : : FJointConstraint * Constraint = static_cast < Chaos : : FJointConstraint * > ( InConstraintRef . Constraint ) )
2020-09-01 14:07:48 -04:00
{
return Constraint - > GetOutputData ( ) . bIsBroken ;
}
}
return false ;
2020-08-11 01:36:57 -04:00
}
2020-11-24 18:42:39 -04:00
2023-07-31 17:46:47 -04:00
void FChaosEngineInterface : : SetGeometry ( FPhysicsShapeHandle & InShape , Chaos : : FImplicitObjectPtr & & InGeometry )
2020-11-24 18:42:39 -04:00
{
using namespace Chaos ;
// This sucks, we build a new union with input geometry. All other geo is copied.
// Cannot modify union as it is shared between threads.
2021-02-03 14:57:28 -04:00
const FShapesArray & ShapeArray = InShape . ActorRef - > GetGameThreadAPI ( ) . ShapesArray ( ) ;
2020-11-24 18:42:39 -04:00
2023-07-31 17:46:47 -04:00
TArray < Chaos : : FImplicitObjectPtr > NewGeometry ;
2020-11-24 18:42:39 -04:00
NewGeometry . Reserve ( ShapeArray . Num ( ) ) ;
int32 ShapeIdx = 0 ;
for ( const TUniquePtr < Chaos : : FPerShapeData > & Shape : ShapeArray )
{
if ( Shape . Get ( ) = = InShape . Shape )
{
NewGeometry . Emplace ( MoveTemp ( InGeometry ) ) ;
}
else
{
2023-07-31 17:46:47 -04:00
NewGeometry . Emplace ( Shape - > GetGeometry ( ) - > CopyGeometry ( ) ) ;
2020-11-24 18:42:39 -04:00
}
ShapeIdx + + ;
}
if ( ensure ( NewGeometry . Num ( ) = = ShapeArray . Num ( ) ) )
{
2023-07-31 17:46:47 -04:00
Chaos : : FImplicitObjectPtr ImplicitUnion = MakeImplicitObjectPtr < Chaos : : FImplicitObjectUnion > ( MoveTemp ( NewGeometry ) ) ;
InShape . ActorRef - > GetGameThreadAPI ( ) . SetGeometry ( ImplicitUnion ) ;
2020-11-24 18:42:39 -04:00
FChaosScene * Scene = FChaosEngineInterface : : GetCurrentScene ( InShape . ActorRef ) ;
if ( ensure ( Scene ) )
{
Scene - > UpdateActorInAccelerationStructure ( InShape . ActorRef ) ;
}
}
}
2020-08-11 01:36:57 -04:00
// @todo(chaos): We probably need to actually duplicate the data here, add virtual TImplicitObject::NewCopy()
FPhysicsShapeHandle FChaosEngineInterface : : CloneShape ( const FPhysicsShapeHandle & InShape )
{
FPhysicsActorHandle NewActor = nullptr ;
return { InShape . Shape , NewActor } ;
}
FPhysicsGeometryCollection_Chaos FChaosEngineInterface : : GetGeometryCollection ( const FPhysicsShapeHandle & InShape )
{
FPhysicsGeometryCollection_Chaos NewCollection ( InShape ) ;
return NewCollection ;
}
2023-05-17 19:11:33 -04:00
FPhysicsGeometryCollection_Chaos FChaosEngineInterface : : GetGeometryCollection ( const FPhysicsGeometry & InShape )
{
return FPhysicsGeometryCollection_Chaos { InShape } ;
}
2022-03-28 08:20:29 -04:00
void FChaosEngineInterface : : SetMaskFilter ( const FPhysicsShapeHandle & InShape , FMaskFilter InFilter )
{
FCollisionFilterData SimFilter = GetSimulationFilter ( InShape ) ;
FCollisionFilterData QueryFilter = GetQueryFilter ( InShape ) ;
auto ApplyMask = [ ] ( uint32 & Word3 , FMaskFilter Mask )
{
// #CHAOSTODO - definitions for filter behavior are in the Engine module.
// Move all to PhysicsCore so we handle things in a safe way here.
static constexpr int32 LocalNumExtraBits = 6 ;
static_assert ( LocalNumExtraBits < = 8 , " Only up to 8 extra filter bits are supported. " ) ;
Word3 & = ( 0xFFFFFFFFu > > LocalNumExtraBits ) ; //we drop the top NumExtraFilterBits bits because that's where the new mask filter is going
Word3 | = uint32 ( Mask ) < < ( 32 - LocalNumExtraBits ) ;
} ;
ApplyMask ( SimFilter . Word3 , InFilter ) ;
ApplyMask ( QueryFilter . Word3 , InFilter ) ;
SetSimulationFilter ( InShape , SimFilter ) ;
SetQueryFilter ( InShape , QueryFilter ) ;
}
2020-08-11 01:36:57 -04:00
FCollisionFilterData FChaosEngineInterface : : GetSimulationFilter ( const FPhysicsShapeReference_Chaos & InShape )
{
if ( ensure ( InShape . Shape ) )
{
return InShape . Shape - > GetSimData ( ) ;
} else
{
return FCollisionFilterData ( ) ;
}
}
FCollisionFilterData FChaosEngineInterface : : GetQueryFilter ( const FPhysicsShapeReference_Chaos & InShape )
{
if ( ensure ( InShape . Shape ) )
{
return InShape . Shape - > GetQueryData ( ) ;
} else
{
return FCollisionFilterData ( ) ;
}
}
void FChaosEngineInterface : : SetQueryFilter ( const FPhysicsShapeReference_Chaos & InShapeRef , const FCollisionFilterData & InFilter )
{
InShapeRef . Shape - > SetQueryData ( InFilter ) ;
}
void FChaosEngineInterface : : SetSimulationFilter ( const FPhysicsShapeReference_Chaos & InShapeRef , const FCollisionFilterData & InFilter )
{
InShapeRef . Shape - > SetSimData ( InFilter ) ;
}
bool FChaosEngineInterface : : IsSimulationShape ( const FPhysicsShapeHandle & InShape )
{
return InShape . Shape - > GetSimEnabled ( ) ;
}
bool FChaosEngineInterface : : IsQueryShape ( const FPhysicsShapeHandle & InShape )
{
// This data is not stored on concrete shape. TODO: Remove ensure if we actually use this flag when constructing shape handles.
CHAOS_ENSURE ( false ) ;
return InShape . Shape - > GetQueryEnabled ( ) ;
}
ECollisionShapeType FChaosEngineInterface : : GetShapeType ( const FPhysicsShapeReference_Chaos & InShapeRef )
{
2022-11-02 14:19:06 -04:00
return ChaosInterface : : GetImplicitType ( * InShapeRef . Shape - > GetGeometry ( ) ) ;
2020-08-11 01:36:57 -04:00
}
FTransform FChaosEngineInterface : : GetLocalTransform ( const FPhysicsShapeReference_Chaos & InShapeRef )
{
// Transforms are baked into the object so there is never a local transform
if ( InShapeRef . Shape - > GetGeometry ( ) - > GetType ( ) = = Chaos : : ImplicitObjectType : : Transformed & & FChaosEngineInterface : : IsValid ( InShapeRef . ActorRef ) )
{
2021-05-05 15:07:25 -04:00
return InShapeRef . Shape - > GetGeometry ( ) - > GetObject < Chaos : : TImplicitObjectTransformed < Chaos : : FReal , 3 > > ( ) - > GetTransform ( ) ;
2020-08-11 01:36:57 -04:00
} else
{
return FTransform ( ) ;
}
}
void FChaosEngineInterface : : SetLocalTransform ( const FPhysicsShapeHandle & InShape , const FTransform & NewLocalTransform )
{
2022-03-01 19:55:30 -05:00
using namespace Chaos ;
FSingleParticlePhysicsProxy * Particle = InShape . ActorRef ;
if ( Particle )
2020-08-11 01:36:57 -04:00
{
2022-03-01 19:55:30 -05:00
Chaos : : FRigidBodyHandle_External & BodyHandle = Particle - > GetGameThreadAPI ( ) ;
2023-07-31 17:46:47 -04:00
const FImplicitObjectRef CurrentGeom = BodyHandle . GetGeometry ( ) ;
2022-03-01 19:55:30 -05:00
if ( ensure ( CurrentGeom & & CurrentGeom - > GetType ( ) = = FImplicitObjectUnion : : StaticType ( ) ) )
2020-08-11 01:36:57 -04:00
{
2022-03-01 19:55:30 -05:00
const FImplicitObjectUnion * AsUnion = static_cast < const FImplicitObjectUnion * > ( CurrentGeom ) ;
const int32 ShapeIndex = InShape . Shape - > GetShapeIndex ( ) ;
2023-07-31 17:46:47 -04:00
const TArray < Chaos : : FImplicitObjectPtr > & ObjectArray = AsUnion - > GetObjects ( ) ;
2022-03-01 19:55:30 -05:00
2023-09-19 10:42:54 -04:00
if ( ensure ( ShapeIndex < ObjectArray . Num ( ) ) )
2022-03-01 19:55:30 -05:00
{
2023-07-31 17:46:47 -04:00
TArray < Chaos : : FImplicitObjectPtr > NewGeoms ;
2022-03-01 19:55:30 -05:00
NewGeoms . Reserve ( ObjectArray . Num ( ) ) ;
// Duplicate the union and either set transforms, or wrap in transforms
2023-09-19 10:42:54 -04:00
int32 CurrentIndex = 0 ;
2023-07-31 17:46:47 -04:00
for ( const Chaos : : FImplicitObjectPtr & Obj : ObjectArray )
2022-03-01 19:55:30 -05:00
{
if ( CurrentIndex = = ShapeIndex )
{
2023-07-31 17:46:47 -04:00
NewGeoms . Emplace ( Utilities : : DuplicateGeometryWithTransform ( Obj . GetReference ( ) , NewLocalTransform ) ) ;
2022-03-01 19:55:30 -05:00
}
else
{
2023-07-31 17:46:47 -04:00
NewGeoms . Emplace ( Obj - > CopyGeometry ( ) ) ;
2022-03-01 19:55:30 -05:00
}
CurrentIndex + + ;
}
if ( ensure ( NewGeoms . Num ( ) = = ObjectArray . Num ( ) ) )
{
2023-07-31 17:46:47 -04:00
Chaos : : FImplicitObjectPtr ImplicitUnion = MakeImplicitObjectPtr < FImplicitObjectUnion > ( MoveTemp ( NewGeoms ) ) ;
BodyHandle . SetGeometry ( ImplicitUnion ) ;
2022-03-01 19:55:30 -05:00
}
}
2020-08-11 01:36:57 -04:00
}
}
}
template < typename AllocatorType >
int32 GetAllShapesInternalImp_AssumedLocked ( const FPhysicsActorHandle & InActorHandle , TArray < FPhysicsShapeReference_Chaos , AllocatorType > & OutShapes )
{
2022-08-08 07:25:52 -04:00
if ( InActorHandle )
2020-08-11 01:36:57 -04:00
{
2022-08-08 07:25:52 -04:00
const Chaos : : FShapesArray & ShapesArray = InActorHandle - > GetGameThreadAPI ( ) . ShapesArray ( ) ;
2023-09-19 10:42:54 -04:00
const int32 NumRelevantShapes = ShapesArray . Num ( ) ;
OutShapes . Reset ( NumRelevantShapes ) ;
2022-08-08 07:25:52 -04:00
//todo: can we avoid this construction?
2023-09-19 10:42:54 -04:00
for ( int32 ShapeIndex = 0 ; ShapeIndex < NumRelevantShapes ; + + ShapeIndex )
2022-08-08 07:25:52 -04:00
{
2023-09-19 10:42:54 -04:00
OutShapes . Add ( FPhysicsShapeReference_Chaos ( ShapesArray [ ShapeIndex ] . Get ( ) , InActorHandle ) ) ;
2022-08-08 07:25:52 -04:00
}
return OutShapes . Num ( ) ;
2020-08-11 01:36:57 -04:00
}
2022-08-08 07:25:52 -04:00
return 0 ;
2020-08-11 01:36:57 -04:00
}
int32 FChaosEngineInterface : : GetAllShapes_AssumedLocked ( const FPhysicsActorHandle & InActorHandle , TArray < FPhysicsShapeReference_Chaos , FDefaultAllocator > & OutShapes )
{
return GetAllShapesInternalImp_AssumedLocked ( InActorHandle , OutShapes ) ;
}
int32 FChaosEngineInterface : : GetAllShapes_AssumedLocked ( const FPhysicsActorHandle & InActorHandle , PhysicsInterfaceTypes : : FInlineShapeArray & OutShapes )
{
return GetAllShapesInternalImp_AssumedLocked ( InActorHandle , OutShapes ) ;
}
void FChaosEngineInterface : : CreateActor ( const FActorCreationParams & InParams , FPhysicsActorHandle & Handle )
{
2021-12-13 13:05:20 -05:00
LLM_SCOPE ( ELLMTag : : ChaosActor ) ;
2021-03-05 19:27:14 -04:00
using namespace Chaos ;
2020-08-11 01:36:57 -04:00
2021-03-05 19:27:14 -04:00
TUniquePtr < FGeometryParticle > Particle ;
2020-08-11 01:36:57 -04:00
// Set object state based on the requested particle type
if ( InParams . bStatic )
{
2021-03-05 19:27:14 -04:00
Particle = FGeometryParticle : : CreateParticle ( ) ;
Chaos terminology pass
#rb Chris.Caulfield, Kriss.Gossart, Cedric.Caillaud, Jaco.VanDyk, Michael.Forot
#jira UE-159295, UE-158667, UE-158656, UE-158652, UE-158651, UE-158640, UE-158526
#preflight 6320a9cd9677b738f497c14f
[CL 22035600 by benn gallagher in ue5-main branch]
2022-09-15 15:09:35 -04:00
Particle - > SetResimType ( EResimType : : ResimAsFollower ) ;
2021-02-03 14:57:28 -04:00
}
else
2020-08-11 01:36:57 -04:00
{
// Create an underlying dynamic particle
2021-03-05 19:27:14 -04:00
TUniquePtr < FPBDRigidParticle > Rigid = FPBDRigidParticle : : CreateParticle ( ) ;
2021-02-03 14:57:28 -04:00
Rigid - > SetGravityEnabled ( InParams . bEnableGravity ) ;
2023-04-27 13:26:51 -04:00
Rigid - > SetUpdateKinematicFromSimulation ( InParams . bUpdateKinematicFromSimulation ) ;
2020-09-01 14:07:48 -04:00
if ( InParams . bSimulatePhysics )
2020-08-11 01:36:57 -04:00
{
2020-09-01 14:07:48 -04:00
if ( InParams . bStartAwake )
2020-08-11 01:36:57 -04:00
{
2021-03-05 19:27:14 -04:00
Rigid - > SetObjectState ( EObjectStateType : : Dynamic ) ;
2020-08-11 01:36:57 -04:00
} else
{
2021-03-05 19:27:14 -04:00
Rigid - > SetObjectState ( EObjectStateType : : Sleeping ) ;
2020-08-11 01:36:57 -04:00
}
2021-03-05 19:27:14 -04:00
Rigid - > SetResimType ( EResimType : : FullResim ) ;
2020-08-11 01:36:57 -04:00
} else
{
2021-03-05 19:27:14 -04:00
Rigid - > SetObjectState ( EObjectStateType : : Kinematic ) ;
Chaos terminology pass
#rb Chris.Caulfield, Kriss.Gossart, Cedric.Caillaud, Jaco.VanDyk, Michael.Forot
#jira UE-159295, UE-158667, UE-158656, UE-158652, UE-158651, UE-158640, UE-158526
#preflight 6320a9cd9677b738f497c14f
[CL 22035600 by benn gallagher in ue5-main branch]
2022-09-15 15:09:35 -04:00
Rigid - > SetResimType ( EResimType : : ResimAsFollower ) ; //for now kinematics are never changed during resim
2020-08-11 01:36:57 -04:00
}
2021-02-03 14:57:28 -04:00
//Particle.Reset(Rigid.Release());
Particle = MoveTemp ( Rigid ) ;
2020-08-11 01:36:57 -04:00
}
2023-02-23 05:05:35 -05:00
// Set the particle acceleration structure spatial index here
{
FSpatialAccelerationIdx SpatialIndex { 0 , ESpatialAccelerationCollectionBucketInnerIdx : : Default } ;
if ( AccelerationStructureSplitStaticAndDynamic = = 1 )
{
if ( AccelerationStructureIsolateQueryOnlyObjects = = 1 )
{
if ( InParams . bStatic & & InParams . bQueryOnly )
{
SpatialIndex = FSpatialAccelerationIdx { 0 , ESpatialAccelerationCollectionBucketInnerIdx : : DefaultQueryOnly } ;
}
else if ( ! InParams . bStatic & & InParams . bQueryOnly )
{
SpatialIndex = FSpatialAccelerationIdx { 0 , ESpatialAccelerationCollectionBucketInnerIdx : : DynamicQueryOnly } ;
}
else if ( ! InParams . bStatic & & ! InParams . bQueryOnly )
{
SpatialIndex = FSpatialAccelerationIdx { 0 , ESpatialAccelerationCollectionBucketInnerIdx : : Dynamic } ;
}
}
else
{
if ( ! InParams . bStatic )
{
SpatialIndex = FSpatialAccelerationIdx { 0 , ESpatialAccelerationCollectionBucketInnerIdx : : Dynamic } ;
}
}
}
else
{
if ( AccelerationStructureIsolateQueryOnlyObjects = = 1 )
{
if ( InParams . bQueryOnly )
{
SpatialIndex = FSpatialAccelerationIdx { 0 , ESpatialAccelerationCollectionBucketInnerIdx : : DefaultQueryOnly } ;
}
}
}
Particle - > SetSpatialIdx ( SpatialIndex ) ;
}
2021-09-22 15:51:55 -04:00
Handle = Chaos : : FSingleParticlePhysicsProxy : : Create ( MoveTemp ( Particle ) ) ;
2021-02-03 14:57:28 -04:00
Chaos : : FRigidBodyHandle_External & Body_External = Handle - > GetGameThreadAPI ( ) ;
2020-08-11 01:36:57 -04:00
// Set up the new particle's game-thread data. This will be sent to physics-thread when
// the particle is added to the scene later.
2021-02-03 14:57:28 -04:00
Body_External . SetX ( InParams . InitialTM . GetLocation ( ) , /*bInvalidate=*/ false ) ; //do not generate wake event since this is part of initialization
Body_External . SetR ( InParams . InitialTM . GetRotation ( ) , /*bInvalidate=*/ false ) ;
2021-08-03 11:56:47 -04:00
# if CHAOS_DEBUG_NAME
Body_External . SetDebugName ( MakeShareable ( new FString ( InParams . DebugName ) ) ) ;
2020-08-11 01:36:57 -04:00
# endif
}
void FChaosEngineInterface : : ReleaseActor ( FPhysicsActorHandle & Handle , FChaosScene * InScene , bool bNeverDerferRelease )
{
if ( ! Handle )
{
2022-07-04 07:30:34 -04:00
UE_LOG ( LogChaos , Verbose , TEXT ( " Attempting to release an actor with a null handle " ) ) ;
2020-08-11 01:36:57 -04:00
return ;
}
if ( InScene )
{
InScene - > RemoveActorFromAccelerationStructure ( Handle ) ;
RemoveActorFromSolver ( Handle , InScene - > GetSolver ( ) ) ;
}
2021-02-03 14:57:28 -04:00
else
{
delete Handle ;
}
2020-08-11 01:36:57 -04:00
Handle = nullptr ;
}
FChaosScene * FChaosEngineInterface : : GetCurrentScene ( const FPhysicsActorHandle & InHandle )
{
if ( ! InHandle )
{
return nullptr ;
}
2021-02-03 14:57:28 -04:00
Chaos : : FPBDRigidsSolver * Solver = InHandle - > GetSolver < Chaos : : FPBDRigidsSolver > ( ) ;
2021-04-29 19:32:06 -04:00
return static_cast < FChaosScene * > ( Solver ? Solver - > PhysSceneHack : nullptr ) ;
2020-08-11 01:36:57 -04:00
}
void FChaosEngineInterface : : SetGlobalPose_AssumesLocked ( const FPhysicsActorHandle & InActorReference , const FTransform & InNewPose , bool bAutoWake )
{
2021-02-03 14:57:28 -04:00
Chaos : : FRigidBodyHandle_External & Body_External = InActorReference - > GetGameThreadAPI ( ) ;
2022-06-22 15:44:37 -04:00
if ( ! IsKinematic ( InActorReference ) & & ! IsSleeping ( InActorReference ) & & Chaos : : FVec3 : : IsNearlyEqual ( InNewPose . GetLocation ( ) , Body_External . X ( ) , SMALL_NUMBER ) & & Chaos : : FRotation3 : : IsNearlyEqual ( InNewPose . GetRotation ( ) , Body_External . R ( ) , SMALL_NUMBER ) )
2022-06-17 16:42:06 -04:00
{
2022-06-22 15:44:37 -04:00
// if simulating, don't update X/R if they haven't changed. this allows scale to be set on simulating body without overriding async position/rotation.
2022-06-17 16:42:06 -04:00
return ;
}
2023-01-05 17:47:41 -05:00
if ( IsKinematic ( InActorReference ) )
{
2023-10-11 11:25:36 -04:00
// NOTE: SetGlobalPose is a teleport for kinematics. Use SetKinematicTarget_AssumesLocked
// if the kinematic should calculate its velocity from the transform delta.
Body_External . SetKinematicTarget ( InNewPose ) ;
Body_External . SetV ( FVector : : Zero ( ) ) ;
Body_External . SetW ( FVector : : Zero ( ) ) ;
2023-01-05 17:47:41 -05:00
}
2023-10-11 11:25:36 -04:00
Body_External . SetX ( InNewPose . GetLocation ( ) ) ;
Body_External . SetR ( InNewPose . GetRotation ( ) ) ;
2021-02-03 14:57:28 -04:00
Body_External . UpdateShapeBounds ( ) ;
2020-08-11 01:36:57 -04:00
FChaosScene * Scene = GetCurrentScene ( InActorReference ) ;
Scene - > UpdateActorInAccelerationStructure ( InActorReference ) ;
}
2023-09-14 06:07:30 -04:00
// Match the logic in places that use SyncKinematicOnGameThread (like
// FSingleParticlePhysicsProxy::PullFromPhysicsState) - to see if that will be updating the
// position. If not, then we need to do it here.
bool ShouldSetKinematicTargetSetGameTransform ( const FPhysicsActorHandle & InActorReference )
2020-08-11 01:36:57 -04:00
{
2023-04-27 13:26:51 -04:00
Chaos : : FPBDRigidParticle * Rigid = InActorReference - > GetRigidParticleUnsafe ( ) ;
if ( Rigid & & Rigid - > ObjectState ( ) = = Chaos : : EObjectStateType : : Kinematic )
{
switch ( Chaos : : SyncKinematicOnGameThread )
{
case 0 :
2023-09-14 06:07:30 -04:00
return true ;
2023-04-27 13:26:51 -04:00
case 1 :
2023-09-14 06:07:30 -04:00
return false ;
2023-04-27 13:26:51 -04:00
default :
2023-09-14 06:07:30 -04:00
return ! Rigid - > UpdateKinematicFromSimulation ( ) ;
2023-04-27 13:26:51 -04:00
}
}
2023-09-14 06:07:30 -04:00
// Historically the game TM gets set through using the kinematic target even if called with a
// non-kinematic object, so preserve that behavior.
return true ;
}
2020-11-24 18:42:39 -04:00
2023-09-14 06:07:30 -04:00
void FChaosEngineInterface : : SetKinematicTarget_AssumesLocked ( const FPhysicsActorHandle & InActorReference , const FTransform & InNewTarget )
{
// SetKinematicTarget_AssumesLocked could be called multiple times in one time step
const Chaos : : FKinematicTarget NewKinematicTarget = Chaos : : FKinematicTarget : : MakePositionTarget ( InNewTarget ) ;
InActorReference - > GetGameThreadAPI ( ) . SetKinematicTarget ( NewKinematicTarget ) ;
2023-10-11 11:25:36 -04:00
// If enabled for this body, immediately update the body transforms to match the kinematic target.
// @todo(chaos): Velocity is not updated here and never will be because we don't read back from the physics thread.
// We should fix this, but it is awkward to handle multiple calls to SetKinematicTarget on the same frame if we
// don't have a "previous transform" from which to calculate the velocity and we have overwritten X/R already.
2023-09-14 06:07:30 -04:00
if ( ShouldSetKinematicTargetSetGameTransform ( InActorReference ) )
2023-04-27 13:26:51 -04:00
{
// IMPORTANT : we do not invalidate X and R as they will be properly computed using the kinematic target information
2023-10-11 11:25:36 -04:00
InActorReference - > GetGameThreadAPI ( ) . SetX ( InNewTarget . GetLocation ( ) , false ) ;
InActorReference - > GetGameThreadAPI ( ) . SetR ( InNewTarget . GetRotation ( ) , false ) ;
2023-04-27 13:26:51 -04:00
InActorReference - > GetGameThreadAPI ( ) . UpdateShapeBounds ( ) ;
FChaosScene * Scene = GetCurrentScene ( InActorReference ) ;
Scene - > UpdateActorInAccelerationStructure ( InActorReference ) ;
}
2020-08-11 01:36:57 -04:00
}