1
0
KF2-Dev-Scripts/Engine/Classes/SkelControlBase.uc
2020-12-13 18:01:13 +03:00

268 lines
10 KiB
Ucode

/**
* Abstract base class for a skeletal controller.
* A SkelControl is a module that can modify the position or orientation of a set of bones in a skeletal mesh in some programmtic way.
*
* Copyright 1998-2013 Epic Games, Inc. All Rights Reserved.
*/
class SkelControlBase extends AnimObject
hidecategories(Object)
native(Anim)
abstract;
/** Enum for controlling which reference frame a controller is applied in. */
enum EBoneControlSpace
{
/** Set absolute position of bone in world space. */
BCS_WorldSpace,
/** Set position of bone in Actor's reference frame. */
BCS_ActorSpace,
/** Set position of bone in SkeletalMeshComponent's reference frame. */
BCS_ComponentSpace,
/** Set position of bone relative to parent bone. */
BCS_ParentBoneSpace,
/** Set position of bone in its own reference frame. */
BCS_BoneSpace,
/** Set position of bone in the reference frame of another bone. */
BCS_OtherBoneSpace,
/** Set position of socket/bone in Owner's Base Mesh. This is useful when this IK has to attach to the base mesh's specific location. */
BCS_BaseMeshSpace,
};
/** Name used to identify this SkelControl. */
var(Controller) name ControlName;
/**
* Used to control how much affect this SkelControl has.
* 1.0 means fully active, 0.0 means have no affect.
* Exactly how the control ramps up depends on the specific control type.
*/
var(Controller) float ControlStrength;
/** When calling SetActive passing in 'true', indicates how many seconds to take to reach a ControlStrength of 1.0. */
var(Controller) float BlendInTime;
/** When calling SetActive passing in 'false', indicates how many seconds to take to reach a ControlStrength of 0.0. */
var(Controller) float BlendOutTime;
/** BlendType - Easy in/out */
var(Controller) AlphaBlendType BlendType;
/** If TRUE, this controller will be applied AFTER physics has been run, as part of the process of blending physics into the graphics skeleton. */
var(Controller) bool bPostPhysicsController;
/** This is the slider bare at the bottom of the control. Strength towards which we are currently ramping. This is used in the anim tree.*/
var float StrengthTarget;
/** Amount of time left in the currently active blend. */
var transient float BlendTimeToGo;
/** If true, Strength will be the same as given AnimNode(s). This is to make transitions easier between nodes and Controllers. */
var(Controller) bool bSetStrengthFromAnimNode;
/** List of AnimNode names, to get Strength from */
var(Controller) Array<Name> StrengthAnimNodeNameList;
/** Cached list of nodes to get strength from */
var transient Array<AnimNode> CachedNodeList;
var transient bool bInitializedCachedNodeList;
//
// AnimMetadata Control
//
/** if TRUE, weight default to 0, and metadata in animation will enable the node based on animation weight. */
var(Controller) bool bControlledByAnimMetada;
/** If TRUE, weight defaults to 1, and metadata will set that to zero, disabling the node */
var(Controller) bool bInvertMetadataWeight;
/** Node weight when controlled by AnimMetadata */
var const transient float AnimMetadataWeight;
/** Tag to update MetaData */
var const transient INT AnimMetaDataUpdateTag;
/** If true, calling SetSkelControlActive on this node will call SetSkelControlActive on the next one in the chain as well. */
var(Controller) bool bPropagateSetActive;
/** This scaling is applied to the bone that this control is acting upon. */
var(Controller) float BoneScale;
/**
* Used to ensure we don't tick this SkelControl twice, if used in multiple different control chains.
* Compared against the SkeletalMeshComponent TickTag.
*/
var transient int ControlTickTag;
/**
* whether this control should be ignored if the SkeletalMeshComponent being composed hasn't been rendered recently
*
* @note this can be forced by the SkeletalMeshComponent's bIgnoreControllersWhenNotRendered flag
*/
var(Performance) bool bIgnoreWhenNotRendered;
/** Whether this skeletal controller should call the script TickSkelControl() event when ticked */
var bool bShouldTickInScript;
/** Call SkelControlTick() on Owner */
var bool bShouldTickOwner;
/** If true, when skel control becomes active it uses a curve rather than a linear blend to blend in more smoothly. */
/** This will change to BlendType in general **/
var() editconst deprecated bool bEnableEaseInOut;
/** If the LOD of this skeletal mesh is at or above this LOD, then this SkelControl will not be applied. */
var(Performance) int IgnoreAtOrAboveLOD;
/** Next SkelControl in the linked list. */
var SkelControlBase NextControl;
/** Used by editor. */
var deprecated int ControlPosX;
/** Used by editor. */
var deprecated int ControlPosY;
cpptext
{
USkelControlBase * GetSkelControlBase() { return this; }
/**
* Called from the SkeletalMeshComponent Tick function, to allow SkelControls to do any time-based update,
* such as adjusting their current blend amount.
*/
virtual void TickSkelControl(FLOAT DeltaSeconds, USkeletalMeshComponent* SkelComp);
/**
* Get the array of bones that this controller affects. Must be in hierarchy order, that is, parents before children.
*/
virtual void GetAffectedBones(INT BoneIndex, USkeletalMeshComponent* SkelComp, TArray<INT>& OutBoneIndices) {}
/**
* Calculate the new component-space transforms for the affected bones.
* The output array OutBoneTransforms must correspond to the OutBoneIndices array returned above (be in the same order etc).
*/
virtual void CalculateNewBoneTransforms(INT BoneIndex, USkeletalMeshComponent* SkelComp, TArray<FBoneAtom>& OutBoneTransforms) {}
/**
* Allows you to modify the scaling of all affected bones.
* The output array OutBoneScales must correspond to the OutBoneIndices array returned above (be in the same order etc).
*/
virtual void CalculateNewBoneScales(INT BoneIndex, USkeletalMeshComponent* SkelComp, TArray<FLOAT>& OutBoneScales) {}
/** Allows you to modify the scaling of the controller bone. */
virtual FLOAT GetBoneScale(INT BoneIndex, USkeletalMeshComponent* SkelComp) { return BoneScale; }
// UObject functions
virtual void PostLoad();
virtual void Serialize(FArchive& Ar);
// UTILS
/** Utility function for turning axis indicator enum into direction vector, possibly inverted. */
static FVector GetAxisDirVector(BYTE InAxis, UBOOL bInvert);
/**
* Create a matrix given two arbitrary rows of it.
* We generate the missing row using another cross product, but we have to get the order right to avoid changing handedness.
*/
static FMatrix BuildMatrixFromVectors(BYTE Vec1Axis, const FVector& Vec1, BYTE Vec2Axis, const FVector& Vec2);
/** Given two unit direction vectors, find the axis and angle between them. */
static void FindAxisAndAngle(const FVector& A, const FVector& B, FVector& OutAxis, FLOAT& OutAngle);
// ANIMTREE EDITOR SUPPORT
/**
* Draws this SkelControl in the AnimTreeEditor.
*
* @param Canvas The canvas to use.
* @param SelectedNodes Reference to array of all currently selected nodes, potentially including this node
* @param bShowWeight If TRUE, show the global percentage weight of this node, if applicable.
*/
virtual void DrawNode(FCanvas* Canvas, const TArray<UAnimObject*>& SelectedNodes, UBOOL bShowWeight) { DrawSkelControl(Canvas, SelectedNodes); }
/**
* Draws this SkelControl in the AnimTreeEditor.
*
* @param Canvas The canvas to use.
* @param SelectedNodes Reference to array of all currently selected nodes, potentially including this node
*/
virtual void DrawSkelControl(FCanvas* Canvas, const TArray<UAnimObject*>& SelectedNodes);
/** For editor use. */
FIntPoint GetConnectionLocation(INT ConnType);
/** If we should draw manipulation widget in 3D viewport. */
virtual INT GetWidgetCount() { return 0; }
/** The transform to use when drawing the widget, in world space. */
virtual FBoneAtom GetWidgetTM(INT WidgetIndex, USkeletalMeshComponent* SkelComp, INT BoneIndex) { return FMatrix::Identity; }
/** Update properties of this controller based on the widget being manipulated in the 3D viewport. */
virtual void HandleWidgetDrag(INT WidgetIndex, const FVector& DragVec) {}
/** Extra function for drawing special debug info in the 3D viewport if desired. */
virtual void DrawSkelControl3D(const FSceneView* View, FPrimitiveDrawInterface* PDI, USkeletalMeshComponent* SkelComp, INT BoneIndex) {}
/** Called when slider is moved in the AnimTreeEditor. NewSliderValue is in range 0.0 to 1.0. */
void HandleControlSliderMove(FLOAT NewSliderValue);
/**
* Get Alpha for this control. By default it is ControlStrength.
* 0.f means no effect, 1.f means full effect.
* ControlStrength controls whether or not CalculateNewBoneTransforms() is called.
* By modifying GetControlAlpha() you can still get CalculateNewBoneTransforms() called
* but not have the controller's effect applied on the mesh.
* This is useful for cases where you need to have the skeleton built in mesh space
* for testing, which is not available in TickSkelControl().
*/
virtual FLOAT GetControlAlpha();
/** Used by high level systems to assign a 'target' for a generic control. One example is the ControlTargets array in SkeletalMeshActor. */
virtual void SetControlTargetLocation(const FVector& TargetLocation) {}
/** Called after (copy/)pasted - reset values or re-link if needed**/
virtual void OnPaste();
}
/**
* Toggle the active state of the SkeControl.
* If passing in true, will take BlendInTime to reach a ControlStrength of 1.0.
* If passing in false, will take BlendOutTime to reach a ControlStrength of 0.0.
*/
native final function SetSkelControlActive(bool bInActive);
/**
* Set custom strength with optional blend time.
* @param NewStrength Target Strength for this controller.
* @param InBlendTime Time it will take to reach that new strength. (0.f == Instant)
*/
native final function SetSkelControlStrength(float NewStrength, float InBlendTime);
/**
* Called every tick if bShouldTickInScript is true
*/
event TickSkelControl(float DeltaTime, SkeletalMeshComponent SkelComp);
/** Accessor to get Metadataweight property value. */
native final function float GetControlMetadataWeight() const;
defaultproperties
{
BoneScale=1.0
ControlStrength=1.0
StrengthTarget=1.0
BlendInTime=0.2
BlendOutTime=0.2
IgnoreAtOrAboveLOD=1000
bShouldTickInScript=FALSE
bShouldTickOwner=FALSE
}