731 lines
30 KiB
C++
731 lines
30 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "PhysicsControlData.h"
|
|
|
|
#include "Rigs/RigPhysics.h"
|
|
#include "Rigs/RigHierarchyDefines.h"
|
|
|
|
#include "PhysicsEngine/ConstraintTypes.h"
|
|
#include "PhysicsEngine/ConstraintDrives.h"
|
|
|
|
#include "RigPhysicsData.generated.h"
|
|
|
|
#define UE_API CONTROLRIGPHYSICS_API
|
|
|
|
struct FRigVMExecuteContext;
|
|
struct FRigBaseElement;
|
|
struct FRigControlElement;
|
|
class URigHierarchy;
|
|
class FRigElementKeyRedirector;
|
|
|
|
const float RigPhysicsDefaultShapeSize = 10.0f;
|
|
|
|
USTRUCT(BlueprintType)
|
|
struct FRigPhysicsVisualizationSettings
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
// Enable visualization (includes enabling low-level chaos debug draw). Note that this can be
|
|
// overridden using CVar ControlRig.Physics.VisualizationOveride
|
|
UPROPERTY(EditAnywhere, Category = Visualization)
|
|
bool bEnableVisualization = true;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Visualization, meta = (ClampMin = "0.0"))
|
|
float LineThickness = 1.0f;
|
|
|
|
// Multiplier on the size things like limit shapes
|
|
UPROPERTY(EditAnywhere, Category = Visualization, meta = (ClampMin = "0.0"))
|
|
int32 ShapeSize = 1;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Visualization, meta = (ClampMin = "0.0"))
|
|
int32 ShapeDetail = 16;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Visualization)
|
|
bool bShowBodies = true;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Visualization)
|
|
bool bShowJoints = true;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Visualization)
|
|
bool bShowControls = false;
|
|
|
|
// If visualization is enabled, show active contacts. Note that this can be overridden using
|
|
// CVar ControlRig.Physics.DrawActiveContactsOveride
|
|
UPROPERTY(EditAnywhere, Category = Visualization)
|
|
bool bShowActiveContacts = true;
|
|
|
|
// If visualization is enabled, show inactive contacts. Note that this can be overridden using
|
|
// CVar ControlRig.Physics.DrawInactiveContactsOveride
|
|
UPROPERTY(EditAnywhere, Category = Visualization)
|
|
bool bShowInactiveContacts = false;
|
|
};
|
|
|
|
/**
|
|
* Specifies what space a kinematic target is defined in
|
|
* Danny TODO this is much better than the similar mechanism in PCC and RBWC (which has a
|
|
* bUseSkeletalAnimation) - switch them to use this.
|
|
*/
|
|
UENUM()
|
|
enum class ERigPhysicsKinematicTargetSpace : uint8
|
|
{
|
|
// Target is in world space
|
|
World,
|
|
// Target is in the space of the component
|
|
Component,
|
|
// Target is specified relative to the bone that controls the (kinematic) body, with the offset
|
|
// applied in the space of that body.
|
|
OffsetInBoneSpace,
|
|
// Target is specified relative to the bone that controls the (kinematic) body, with the offset
|
|
// applied in world space.
|
|
OffsetInWorldSpace,
|
|
// Target is specified relative to the bone that controls the (kinematic) body, with the offset
|
|
// applied in component space.
|
|
OffsetInComponentSpace,
|
|
// Ignore the specified target, and just track the bone
|
|
IgnoreTarget
|
|
};
|
|
|
|
/** Specifies what space the simulation should run in */
|
|
UENUM()
|
|
enum class ERigPhysicsSimulationSpace : uint8
|
|
{
|
|
/** Simulate in world space. Moving the skeletal mesh will generate velocity changes */
|
|
World,
|
|
/**
|
|
* Simulate in component space. Moving the entire skeletal mesh will have no affect on velocities
|
|
* unless this is explicitly enabled in the simulation space settings */
|
|
Component,
|
|
/**
|
|
* Simulate in the space of the specified bone. Moving the entire skeletal mesh and/or the Bone
|
|
* will have no affect on velocities unless this is explicitly enabled in the simulation space settings.
|
|
*/
|
|
SpaceBone,
|
|
};
|
|
|
|
/**
|
|
* Properties common to all collision shape types
|
|
*/
|
|
USTRUCT(BlueprintType)
|
|
struct FRigPhysicsCollisionShape
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
/** Offset used when generating contact points. This allows you to smooth out
|
|
the Minkowski sum by radius R. Useful for making objects slide smoothly
|
|
on top of irregularities */
|
|
UPROPERTY(Category = Shape, EditAnywhere, meta = (ClampMin = "0.0"))
|
|
float RestOffset = 0.0f;
|
|
|
|
UPROPERTY(Category = Shape, EditAnywhere)
|
|
FName Name;
|
|
|
|
/** True if this shape should contribute to the overall mass of the body it
|
|
belongs to. This lets you create extra collision volumes which do not affect
|
|
the mass properties of an object. */
|
|
UPROPERTY(Category = Shape, EditAnywhere)
|
|
bool bContributeToMass = true;
|
|
};
|
|
|
|
/**
|
|
* Box collision
|
|
*/
|
|
USTRUCT(BlueprintType)
|
|
struct FRigPhysicsCollisionBox : public FRigPhysicsCollisionShape
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
FRigPhysicsCollisionBox(const FTransform& InTM, const FVector& InExtents) :
|
|
TM(InTM), Extents(InExtents) {}
|
|
FRigPhysicsCollisionBox() {}
|
|
|
|
friend FArchive& operator <<(FArchive& Ar, FRigPhysicsCollisionBox& Data)
|
|
{
|
|
Ar << Data.TM;
|
|
Ar << Data.Extents;
|
|
return Ar;
|
|
}
|
|
|
|
UPROPERTY(EditAnywhere, Category = Shapes)
|
|
FTransform TM;
|
|
|
|
// These are the full extents of the box in each axis
|
|
UPROPERTY(EditAnywhere, Category = Shapes)
|
|
FVector Extents = FVector::OneVector * RigPhysicsDefaultShapeSize;
|
|
};
|
|
|
|
/**
|
|
* Sphere collision
|
|
*/
|
|
USTRUCT(BlueprintType)
|
|
struct FRigPhysicsCollisionSphere : public FRigPhysicsCollisionShape
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
FRigPhysicsCollisionSphere(const FTransform& InTM, const float InRadius) :
|
|
TM(InTM), Radius(InRadius) {
|
|
}
|
|
FRigPhysicsCollisionSphere() {}
|
|
|
|
friend FArchive& operator <<(FArchive& Ar, FRigPhysicsCollisionSphere& Data)
|
|
{
|
|
Ar << Data.TM;
|
|
Ar << Data.Radius;
|
|
return Ar;
|
|
}
|
|
|
|
UPROPERTY(EditAnywhere, Category = Shapes)
|
|
FTransform TM;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Shapes, meta = (ClampMin = "0.0"))
|
|
float Radius = RigPhysicsDefaultShapeSize;
|
|
};
|
|
|
|
/**
|
|
* Capsule collision
|
|
*/
|
|
USTRUCT(BlueprintType)
|
|
struct FRigPhysicsCollisionCapsule : public FRigPhysicsCollisionShape
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
FRigPhysicsCollisionCapsule(const FTransform& InTM, const float InRadius, const float InLength)
|
|
: TM(InTM), Radius(InRadius), Length(InLength) {}
|
|
FRigPhysicsCollisionCapsule() {}
|
|
|
|
friend FArchive& operator <<(FArchive& Ar, FRigPhysicsCollisionCapsule& Data)
|
|
{
|
|
Ar << Data.TM;
|
|
Ar << Data.Radius;
|
|
Ar << Data.Length;
|
|
return Ar;
|
|
}
|
|
|
|
UPROPERTY(EditAnywhere, Category = Shapes)
|
|
FTransform TM;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Shapes, meta = (ClampMin = "0.0"))
|
|
float Radius = RigPhysicsDefaultShapeSize;
|
|
|
|
// This is the length of the core part of the capsule. The total length will be Length + 2 * Radius
|
|
UPROPERTY(EditAnywhere, Category = Shapes, meta = (ClampMin = "0.0"))
|
|
float Length = RigPhysicsDefaultShapeSize;
|
|
};
|
|
|
|
// How to combine friction/restitution values.
|
|
UENUM(BlueprintType)
|
|
enum class ERigPhysicsCombineMode : uint8
|
|
{
|
|
Avg,
|
|
Min,
|
|
Multiply,
|
|
Max
|
|
// The values here must match those in Chaos::FChaosPhysicsMaterial::ECombineMode
|
|
};
|
|
|
|
// Material properties of a collision shapes.
|
|
USTRUCT(BlueprintType)
|
|
struct FRigPhysicsMaterial
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
friend FArchive& operator <<(FArchive& Ar, FRigPhysicsMaterial& Data);
|
|
|
|
// Friction is simplified here - just one value used for static and dynamic friction.
|
|
UPROPERTY(EditAnywhere, Category = Material, meta = (ClampMin = "0.0"))
|
|
float Friction = 0.5f;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Material, meta = (ClampMin = "0.0", ClampMax = "1.0"))
|
|
float Restitution = 0.0f;
|
|
|
|
// How to combine friction values. If the materials have different combine modes, then Max is
|
|
// used over Multiply, Multiply over Min and Min over Avg.
|
|
UPROPERTY(EditAnywhere, Category = Material)
|
|
ERigPhysicsCombineMode FrictionCombineMode = ERigPhysicsCombineMode::Multiply;
|
|
|
|
// How to combine restitution values. If the materials have different combine modes, then Max is
|
|
// used over Multiply, Multiply over Min and Min over Avg.
|
|
UPROPERTY(EditAnywhere, Category = Material)
|
|
ERigPhysicsCombineMode RestitutionCombineMode = ERigPhysicsCombineMode::Multiply;
|
|
};
|
|
|
|
// Collection of shapes that define the collision and (optionally) mass distribution of the body
|
|
USTRUCT(BlueprintType)
|
|
struct FRigPhysicsCollision
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
friend FArchive& operator <<(FArchive& Ar, FRigPhysicsCollision& Data);
|
|
|
|
UPROPERTY(EditAnywhere, Category = Shapes)
|
|
TArray<FRigPhysicsCollisionBox> Boxes;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Shapes)
|
|
TArray<FRigPhysicsCollisionSphere> Spheres;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Shapes)
|
|
TArray<FRigPhysicsCollisionCapsule> Capsules;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Shapes)
|
|
FRigPhysicsMaterial Material;
|
|
|
|
bool IsEmpty() const { return Boxes.IsEmpty() && Spheres.IsEmpty() && Capsules.IsEmpty(); }
|
|
int32 NumShapes() const { return Boxes.Num() + Capsules.Num() + Spheres.Num(); }
|
|
};
|
|
|
|
/**
|
|
* These settings are used when the simulation is not done in world space. They allow the
|
|
* movement of the simulation space (e.g. the component) to be added to the local simulation in a controlled way.
|
|
*/
|
|
USTRUCT(BlueprintType)
|
|
struct FRigPhysicsSimulationSpaceSettings
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
friend FArchive& operator <<(FArchive& Ar, FRigPhysicsSimulationSpaceSettings& Data);
|
|
|
|
// Overall multiplier on the effects of simulation space movement on the simulation
|
|
UPROPERTY(EditAnywhere, Category = Settings, meta = (ClampMin = "0.0", ClampMax = "1.0"))
|
|
float SpaceMovementAmount = 1.0f;
|
|
|
|
// Multiplier on the components of vertical velocity of the simulation space that is passed to the simulation.
|
|
// Usually from 0.0 to 1.0 to reduce the effects of jumping and crouching on the simulation, but
|
|
// it can be higher than 1.0 if you need to exaggerate this motion for some reason.
|
|
UPROPERTY(EditAnywhere, Category = Settings)
|
|
float VelocityScaleZ = 1.0f;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Settings, meta = (InlineEditConditionToggle))
|
|
bool bClampLinearVelocity = false;
|
|
|
|
// A clamp on the effective world-space velocity that is passed to the simulation. The default
|
|
// value effectively means "unlimited". It is not usually required to change this but you would
|
|
// reduce this to limit the effects of drag on the bodies in the simulation (if you have bodies
|
|
// that have LinearDrag set to non-zero in the physics asset). Expected values in this case
|
|
// would be somewhat less than the usual velocities of your object which is commonly a few
|
|
// hundred for a character.
|
|
UPROPERTY(EditAnywhere, Category = Settings, meta = (ClampMin = "0.0", EditCondition = "bClampLinearVelocity"))
|
|
float MaxLinearVelocity = 10000;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Settings, meta = (InlineEditConditionToggle))
|
|
bool bClampAngularVelocity = false;
|
|
|
|
// A clamp on the effective world-space angular velocity that is passed to the simulation. Units
|
|
// are radian/s, so a value of about 6.0 is one rotation per second. The default value
|
|
// effectively means "unlimited". You would reduce this (and MaxAngularAcceleration) to limit
|
|
// how much bodies "fly out" when the actor spins on the spot. This is especially useful if you
|
|
// have characters than can rotate very quickly and you would probably want values around or
|
|
// less than 10 in this case.
|
|
UPROPERTY(EditAnywhere, Category = Settings, meta = (ClampMin = "0.0", EditCondition = "bClampAngularVelocity"))
|
|
float MaxAngularVelocity = 10000;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Settings, meta = (InlineEditConditionToggle))
|
|
bool bClampLinearAcceleration = false;
|
|
|
|
// A clamp on the effective world-space acceleration that is passed to the simulation. The
|
|
// default value effectively means "unlimited". This property is used to stop the bodies of the
|
|
// simulation flying out when suddenly changing linear speed. It is useful when you have
|
|
// characters than can changes from stationary to running very quickly such as in an FPS. A
|
|
// common value for a character might be in the few hundreds.
|
|
UPROPERTY(EditAnywhere, Category = Settings, meta = (ClampMin = "0.0", EditCondition = "bClampLinearAcceleration"))
|
|
float MaxLinearAcceleration = 10000;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Settings, meta = (InlineEditConditionToggle))
|
|
bool bClampAngularAcceleration = false;
|
|
|
|
// A clamp on the effective world-space angular acceleration that is passed to the simulation.
|
|
// Units are radian/s/s. The default value effectively means "unlimited". This has a similar
|
|
// effect to MaxAngularVelocity, except that it is related to the flying out of bodies when the
|
|
// rotation speed suddenly changes. A typical value for a character might be around 100.
|
|
UPROPERTY(EditAnywhere, Category = Settings, meta = (ClampMin = "0.0", EditCondition = "bClampAngularAcceleration"))
|
|
float MaxAngularAcceleration = 10000;
|
|
|
|
// If the linear acceleration is above this threshold, the movement is treated as a teleport.
|
|
// The calculated accelerations and velocities will be set to zero, without resetting the
|
|
// simulation state.
|
|
// A value of zero will disable this detection
|
|
UPROPERTY(EditAnywhere, Category = Settings, meta = (ClampMin = "0.0"))
|
|
float LinearAccelerationThresholdForTeleport = 10000;
|
|
|
|
// If the angular acceleration (deg/s/s) is above this threshold, the movement is treated as a teleport.
|
|
// The calculated accelerations and velocities will be set to zero, without resetting the
|
|
// simulation state.
|
|
// A value of zero will disable this detection
|
|
UPROPERTY(EditAnywhere, Category = Settings, meta = (ClampMin = "0.0"))
|
|
float AngularAccelerationThresholdForTeleport = 10000;
|
|
|
|
// If the linear position change is above this threshold, the movement is treated as a teleport.
|
|
// The calculated accelerations and velocities will be set to zero, without resetting the
|
|
// simulation state.
|
|
// A value of zero will disable this detection
|
|
UPROPERTY(EditAnywhere, Category = Settings, meta = (ClampMin = "0.0"))
|
|
float PositionChangeThresholdForTeleport = 100;
|
|
|
|
// If the angular change (degrees) is above this threshold, the movement is treated as a teleport.
|
|
// The calculated accelerations and velocities will be set to zero, without resetting the
|
|
// simulation state.
|
|
// A value of zero will disable this detection
|
|
UPROPERTY(EditAnywhere, Category = Settings, meta = (ClampMin = "0.0"))
|
|
float OrientationChangeThresholdForTeleport = 30;
|
|
|
|
// How much of the simulation frame's linear velocity to pass onto the bodies (linear ether
|
|
// drag). This relies on there being drag authored on the bodies. If set to zero, the only drag
|
|
// will be from the body's local movement (in the simulation space).
|
|
UPROPERTY(EditAnywhere, Category = Settings, meta = (ClampMin = "0.0", ClampMax = "1.0"))
|
|
float LinearDragMultiplier = 1.0;
|
|
|
|
// How much of the simulation frame's angular velocity to pass onto the bodies (angular ether
|
|
// drag). This relies on there being drag authored on the bodies. If set to zero, the only drag
|
|
// will be from the body's local movement (in the simulation space).
|
|
UPROPERTY(EditAnywhere, Category = Settings, meta = (ClampMin = "0.0", ClampMax = "1.0"))
|
|
float AngularDragMultiplier = 1.0f;
|
|
|
|
// Additional linear drag from movement of the simulation space, applied to every body in
|
|
// addition to linear drag specified on them in the physics asset. When combined with
|
|
// ExternalLinearVelocity, this can be used to add a temporary wind-blown effect without having
|
|
// to tune linear drag on all the bodies in the physics asset. The result is that each body has
|
|
// a force equal to -ExternalLinearDrag * ExternalLinearVelocity applied to it, in addition to
|
|
// all other forces. The vector is in simulation local space.
|
|
UPROPERTY(EditAnywhere, Category = Settings)
|
|
FVector ExternalLinearDrag = FVector::ZeroVector;
|
|
|
|
// Additional velocity that is added to the component velocity so the simulation acts as if the
|
|
// actor is moving at speed, even when stationary. The vector is in world space. This could be
|
|
// used for wind effects etc. Typical values are similar to the velocity of the object or
|
|
// effect, and usually around or less than 1000 for characters/wind.
|
|
UPROPERTY(EditAnywhere, Category = Settings)
|
|
FVector ExternalLinearVelocity = FVector::ZeroVector;
|
|
|
|
// Additional angular velocity that is added to the component angular velocity. This can be used
|
|
// to make the simulation act as if the actor is rotating even when it is not. E.g., to apply
|
|
// physics to a character on a podium as the camera rotates around it, to emulate the podium
|
|
// itself rotating. Vector is in world space. Units are deg/s.
|
|
UPROPERTY(EditAnywhere, Category = Settings)
|
|
FVector ExternalAngularVelocity = FVector::ZeroVector;
|
|
|
|
// This will treat the external velocity like a wind field and add turbulence to it. Units are
|
|
// the same as velocity, so this is the approximate magnitude of the turbulence.
|
|
UPROPERTY(EditAnywhere, Category = Settings)
|
|
FVector ExternalTurbulenceVelocity = FVector::ZeroVector;
|
|
};
|
|
|
|
/**
|
|
* Configuration/settings for the physics solver
|
|
*/
|
|
USTRUCT(BlueprintType)
|
|
struct FRigPhysicsSolverSettings
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
friend FArchive& operator <<(FArchive& Ar, FRigPhysicsSolverSettings& Data);
|
|
|
|
// If true, then any physics component below (the element owning this one) will be automatically
|
|
// added to this solver, if its UseAutomaticSolver flag is set.
|
|
UPROPERTY(EditAnywhere, Category = SolverSettings)
|
|
bool bAutomaticallyAddPhysicsComponents = true;
|
|
|
|
UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = SolverSettings)
|
|
ERigPhysicsSimulationSpace SimulationSpace = ERigPhysicsSimulationSpace::Component;
|
|
|
|
// The space in which collision shapes are defined
|
|
UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = SolverSettings)
|
|
ERigPhysicsSimulationSpace CollisionSpace = ERigPhysicsSimulationSpace::Component;
|
|
|
|
/** The bone to use for the collision or simulation space (only relevant if one is set to BoneSpace) */
|
|
UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = SolverSettings)
|
|
FRigElementKey SpaceBone;
|
|
|
|
// The collision shapes defined in the collision space - e.g. for representing a ground etc
|
|
UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = SolverSettings, meta = (ShowOnlyInnerProperties))
|
|
FRigPhysicsCollision Collision;
|
|
|
|
UPROPERTY(EditAnywhere, Category = SolverSettings)
|
|
FVector Gravity = FVector(0, 0, -981.0);
|
|
|
|
/**
|
|
* The number of position iterations to run. The position solve is responsible for de-penetration.
|
|
* Increasing this will improve simulation stability, but increase the cost.
|
|
*/
|
|
UPROPERTY(EditAnywhere, Category = SolverSettings, meta = (ClampMin = 0))
|
|
int32 PositionIterations = 6;
|
|
|
|
/**
|
|
* The number of velocity iterations to run. The velocity solve is responsible for restitution (bounce) and friction.
|
|
* This should usually be 1, but could be 0 if you don't care about friction and restitution.
|
|
*/
|
|
UPROPERTY(EditAnywhere, Category = SolverSettings, meta = (ClampMin = 0))
|
|
int32 VelocityIterations = 1;
|
|
|
|
/**
|
|
* The number of projection iterations to run. The projection phase is a final pass over the constraints, applying
|
|
* a semi-physical correction to any joint errors remaining after the position and velocity solves. It can be
|
|
* very helpful to stabilize joint chains, but can cause issues with collision response. The projection magnitude
|
|
* can be controlled per-constraint in the constraint settings (assuming ProjectionIteration is not zero).
|
|
* This should be left as 1 in almost all cases.
|
|
*/
|
|
UPROPERTY(EditAnywhere, Category = SolverSettings, meta = (ClampMin = 0))
|
|
int32 ProjectionIterations = 1;
|
|
|
|
// This sets how or if the step size should be smoothed. A value of one will disable smoothing,
|
|
// so that the physics simulation will match the Control Rig delta time.
|
|
UPROPERTY(EditAnywhere, Category = SolverSettings, meta = (ClampMin = 1))
|
|
int32 MaxNumRollingAverageStepTimes = 1;
|
|
|
|
// This is the margin around shapes used to detect collisions. Increasing this will increase the
|
|
// number of inactive contacts, which will reduce the likelihood of penetration, but will also
|
|
// increase solver cost.
|
|
UPROPERTY(EditAnywhere, Category = SolverSettings, meta = (ClampMin = 0))
|
|
float CollisionBoundsExpansion = 2.0f;
|
|
|
|
// Expands the shape bounds to detect potentially active contacts when moving. Increasing this
|
|
// (typically up to 1) will increase the number of inactive contacts, which will reduce the
|
|
// likelihood of penetration, but will also increase solver cost.
|
|
UPROPERTY(EditAnywhere, Category = SolverSettings, meta = (ClampMin = 0))
|
|
float BoundsVelocityMultiplier = 1.0f;
|
|
|
|
// The maximum margin added due to movement. Reducing this can prevent excessive numbers of inactive
|
|
// contacts being generated.
|
|
UPROPERTY(EditAnywhere, Category = SolverSettings, meta = (ClampMin = 0))
|
|
float MaxVelocityBoundsExpansion = 25.0f;
|
|
|
|
// When bodies are penetrating, this is the maximum velocity delta that can be applied in one frame.
|
|
UPROPERTY(EditAnywhere, Category = SolverSettings, meta = (ClampMin = 0))
|
|
float MaxDepenetrationVelocity = 0.0f;
|
|
|
|
/**
|
|
* The recommended fixed timestep for the RBAN solver. Set to 0 to run with variable timestep.
|
|
* NOTE: If this value is non-zero and less than the current frame time, the simulation will step multiple times
|
|
* which increases the cost.
|
|
*/
|
|
UPROPERTY(EditAnywhere, Category = SolverSettings, meta = (ClampMin = 0))
|
|
float FixedTimeStep = 0.02f;
|
|
|
|
// The maximum number of solver steps that can be made
|
|
UPROPERTY(EditAnywhere, Category = SolverSettings, meta = (ClampMin = 1))
|
|
int32 MaxTimeSteps = 10;
|
|
|
|
/**
|
|
* If a variable timestep is in use, this is the maximum delta time that can be used. If this is smaller than the
|
|
* requested total delta time then multiple steps will be used.
|
|
*/
|
|
UPROPERTY(EditAnywhere, Category = SolverSettings, meta = (ClampMin = 0))
|
|
float MaxDeltaTime = 0.02f;
|
|
|
|
/**
|
|
* Whether to use the linear or non-linear solver for RBAN Joints. The linear solver is significantly cheaper than
|
|
* the non-linear solver when you are running multiple iterations, but is more likely to suffer from jitter.
|
|
* In general you should try to use the linear solver and increase the PositionIterations to improve stability if
|
|
* possible, only using the non-linear solver as a last resort.
|
|
*/
|
|
UPROPERTY(EditAnywhere, Category = SolverSettings)
|
|
bool bUseLinearJointSolver = true;
|
|
|
|
/**
|
|
* When solving joints, whether to solve the positions last (as opposed to the orientations)
|
|
*/
|
|
UPROPERTY(EditAnywhere, Category = SolverSettings)
|
|
bool bSolveJointPositionsLast = true;
|
|
|
|
/**
|
|
* It enables the use of multi-point contact manifolds, which are created only once at the start of each tick.
|
|
* When disabled, a single-point contact is generated in each solver iteration which is more expensive.
|
|
*/
|
|
UPROPERTY(EditAnywhere, Category = CollisionSettings)
|
|
bool bUseManifolds = true;
|
|
|
|
// If any object in the simulation exceeds this distance from the simulation origin, we will
|
|
// reset the pose and velocity of the entire simulation. This is to detect problems/explosions.
|
|
// Disabled when the value is zero.
|
|
UPROPERTY(EditAnywhere, Category = Settings, meta = (ClampMin = "0.0"))
|
|
float PositionThresholdForReset = 0;
|
|
|
|
// If any kinematic object in the simulation exceeds this speed, we will reset the velocities
|
|
// of all objects in the simulation.This is to detect problems - for example if the
|
|
// target animation has teleports etc. Disabled when the value is zero.
|
|
UPROPERTY(EditAnywhere, Category = Settings, meta = (ClampMin = "0.0"))
|
|
float KinematicSpeedThresholdForReset = 5000.0f;
|
|
|
|
// If any kinematic object in the simulation exceeds this acceleration, we will reset the
|
|
// velocities of all objects in the simulation.This is to detect problems - for example if the
|
|
// target animation has teleports etc. Disabled when the value is zero.
|
|
UPROPERTY(EditAnywhere, Category = Settings, meta = (ClampMin = "0.0"))
|
|
float KinematicAccelerationThresholdForReset = 40000.0f;
|
|
};
|
|
|
|
/**
|
|
* Properties of a body affecting its dynamics (movement without regard to collision).
|
|
*/
|
|
USTRUCT(BlueprintType)
|
|
struct FRigPhysicsDynamics
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
friend FArchive& operator <<(FArchive& Ar, FRigPhysicsDynamics& Data);
|
|
|
|
// Density - units g per cm^3 so this defaults to "water"
|
|
UPROPERTY(EditAnywhere, Category = Dynamics, meta = (EditCondition = "MassOverride <= 0"))
|
|
float Density = 1.0f;
|
|
|
|
// The total mass of this body - will override density if positive
|
|
UPROPERTY(EditAnywhere, Category = Dynamics)
|
|
float MassOverride = 1.0f;
|
|
|
|
// Use this to specify the location of the centre of mass
|
|
UPROPERTY(EditAnywhere, Category = Dynamics)
|
|
bool bOverrideCentreOfMass = false;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Dynamics, meta = (EditCondition = "bOverrideCentreOfMass"))
|
|
FVector CentreOfMassOverride = FVector::ZeroVector;
|
|
|
|
// Use this to specify the moments of inertia
|
|
UPROPERTY(EditAnywhere, Category = Dynamics)
|
|
bool bOverrideMomentsOfInertia = false;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Dynamics, meta = (EditCondition = "bOverrideMomentsOfInertia"))
|
|
FVector MomentsOfInertiaOverride = FVector(1.0f, 1.0f, 1.0f);
|
|
|
|
UPROPERTY(EditAnywhere, Category = Dynamics, meta = (ClampMin = "0.0"))
|
|
float LinearDamping = 0.0f;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Dynamics, meta = (ClampMin = "0.0"))
|
|
float AngularDamping = 0.0f;
|
|
};
|
|
|
|
// This represents the motor drive associated with a physics joint, that can drive the bodies
|
|
// towards a target pose.
|
|
USTRUCT(BlueprintType)
|
|
struct FRigPhysicsDriveData
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
friend FArchive& operator<<(FArchive& Ar, FRigPhysicsDriveData& Data);
|
|
|
|
UPROPERTY(EditAnywhere, Category = LinearDrive)
|
|
FLinearDriveConstraint LinearDriveConstraint;
|
|
|
|
UPROPERTY(EditAnywhere, Category = AngularDrive)
|
|
FAngularDriveConstraint AngularDriveConstraint;
|
|
|
|
// If true, then targets in the linear and angular drives will be applied on top of the pose
|
|
// from animation.
|
|
UPROPERTY(EditAnywhere, Category = Drive)
|
|
bool bUseSkeletalAnimation = true;
|
|
|
|
// The amount of skeletal animation velocity to use in the targets
|
|
UPROPERTY(EditAnywhere, Category = Drive)
|
|
float SkeletalAnimationVelocityMultiplier = 1.0f;
|
|
};
|
|
|
|
/**
|
|
* This represents an "articulation" - a general purpose "character joint" consisting of
|
|
* * A linear limit (a linear constraint), which is normally used to pin two bones together
|
|
* * An angular limit (an angular constraint), which is normally used to allow a limited range of rotational movement.
|
|
*
|
|
* The joint is defined by a parent frame, which is attached to the parent body, and a child frame which is
|
|
* attached to the child body. If the limits are all zero, then these two bodies will be held in a fixed pose.
|
|
* Normally the angular limit will be relaxed to allow rotational movement around the joint position.
|
|
*
|
|
* Most bodies in a character will have one Physics Joint which connects them to their parent in the hierarchy.
|
|
* However
|
|
* * The root of the hierarchy will not have an enabled Physics Joint
|
|
* * There may be times when a body has additional Physics Joints.
|
|
*/
|
|
USTRUCT(BlueprintType)
|
|
struct FRigPhysicsJointData
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
friend FArchive& operator<<(FArchive& Ar, FRigPhysicsJointData& Data);
|
|
|
|
// The auto-calculated offset of the parent frame from the parent body places it at the
|
|
// location of the child body relative to the parent body in the initial pose.
|
|
UPROPERTY(EditAnywhere, Category = Joint)
|
|
bool bAutoCalculateParentOffset = true;
|
|
|
|
// The parent frame offset applied after any auto-calculation
|
|
UPROPERTY(EditAnywhere, Category = Joint)
|
|
FTransform ExtraParentOffset;
|
|
|
|
// The auto-calculated offset of the child frame is for it to be co-located with the child body.
|
|
UPROPERTY(EditAnywhere, Category = Joint)
|
|
bool bAutoCalculateChildOffset = true;
|
|
|
|
// The child frame offset applied after any auto-calculation
|
|
UPROPERTY(EditAnywhere, Category = Joint)
|
|
FTransform ExtraChildOffset;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Joint)
|
|
FLinearConstraint LinearConstraint;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Joint)
|
|
FConeConstraint ConeConstraint;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Joint)
|
|
FTwistConstraint TwistConstraint;
|
|
|
|
// Disable collisions between the parent and child bodies
|
|
UPROPERTY(EditAnywhere, Category = Joint)
|
|
bool bDisableCollision = true;
|
|
|
|
// The amount of linear projection to reduce joint separation when the linear constraint is
|
|
// locked or has a hard limit. A value of one will apply full projection, but can introduce artefacts.
|
|
UPROPERTY(EditAnywhere, Category = Joint, meta = (ClampMin = 0, ClampMax = 1))
|
|
float LinearProjectionAmount = 0.5f;
|
|
|
|
// The amount of angular projection to reduce joint separation when the angular constraint is
|
|
// locked or has a hard limit. Note that projecting back to angular limits will often break the
|
|
// position projection, so it is normally better to disable this.
|
|
UPROPERTY(EditAnywhere, Category = Joint, meta = (ClampMin = 0, ClampMax = 1))
|
|
float AngularProjectionAmount = 0.0f;
|
|
|
|
// As this is reduced to 0, the parent body becomes less affected by the motion of the child
|
|
// body, making the joint behave in one direction.
|
|
UPROPERTY(EditAnywhere, Category = Joint, meta = (ClampMin = 0))
|
|
float ParentInverseMassScale = 1.0f;
|
|
};
|
|
|
|
/**
|
|
* Basic settings of the body in relation to the solver that are not covered elsewhere
|
|
*/
|
|
USTRUCT(BlueprintType)
|
|
struct FRigPhysicsBodySolverSettings
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
FRigPhysicsBodySolverSettings(
|
|
FRigComponentKey InPhysicsSolverComponentKey = FRigComponentKey(), FRigElementKey InTargetBone = FRigElementKey())
|
|
: PhysicsSolverComponentKey(InPhysicsSolverComponentKey), TargetBone(InTargetBone) {}
|
|
|
|
friend FArchive& operator <<(FArchive& Ar, FRigPhysicsBodySolverSettings& Data);
|
|
|
|
// Note that setting the solver component, if known, has the benefit of avoiding the need to
|
|
// search for an automatic solver.
|
|
UPROPERTY(EditAnywhere, Category = Solver)
|
|
FRigComponentKey PhysicsSolverComponentKey;
|
|
|
|
// If true (and the physics solver is not explicitly set), then this component will be added to
|
|
// any physics solver that exists above it in the hierarchy, if that solver allows automatically
|
|
// adding physics components.
|
|
UPROPERTY(EditAnywhere, Category = Solver)
|
|
bool bUseAutomaticSolver = true;
|
|
|
|
// The bone that is used to initialize physics, as well as what to track when the body is set to be kinematic.
|
|
// Note that if this is unset, the it will default to the parent of our owner.
|
|
UPROPERTY(EditAnywhere, Category = Solver)
|
|
FRigElementKey SourceBone;
|
|
|
|
// The bone that is written to following simulation. Note that if this is unset, the it will
|
|
// default to the parent of our owner.
|
|
UPROPERTY(EditAnywhere, Category = Solver)
|
|
FRigElementKey TargetBone;
|
|
|
|
// Whether to include this bone in checks for whether we should reset physics on the whole rig,
|
|
// using thresholds in the solver. Set to false for bodies you know may jump around safely when kinematic.
|
|
UPROPERTY(EditAnywhere, Category = Solver)
|
|
bool bIncludeInChecksForReset = true;
|
|
|
|
UE_API void OnRigHierarchyKeyChanged(const FRigHierarchyKey& InOldKey, const FRigHierarchyKey& InNewKey);
|
|
};
|
|
|
|
#undef UE_API
|