Files
UnrealEngineUWP/Engine/Source/Runtime/AnimGraphRuntime/Public/BoneControllers/AnimNode_AnimDynamics.h
Marc Audy 6183efcc36 Integrate Engine/Config, Engine/Plugins, Engine/Programs, Engine/Shaders and remaining Engine/Source from UE4-Orion to UE4 at CL# 2716634
#lockdown Ben.Marsh
#platformnotify Josh.Adams

[CL 2718314 by Marc Audy in Main branch]
2015-10-06 16:47:09 -04:00

270 lines
9.9 KiB
C++

// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "AnimPhysicsSolver.h"
#include "AnimNode_SkeletalControlBase.h"
#include "AnimNode_AnimDynamics.generated.h"
/** Supported angular constraint types */
UENUM()
enum class AnimPhysAngularConstraintType : uint8
{
Angular,
Cone
};
/** Supported linear axis constraints */
UENUM()
enum class AnimPhysLinearConstraintType : uint8
{
Free,
Limited,
};
/** Helper mapping a rigid body to a bone reference */
struct FAnimPhysBoneRigidBody
{
FAnimPhysBoneRigidBody(TArray<FAnimPhysShape>& Shapes, const FVector& Position, const FBoneReference& LinkedBone)
: PhysBody(Shapes, Position)
, BoundBone(LinkedBone)
{}
FAnimPhysRigidBody PhysBody;
FBoneReference BoundBone;
};
/** Helper describing a body linked to an optional parent (can be nullptr) */
struct FAnimPhysLinkedBody
{
FAnimPhysLinkedBody(TArray<FAnimPhysShape>& Shapes, const FVector& Position, const FBoneReference& LinkedBone)
: RigidBody(Shapes, Position, LinkedBone)
, ParentBody(nullptr)
{}
FAnimPhysBoneRigidBody RigidBody;
FAnimPhysBoneRigidBody* ParentBody;
};
/** Constraint setup struct, holds data required to build a physics constraint */
USTRUCT()
struct FAnimPhysConstraintSetup
{
GENERATED_BODY()
FAnimPhysConstraintSetup()
: LinearXLimitType(AnimPhysLinearConstraintType::Limited)
, LinearYLimitType(AnimPhysLinearConstraintType::Limited)
, LinearZLimitType(AnimPhysLinearConstraintType::Limited)
, AngularConstraintType(AnimPhysAngularConstraintType::Angular)
, TwistAxis(AnimPhysTwistAxis::AxisX)
, ConeAngle(0.0f)
, AngularXAngle_DEPRECATED(0.0f)
, AngularYAngle_DEPRECATED(0.0f)
, AngularZAngle_DEPRECATED(0.0f)
{}
/** Whether to limit the linear X axis */
UPROPERTY(EditAnywhere, Category = Linear)
AnimPhysLinearConstraintType LinearXLimitType;
/** Whether to limit the linear Y axis */
UPROPERTY(EditAnywhere, Category = Linear)
AnimPhysLinearConstraintType LinearYLimitType;
/** Whether to limit the linear Z axis */
UPROPERTY(EditAnywhere, Category = Linear)
AnimPhysLinearConstraintType LinearZLimitType;
/** Minimum linear movement per-axis (Set zero here and in the max limit to lock) */
UPROPERTY(EditAnywhere, Category = Linear, meta = (UIMax = "0", ClampMax = "0"))
FVector LinearAxesMin;
/** Maximum linear movement per-axis (Set zero here and in the min limit to lock) */
UPROPERTY(EditAnywhere, Category = Linear, meta = (UIMin = "0", ClampMin = "0"))
FVector LinearAxesMax;
/** Method to use when constraining angular motion */
UPROPERTY(EditAnywhere, Category = Angular)
AnimPhysAngularConstraintType AngularConstraintType;
/** Axis to consider for twist when constraining angular motion (forward axis) */
UPROPERTY(EditAnywhere, Category = Angular)
AnimPhysTwistAxis TwistAxis;
/** Angle to use when constraining using a cone */
UPROPERTY(EditAnywhere, Category = Angular, meta = (UIMin = "0", UIMax = "90", ClampMin = "0", ClampMax = "90"))
float ConeAngle;
/** X-axis limit for angular motion when using the "Angular" constraint type (Set to 0 to lock, or 180 to remain free) */
UPROPERTY()
float AngularXAngle_DEPRECATED;
/** Y-axis limit for angular motion when using the "Angular" constraint type (Set to 0 to lock, or 180 to remain free) */
UPROPERTY()
float AngularYAngle_DEPRECATED;
/** Z-axis limit for angular motion when using the "Angular" constraint type (Set to 0 to lock, or 180 to remain free) */
UPROPERTY()
float AngularZAngle_DEPRECATED;
UPROPERTY(EditAnywhere, Category = Angular, meta = (UIMin = "-180", UIMax = "180", ClampMin = "-180", ClampMax = "180"))
FVector AngularLimitsMin;
UPROPERTY(EditAnywhere, Category = Angular, meta = (UIMin = "-180", UIMax = "180", ClampMin = "-180", ClampMax = "180"))
FVector AngularLimitsMax;
/** Axis on body1 to match to the angular target direction. */
UPROPERTY(EditAnywhere, Category = Angular)
AnimPhysTwistAxis AngularTargetAxis;
/** Target direction to face for body1 (in body0 local space) */
UPROPERTY(EditAnywhere, Category = Angular)
FVector AngularTarget;
/** The values below are calculated on initialisation and used when building the limits */
/** If all axes are locked we can use 3 linear limits instead of the 6 needed for limited axes */
UPROPERTY()
bool bLinearFullyLocked;
};
USTRUCT()
struct ANIMGRAPHRUNTIME_API FAnimNode_AnimDynamics : public FAnimNode_SkeletalControlBase
{
GENERATED_BODY();
FAnimNode_AnimDynamics();
/** Set to true to use the solver to simulate a connected chain */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Setup)
bool bChain;
/** The bone to attach the physics body to, if bChain is true this is the top of the chain */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Setup)
FBoneReference BoundBone;
/** If bChain is true this is the bottom of the chain, otherwise ignored */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Setup, meta=(EditCondition = bChain))
FBoneReference ChainEnd;
/** Extents of the box to use for simulation */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Setup)
FVector BoxExtents;
/** Vector relative to the body being simulated to attach the constraint to */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Setup)
FVector LocalJointOffset;
/** Scale for gravity, higher values increase forces due to gravity */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Setup)
float GravityScale;
/** If true the body will attempt to spring back to its initial position */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Setup)
bool bLinearSpring;
/** If true the body will attempt to align itself with the specified angular target */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Setup)
bool bAngularSpring;
/** Spring constant to use when calculating linear springs, higher values mean a stronger spring.*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Setup)
float LinearSpringConstant;
/** Spring constant to use when calculating angular springs, higher values mean a stronger spring */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Setup)
float AngularSpringConstant;
/** If true, the override value will be used for linear damping */
UPROPERTY(EditAnywhere, AdvancedDisplay, BlueprintReadWrite, Category = Setup)
bool bOverrideLinearDamping;
/** Overridden linear damping value */
UPROPERTY(EditAnywhere, AdvancedDisplay, BlueprintReadWrite, Category = Setup)
float LinearDampingOverride;
/** If true, the override value will be used for angular damping */
UPROPERTY(EditAnywhere, AdvancedDisplay, BlueprintReadWrite, Category = Setup)
bool bOverrideAngularDamping;
/** Overridden angular damping value */
UPROPERTY(EditAnywhere, AdvancedDisplay, BlueprintReadWrite, Category = Setup)
float AngularDampingOverride;
/** If true we will perform physics update, otherwise skip - allows visualisation of the initial state of the bodies */
UPROPERTY(EditAnywhere, AdvancedDisplay, BlueprintReadWrite, Category = Setup)
bool bDoUpdate;
/** If true we will perform bone transform evaluation, otherwise skip - allows visualisation of the initial anim state compared to the physics sim */
UPROPERTY(EditAnywhere, AdvancedDisplay, BlueprintReadWrite, Category = Setup)
bool bDoEval;
/** Number of update passes on the linear and angular limits before we solve the position of the bodies recommended to be four times the value of NumSolverIterationsPostUpdate */
UPROPERTY(EditAnywhere, AdvancedDisplay, Category = Setup)
int32 NumSolverIterationsPreUpdate;
/** Number of update passes on the linear and angular limits after we solve the position of the bodies, recommended to be around a quarter of NumSolverIterationsPreUpdate */
UPROPERTY(EditAnywhere, AdvancedDisplay, Category = Setup)
int32 NumSolverIterationsPostUpdate;
/** Data describing the constraints we will apply to the body */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Constraint)
FAnimPhysConstraintSetup ConstraintSetup;
// FAnimNode_SkeletalControlBase interface
virtual void Initialize(const FAnimationInitializeContext& Context) override;
virtual void Update(const FAnimationUpdateContext& Context) override;
virtual void EvaluateBoneTransforms(USkeletalMeshComponent* SkelComp, FCSPose<FCompactPose>& MeshBases, TArray<FBoneTransform>& OutBoneTransforms) override;
virtual void GatherDebugData(FNodeDebugData& DebugData) override;
// End of FAnimNode_SkeletalControlBase interface
void RequestInitialise() { bRequiresInit = true; }
void InitPhysics(USkeletalMeshComponent* Component, FCSPose<FCompactPose>& MeshBases);
void TermPhysics();
void UpdateLimits(FCSPose<FCompactPose>& MeshBases);
int32 GetNumBodies() const;
const FAnimPhysRigidBody& GetPhysBody(int32 BodyIndex) const;
protected:
// FAnimNode_SkeletalControlBase protected interface
virtual void InitializeBoneReferences(const FBoneContainer& RequiredBones) override;
virtual bool IsValidToEvaluate(const USkeleton* Skeleton, const FBoneContainer& RequiredBones);
// End of FAnimNode_SkeletalControlBase protected interface
private:
// We can't get clean bone positions unless we are in the evaluate step.
// Requesting an init or reinit sets this flag for us to pick up during evaluate
bool bRequiresInit;
// Maximum time to consider when accumulating time debt to avoid spiraling
static const float MaxTimeDebt;
// Cached timestep from the update phase (needed in evaluate phase)
float NextTimeStep;
// Current amount of time debt
float TimeDebt;
// Active body list
TArray<FAnimPhysLinkedBody> Bodies;
// List of current linear limits built for the current frame
TArray<FAnimPhysLinearLimit> LinearLimits;
// List of current angular limits built for the current frame
TArray<FAnimPhysAngularLimit> AngularLimits;
// List of spring force generators created for this frame
TArray<FAnimPhysSpring> Springs;
// Local space offsets for each body
TArray<FVector> JointOffsets;
// List of bone references for all bodies in this node
TArray<FBoneReference> BoundBoneReferences;
};