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"
2020-08-11 01:36:57 -04:00
FPhysicsDelegatesCore : : FOnUpdatePhysXMaterial FPhysicsDelegatesCore : : OnUpdatePhysXMaterial ;
# if WITH_CHAOS
# 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"
2020-08-11 01:36:57 -04:00
# include "PBDRigidsSolver.h"
2021-02-03 14:57:28 -04:00
# include "PhysicsProxy/SingleParticlePhysicsProxy.h"
2020-08-11 01:36:57 -04: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
{
return GetImplicitType ( Geom ) ;
}
const Chaos : : FImplicitObject & FPhysicsGeometryCollection_Chaos : : GetGeometry ( ) const
{
return Geom ;
}
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
{
2021-03-18 15:20:03 -04:00
return Geom . GetObjectChecked < Chaos : : TBox < Chaos : : FReal , 3 > > ( ) ;
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
{
2021-03-18 15:20:03 -04:00
return Geom . GetObjectChecked < Chaos : : TSphere < Chaos : : FReal , 3 > > ( ) ;
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
{
2021-03-05 19:27:14 -04:00
return Geom . GetObjectChecked < Chaos : : FCapsule > ( ) ;
2020-08-11 01:36:57 -04:00
}
const Chaos : : FConvex & FPhysicsGeometryCollection_Chaos : : GetConvexGeometry ( ) const
{
return Geom . GetObjectChecked < Chaos : : FConvex > ( ) ;
}
const Chaos : : FTriangleMeshImplicitObject & FPhysicsGeometryCollection_Chaos : : GetTriMeshGeometry ( ) const
{
return Geom . GetObjectChecked < Chaos : : FTriangleMeshImplicitObject > ( ) ;
}
FPhysicsGeometryCollection_Chaos : : FPhysicsGeometryCollection_Chaos ( const FPhysicsShapeReference_Chaos & InShape )
: Geom ( InShape . GetGeometry ( ) )
{
}
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 ( ) ) ;
2021-03-05 19:27:14 -04:00
Geometry = TUniquePtr < 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 ( ) ) ;
2021-03-18 15:20:03 -04:00
Geometry = TUniquePtr < 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 ( ) ) ;
2021-03-18 15:20:03 -04:00
Geometry = TUniquePtr < 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 ( ) ) ;
2021-03-18 15:20:03 -04:00
Geometry = TUniquePtr < 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 )
{
LLM_SCOPE ( ELLMTag : : Chaos ) ;
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 ) ;
Material - > SleepingLinearThreshold = InMaterial - > SleepLinearVelocityThreshold ;
Material - > SleepingAngularThreshold = InMaterial - > SleepAngularVelocityThreshold ;
Material - > SleepCounterThreshold = InMaterial - > SleepCounterThreshold ;
}
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
}
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
{
Rigid0 - > SetCollisionConstraintFlag ( ( uint32 ) Chaos : : ECollisionConstraintFlags : : CCF_BroadPhaseIgnoreCollisions ) ;
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
{
Rigid1 - > SetCollisionConstraintFlag ( ( uint32 ) Chaos : : ECollisionConstraintFlags : : CCF_BroadPhaseIgnoreCollisions ) ;
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 )
{
// Do this to match the PhysX interface behavior: :( :( :(
return ! IsStatic ( InActorReference ) ;
}
bool FChaosEngineInterface : : IsStatic ( const FPhysicsActorHandle & InActorReference )
{
2021-02-03 14:57:28 -04:00
return InActorReference - > GetGameThreadAPI ( ) . ObjectState ( ) = = Chaos : : EObjectStateType : : Static ;
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
}
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 )
{
CHAOS_ENSURE ( false ) ;
return FLT_MAX ;
}
void FChaosEngineInterface : : SetMaxDepenetrationVelocity_AssumesLocked ( const FPhysicsActorHandle & InActorReference , float InMaxDepenetrationVelocity )
{
CHAOS_ENSURE ( false ) ;
}
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 ( ) ;
if ( ensure ( 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 ) ;
}
2020-10-09 22:42:26 -04:00
# if WITH_CHAOS
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
}
# endif
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 )
{
2021-03-05 19:27:14 -04:00
const Chaos : : FMatrix33 Tensor = InActorReference - > GetGameThreadAPI ( ) . I ( ) ;
2021-02-03 14:57:28 -04:00
return FVector ( Tensor . M [ 0 ] [ 0 ] , Tensor . M [ 1 ] [ 1 ] , Tensor . M [ 2 ] [ 2 ] ) ;
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 ( ) ;
if ( const FImplicitObject * Geometry = Body_External . Geometry ( ) . Get ( ) )
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
}
}
void FChaosEngineInterface : : AddImpulse_AssumesLocked ( const FPhysicsActorHandle & InActorReference , const FVector & InForce )
{
if ( ensure ( FChaosEngineInterface : : IsValid ( InActorReference ) ) )
{
2021-02-03 14:57:28 -04:00
Chaos : : FRigidBodyHandle_External & Body_External = InActorReference - > GetGameThreadAPI ( ) ;
2021-12-02 16:42:39 -05:00
Body_External . SetLinearImpulse ( Body_External . LinearImpulse ( ) + InForce , /*bIsVelocity=*/ false ) ;
2020-08-11 01:36:57 -04:00
}
}
void FChaosEngineInterface : : AddAngularImpulseInRadians_AssumesLocked ( const FPhysicsActorHandle & InActorReference , const FVector & InTorque )
{
if ( ensure ( FChaosEngineInterface : : IsValid ( InActorReference ) ) )
{
2021-02-03 14:57:28 -04:00
Chaos : : FRigidBodyHandle_External & Body_External = InActorReference - > GetGameThreadAPI ( ) ;
2021-12-02 16:42:39 -05:00
Body_External . SetAngularImpulse ( Body_External . AngularImpulse ( ) + InTorque , /*bIsVelocity=*/ false ) ;
2020-08-11 01:36:57 -04:00
}
}
void FChaosEngineInterface : : AddVelocity_AssumesLocked ( const FPhysicsActorHandle & InActorReference , const FVector & InVelocityDelta )
{
if ( ensure ( FChaosEngineInterface : : IsValid ( InActorReference ) ) )
{
2021-02-03 14:57:28 -04:00
AddImpulse_AssumesLocked ( InActorReference , InActorReference - > GetGameThreadAPI ( ) . M ( ) * InVelocityDelta ) ;
2020-08-11 01:36:57 -04:00
}
}
void FChaosEngineInterface : : AddAngularVelocityInRadians_AssumesLocked ( const FPhysicsActorHandle & InActorReference , const FVector & InAngularVelocityDeltaRad )
{
if ( ensure ( FChaosEngineInterface : : IsValid ( InActorReference ) ) )
{
2021-02-03 14:57:28 -04:00
const Chaos : : FMatrix33 WorldI = Chaos : : FParticleUtilitiesXR : : GetWorldInertia ( & InActorReference - > GetGameThreadAPI ( ) ) ;
2021-04-29 19:32:06 -04:00
AddAngularImpulseInRadians_AssumesLocked ( InActorReference , WorldI * InAngularVelocityDeltaRad ) ;
}
2020-08-11 01:36:57 -04:00
}
void FChaosEngineInterface : : AddImpulseAtLocation_AssumesLocked ( const FPhysicsActorHandle & InActorReference , const FVector & InImpulse , const FVector & InLocation )
{
if ( ensure ( FChaosEngineInterface : : IsValid ( InActorReference ) ) )
{
2021-02-03 14:57:28 -04:00
const Chaos : : FVec3 WorldCOM = Chaos : : FParticleUtilitiesGT : : GetCoMWorldPosition ( & InActorReference - > GetGameThreadAPI ( ) ) ;
2021-04-29 19:32:06 -04:00
const Chaos : : FVec3 AngularImpulse = Chaos : : FVec3 : : CrossProduct ( InLocation - WorldCOM , InImpulse ) ;
AddImpulse_AssumesLocked ( InActorReference , InImpulse ) ;
AddAngularImpulseInRadians_AssumesLocked ( InActorReference , AngularImpulse ) ;
}
2020-08-11 01:36:57 -04:00
}
void FChaosEngineInterface : : AddRadialImpulse_AssumesLocked ( const FPhysicsActorHandle & InActorReference , const FVector & InOrigin , float InRadius , float InStrength , ERadialImpulseFalloff InFalloff , bool bInVelChange )
{
2020-11-24 18:42:39 -04:00
using namespace Chaos ;
2021-02-03 14:57:28 -04:00
if ( ensure ( InActorReference - > GetGameThreadAPI ( ) . CanTreatAsRigid ( ) ) )
2020-11-24 18:42:39 -04:00
{
2021-02-03 14:57:28 -04:00
const FVec3 WorldCOM = FParticleUtilitiesGT : : GetCoMWorldPosition ( & InActorReference - > GetGameThreadAPI ( ) ) ;
2020-11-24 18:42:39 -04:00
const FVec3 OriginToActor = WorldCOM - InOrigin ;
const FReal OriginToActorDistance = OriginToActor . Size ( ) ;
2021-02-03 14:57:28 -04:00
if ( OriginToActorDistance < InRadius )
2020-11-24 18:42:39 -04:00
{
2021-03-03 12:28:33 -04:00
FVec3 FinalImpulse = FVector : : ZeroVector ;
2021-02-03 14:57:28 -04:00
if ( OriginToActorDistance > 0 )
2021-04-29 19:32:06 -04:00
{
const FVec3 OriginToActorNorm = OriginToActor / OriginToActorDistance ;
2020-11-24 18:42:39 -04:00
2021-02-03 14:57:28 -04:00
if ( InFalloff = = ERadialImpulseFalloff : : RIF_Constant )
2021-04-29 19:32:06 -04:00
{
2021-03-03 12:28:33 -04:00
FinalImpulse = OriginToActorNorm * InStrength ;
2021-04-29 19:32:06 -04:00
}
2021-02-03 14:57:28 -04:00
else if ( InFalloff = = ERadialImpulseFalloff : : RIF_Linear )
2021-04-29 19:32:06 -04:00
{
const FReal DistanceOverlapping = InRadius - OriginToActorDistance ;
2021-02-03 14:57:28 -04:00
if ( DistanceOverlapping > 0 )
{
2021-04-29 19:32:06 -04:00
FinalImpulse = OriginToActorNorm * FMath : : Lerp ( 0.0f , InStrength , DistanceOverlapping / InRadius ) ;
2020-11-24 18:42:39 -04:00
}
}
else
{
2021-04-29 19:32:06 -04:00
// Unimplemented falloff type
ensure ( false ) ;
}
}
else
{
// 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 ;
}
if ( bInVelChange )
{
AddVelocity_AssumesLocked ( InActorReference , FinalImpulse ) ;
}
else
{
AddImpulse_AssumesLocked ( InActorReference , FinalImpulse ) ;
2020-11-24 18:42:39 -04:00
}
}
}
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
}
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 )
{
}
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 ( ) ;
2021-03-05 19:27:14 -04:00
Body_External . SetI ( Chaos : : FMatrix33 ( InTensor . X , InTensor . Y , InTensor . Z ) ) ;
Body_External . SetInvI ( Chaos : : FMatrix33 ( 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 )
{
//@todo(mlentine): What is InComLocalPose? If the center of an object is not the local pose then many things break including the three vector represtnation of inertia.
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
}
void FChaosEngineInterface : : SetIsSimulationShape ( const FPhysicsShapeHandle & InShape , bool bIsSimShape )
{
InShape . Shape - > SetSimEnabled ( bIsSimShape ) ;
}
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
FPhysicsConstraintHandle FChaosEngineInterface : : CreateConstraint ( const FPhysicsActorHandle & InActorRef1 , const FPhysicsActorHandle & InActorRef2 , const FTransform & InLocalFrame1 , const FTransform & InLocalFrame2 )
{
FPhysicsConstraintHandle ConstraintRef ;
if ( bEnableChaosJointConstraints )
{
2021-02-18 18:13:28 -04:00
if ( InActorRef1 & & InActorRef2 & & InActorRef1 - > GetSolverBase ( ) & & InActorRef2 - > GetSolverBase ( ) )
2020-08-11 01:36:57 -04:00
{
2021-02-03 14:57:28 -04:00
if ( InActorRef1 - > GetSolverBase ( ) & & InActorRef2 - > GetSolverBase ( ) )
2020-08-11 01:36:57 -04:00
{
LLM_SCOPE ( ELLMTag : : Chaos ) ;
2020-09-24 00:43:27 -04:00
auto * JointConstraint = new Chaos : : FJointConstraint ( ) ;
ConstraintRef . Constraint = JointConstraint ;
2020-08-11 01:36:57 -04:00
2021-02-03 14:57:28 -04:00
JointConstraint - > SetParticleProxies ( { InActorRef1 , InActorRef2 } ) ;
2020-09-24 00:43:27 -04:00
JointConstraint - > SetJointTransforms ( { InLocalFrame1 , InLocalFrame2 } ) ;
2020-08-11 01:36:57 -04:00
2021-02-03 14:57:28 -04:00
Chaos : : FPhysicsSolver * Solver = InActorRef1 - > GetSolver < Chaos : : FPhysicsSolver > ( ) ;
checkSlow ( Solver = = InActorRef2 - > GetSolver < Chaos : : FPhysicsSolver > ( ) ) ;
2020-09-24 00:43:27 -04:00
Solver - > RegisterObject ( JointConstraint ) ;
2020-08-11 01:36:57 -04:00
}
}
2020-11-24 18:42:39 -04:00
else if ( InActorRef1 ! = nullptr | | InActorRef2 ! = nullptr )
{
LLM_SCOPE ( ELLMTag : : Chaos ) ;
FPhysicsActorHandle ValidParticle = InActorRef1 ;
bool bSwapped = false ;
if ( ValidParticle = = nullptr )
{
bSwapped = true ;
ValidParticle = InActorRef2 ;
}
2021-02-08 15:59:34 -04:00
if ( ValidParticle - > GetSolverBase ( ) )
2020-11-24 18:42:39 -04:00
{
2021-02-08 15:59:34 -04:00
FChaosScene * Scene = FChaosEngineInterface : : GetCurrentScene ( ValidParticle ) ;
// 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.
auto Sphere = MakeUnique < Chaos : : FImplicitSphere3 > ( FVector ( 0 , 0 , 0 ) , 0 ) ;
KinematicEndPoint - > GetGameThreadAPI ( ) . SetGeometry ( MoveTemp ( Sphere ) ) ;
KinematicEndPoint - > GetGameThreadAPI ( ) . SetUserData ( nullptr ) ;
auto * JointConstraint = new Chaos : : FJointConstraint ( ) ;
JointConstraint - > SetKinematicEndPoint ( KinematicEndPoint , Scene - > GetSolver ( ) ) ;
ConstraintRef . Constraint = JointConstraint ;
2021-06-22 00:27:54 -04: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-02-18 18:13:28 -04:00
JointConstraint - > SetParticleProxies ( { ValidParticle , KinematicEndPoint } ) ;
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 ) ;
Chaos : : FPhysicsSolver * Solver = ValidParticle - > GetSolver < Chaos : : FPhysicsSolver > ( ) ;
checkSlow ( Solver = = KinematicEndPoint - > GetSolver < Chaos : : FPhysicsSolver > ( ) ) ;
Solver - > RegisterObject ( JointConstraint ) ;
2020-11-24 18:42:39 -04:00
}
}
2020-08-11 01:36:57 -04:00
}
return ConstraintRef ;
}
2020-09-24 00:43:27 -04:00
FPhysicsConstraintHandle FChaosEngineInterface : : CreateSuspension ( const FPhysicsActorHandle & InActorRef , const FVector & InLocalFrame )
{
FPhysicsConstraintHandle ConstraintRef ;
if ( bEnableChaosJointConstraints )
{
2021-02-03 14:57:28 -04:00
if ( InActorRef )
2020-09-24 00:43:27 -04:00
{
2021-02-03 14:57:28 -04:00
if ( InActorRef - > GetSolverBase ( ) )
2020-09-24 00:43:27 -04:00
{
LLM_SCOPE ( ELLMTag : : Chaos ) ;
auto * SuspensionConstraint = new Chaos : : FSuspensionConstraint ( ) ;
ConstraintRef . Constraint = SuspensionConstraint ;
2021-09-22 15:51:55 -04:00
SuspensionConstraint - > SetParticleProxy ( InActorRef ) ;
SuspensionConstraint - > SetLocation ( InLocalFrame ) ;
2020-09-24 00:43:27 -04:00
2021-02-03 14:57:28 -04:00
Chaos : : FPhysicsSolver * Solver = InActorRef - > GetSolver < Chaos : : FPhysicsSolver > ( ) ;
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 )
{
LLM_SCOPE ( ELLMTag : : Chaos ) ;
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 ) ;
}
}
}
2020-09-01 14:07:48 -04:00
void FChaosEngineInterface : : SetProjectionEnabled_AssumesLocked ( const FPhysicsConstraintHandle & InConstraintRef , bool bInProjectionEnabled , float InLinearAlpha , float InAngularAlpha )
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 ) ;
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 ) ;
}
}
}
}
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
void FChaosEngineInterface : : SetGeometry ( FPhysicsShapeHandle & InShape , TUniquePtr < Chaos : : FImplicitObject > & & InGeometry )
{
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
TArray < TUniquePtr < FImplicitObject > > NewGeometry ;
NewGeometry . Reserve ( ShapeArray . Num ( ) ) ;
int32 ShapeIdx = 0 ;
for ( const TUniquePtr < Chaos : : FPerShapeData > & Shape : ShapeArray )
{
if ( Shape . Get ( ) = = InShape . Shape )
{
NewGeometry . Emplace ( MoveTemp ( InGeometry ) ) ;
}
else
{
NewGeometry . Emplace ( Shape - > GetGeometry ( ) - > Copy ( ) ) ;
}
ShapeIdx + + ;
}
if ( ensure ( NewGeometry . Num ( ) = = ShapeArray . Num ( ) ) )
{
2021-02-03 14:57:28 -04:00
InShape . ActorRef - > GetGameThreadAPI ( ) . SetGeometry ( MakeUnique < Chaos : : FImplicitObjectUnion > ( MoveTemp ( NewGeometry ) ) ) ;
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 ;
}
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 )
{
return GetImplicitType ( * InShapeRef . Shape - > GetGeometry ( ) ) ;
}
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 )
{
# if !WITH_CHAOS_NEEDS_TO_BE_FIXED
if ( InShape . ActorRef . IsValid ( ) )
{
TArray < RigidBodyId > Ids = { InShape . ActorRef . GetId ( ) } ;
const auto Index = InShape . ActorRef . GetScene ( ) - > GetIndexFromId ( InShape . ActorRef . GetId ( ) ) ;
if ( InShape . Object - > GetType ( ) = = Chaos : : ImplicitObjectType : : Transformed )
{
// @todo(mlentine): We can avoid creating a new object here by adding delayed update support for the object transforms
2021-05-05 15:07:25 -04:00
LocalParticles . SetDynamicGeometry ( Index , MakeUnique < Chaos : : TImplicitObjectTransformed < Chaos : : FReal , 3 > > ( InShape . Object - > GetObject < Chaos : : TImplicitObjectTransformed < Chaos : : FReal , 3 > > ( ) - > Object ( ) , NewLocalTransform ) ) ;
2020-08-11 01:36:57 -04:00
} else
{
2021-05-05 15:07:25 -04:00
LocalParticles . SetDynamicGeometry ( Index , MakeUnique < Chaos : : TImplicitObjectTransformed < Chaos : : FReal , 3 > > ( InShape . Object , NewLocalTransform ) ) ;
2020-08-11 01:36:57 -04:00
}
}
{
if ( InShape . Object - > GetType ( ) = = Chaos : : ImplicitObjectType : : Transformed )
{
2021-05-05 15:07:25 -04:00
InShape . Object - > GetObject < Chaos : : TImplicitObjectTransformed < Chaos : : FReal , 3 > > ( ) - > SetTransform ( NewLocalTransform ) ;
2020-08-11 01:36:57 -04:00
} else
{
2021-05-05 15:07:25 -04:00
const_cast < FPhysicsShapeHandle & > ( InShape ) . Object = new Chaos : : TImplicitObjectTransformed < Chaos : : FReal , 3 > ( InShape . Object , NewLocalTransform ) ;
2020-08-11 01:36:57 -04:00
}
}
# endif
}
template < typename AllocatorType >
int32 GetAllShapesInternalImp_AssumedLocked ( const FPhysicsActorHandle & InActorHandle , TArray < FPhysicsShapeReference_Chaos , AllocatorType > & OutShapes )
{
2021-02-03 14:57:28 -04:00
const Chaos : : FShapesArray & ShapesArray = InActorHandle - > GetGameThreadAPI ( ) . ShapesArray ( ) ;
2020-08-11 01:36:57 -04:00
OutShapes . Reset ( ShapesArray . Num ( ) ) ;
//todo: can we avoid this construction?
for ( const TUniquePtr < Chaos : : FPerShapeData > & Shape : ShapesArray )
{
OutShapes . Add ( FPhysicsShapeReference_Chaos ( Shape . Get ( ) , InActorHandle ) ) ;
}
return OutShapes . Num ( ) ;
}
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 )
{
LLM_SCOPE ( ELLMTag : : Chaos ) ;
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 ( ) ;
2021-08-30 15:17:27 -04:00
Particle - > SetResimType ( EResimType : : ResimAsSlave ) ;
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 ) ;
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 ) ;
Rigid - > SetResimType ( EResimType : : ResimAsSlave ) ; //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
}
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 )
{
2021-01-21 16:22:06 -04:00
LLM_SCOPE ( ELLMTag : : Chaos ) ;
2020-08-11 01:36:57 -04:00
if ( ! Handle )
{
UE_LOG ( LogChaos , Warning , TEXT ( " Attempting to release an actor with a null handle " ) ) ;
CHAOS_ENSURE ( false ) ;
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 ( ) ;
Body_External . SetX ( InNewPose . GetLocation ( ) ) ;
Body_External . SetR ( InNewPose . GetRotation ( ) ) ;
Body_External . UpdateShapeBounds ( ) ;
2020-08-11 01:36:57 -04:00
FChaosScene * Scene = GetCurrentScene ( InActorReference ) ;
Scene - > UpdateActorInAccelerationStructure ( InActorReference ) ;
}
void FChaosEngineInterface : : SetKinematicTarget_AssumesLocked ( const FPhysicsActorHandle & InActorReference , const FTransform & InNewTarget )
{
2021-05-27 13:40:37 -04:00
Chaos : : TKinematicTarget < Chaos : : FReal , 3 > NewKinematicTarget ;
// SetKinematicTarget_AssumesLocked could be called multiple times in one time step
NewKinematicTarget . SetTargetMode ( InNewTarget ) ;
InActorReference - > GetGameThreadAPI ( ) . SetKinematicTarget ( NewKinematicTarget ) ;
2020-11-24 18:42:39 -04:00
2021-05-27 13:40:37 -04:00
// IMPORTANT : we do not invalidate X and R as they will be properly computed using the kinematic target information
InActorReference - > GetGameThreadAPI ( ) . SetX ( InNewTarget . GetLocation ( ) , false ) ;
InActorReference - > GetGameThreadAPI ( ) . SetR ( InNewTarget . GetRotation ( ) , false ) ;
InActorReference - > GetGameThreadAPI ( ) . UpdateShapeBounds ( ) ;
2020-11-24 18:42:39 -04:00
2021-05-27 13:40:37 -04:00
FChaosScene * Scene = GetCurrentScene ( InActorReference ) ;
Scene - > UpdateActorInAccelerationStructure ( InActorReference ) ;
2020-08-11 01:36:57 -04:00
}
# elif WITH_ENGINE //temp physx code to make moving out of engine easier
# include "PhysXSupportCore.h"
FPhysicsMaterialHandle FChaosEngineInterface : : CreateMaterial ( const UPhysicalMaterial * InMaterial )
{
check ( GPhysXSDK ) ;
FPhysicsMaterialHandle_PhysX NewRef ;
const float Friction = InMaterial - > Friction ;
const float Restitution = InMaterial - > Restitution ;
NewRef . Material = GPhysXSDK - > createMaterial ( Friction , Friction , Restitution ) ;
return NewRef ;
}
void FChaosEngineInterface : : ReleaseMaterial ( FPhysicsMaterialHandle_PhysX & InHandle )
{
if ( InHandle . IsValid ( ) )
{
InHandle . Material - > userData = nullptr ;
GPhysXPendingKillMaterial . Add ( InHandle . Material ) ;
InHandle . Material = nullptr ;
}
}
void FChaosEngineInterface : : UpdateMaterial ( FPhysicsMaterialHandle_PhysX & InHandle , UPhysicalMaterial * InMaterial )
{
if ( InHandle . IsValid ( ) )
{
PxMaterial * PMaterial = InHandle . Material ;
PMaterial - > setStaticFriction ( InMaterial - > Friction ) ;
PMaterial - > setDynamicFriction ( InMaterial - > Friction ) ;
PMaterial - > setRestitution ( InMaterial - > Restitution ) ;
const uint32 UseFrictionCombineMode = ( InMaterial - > bOverrideFrictionCombineMode ? InMaterial - > FrictionCombineMode . GetValue ( ) : UPhysicsSettingsCore : : Get ( ) - > FrictionCombineMode . GetValue ( ) ) ;
PMaterial - > setFrictionCombineMode ( static_cast < physx : : PxCombineMode : : Enum > ( UseFrictionCombineMode ) ) ;
const uint32 UseRestitutionCombineMode = ( InMaterial - > bOverrideRestitutionCombineMode ? InMaterial - > RestitutionCombineMode . GetValue ( ) : UPhysicsSettingsCore : : Get ( ) - > RestitutionCombineMode . GetValue ( ) ) ;
PMaterial - > setRestitutionCombineMode ( static_cast < physx : : PxCombineMode : : Enum > ( UseRestitutionCombineMode ) ) ;
FPhysicsDelegatesCore : : OnUpdatePhysXMaterial . Broadcast ( InMaterial ) ;
}
}
void FChaosEngineInterface : : SetUserData ( FPhysicsMaterialHandle_PhysX & InHandle , void * InUserData )
{
if ( InHandle . IsValid ( ) )
{
InHandle . Material - > userData = InUserData ;
}
}
# endif