285 lines
13 KiB
Ucode
285 lines
13 KiB
Ucode
|
|
||
|
/**
|
||
|
* Copyright 1998-2013 Epic Games, Inc. All Rights Reserved.
|
||
|
*/
|
||
|
|
||
|
class AnimNode extends AnimObject
|
||
|
native(Anim)
|
||
|
hidecategories(Object)
|
||
|
abstract;
|
||
|
|
||
|
/** Enumeration for slider types */
|
||
|
enum ESliderType
|
||
|
{
|
||
|
ST_1D,
|
||
|
ST_2D
|
||
|
};
|
||
|
|
||
|
/** Curve Key
|
||
|
@CurveName : Morph Target name to blend
|
||
|
@Weight : Weight of the Morph Target
|
||
|
**/
|
||
|
struct CurveKey
|
||
|
{
|
||
|
var name CurveName;
|
||
|
var float Weight;
|
||
|
};
|
||
|
|
||
|
/** This node is considered 'relevant' - that is, has >0 weight in the final blend. */
|
||
|
var transient const bool bRelevant;
|
||
|
/** set to TRUE when this node became relevant this round of updates. Will be set to false on the next tick. */
|
||
|
var transient const bool bJustBecameRelevant;
|
||
|
/** If TRUE, this node will be ticked, even if bPauseAnims is TRUE on the SkelMeshComp. */
|
||
|
var(Performance) bool bTickDuringPausedAnims;
|
||
|
/** This node is editor only and used for something like placement preview */
|
||
|
var const bool bEditorOnly;
|
||
|
|
||
|
/** Used to avoid ticking a node twice if it has multiple parents. */
|
||
|
var transient const int NodeTickTag;
|
||
|
/** Initialization tag, for deferred InitAnim. */
|
||
|
var transient const INT NodeInitTag;
|
||
|
/** Used to avoid a node triggerring event twice if it has multiple parents. */
|
||
|
var transient const int NodeEndEventTick;
|
||
|
/** Index in AnimTick Array. Serialized, because we serialize TickArrayIndex in UAnimTree. */
|
||
|
var const int TickArrayIndex;
|
||
|
/** Used to indicate whether the BoneAtom cache for this node is up-to-date or not. */
|
||
|
var transient const int NodeCachedAtomsTag;
|
||
|
|
||
|
/** Total apparent weight this node has in the final blend of all animations. */
|
||
|
var const float NodeTotalWeight;
|
||
|
|
||
|
/** Array of Parent nodes, which in most cases only has 1 element. */
|
||
|
var duplicatetransient Array<AnimNodeBlendBase> ParentNodes;
|
||
|
|
||
|
/** This is the name used to find an AnimNode by name from a tree. */
|
||
|
var() name NodeName;
|
||
|
|
||
|
/** Temporarily disable caching when calling Super::GetBoneAtoms so it's not done multiple times. */
|
||
|
var const transient bool bDisableCaching;
|
||
|
/** If a node is linked to more than once in the graph, this is a cache of the results, to avoid re-evaluating the results. */
|
||
|
var transient array<BoneAtom> CachedBoneAtoms;
|
||
|
/** Num Desired Bones used in CachedBoneAtoms. If we request something different, CachedBoneAtoms array is not going to be valid. */
|
||
|
var transient byte CachedNumDesiredBones;
|
||
|
/** Cached root motion delta, to avoid recalculating (see above). */
|
||
|
var transient BoneAtom CachedRootMotionDelta;
|
||
|
/** Cached bool indicating if node supplies root motion, to avoid recalculating (see above). */
|
||
|
var transient int bCachedHasRootMotion;
|
||
|
/** Cached curve keys to avoid recalculating (see above). */
|
||
|
var transient array<CurveKey> CachedCurveKeys;
|
||
|
|
||
|
/** used when iterating over nodes via GetNodes() and related functions to skip nodes that have already been processed */
|
||
|
var transient int SearchTag;
|
||
|
|
||
|
/** Array of blended curve key for editor only **/
|
||
|
var(Morph) editoronly editconst transient array<CurveKey> LastUpdatedAnimMorphKeys;
|
||
|
|
||
|
/** Flags to control if Script Events should be called. Note that those will affect performance, so be careful! */
|
||
|
var() bool bCallScriptEventOnInit;
|
||
|
var() bool bCallScriptEventOnBecomeRelevant;
|
||
|
var() bool bCallScriptEventOnCeaseRelevant;
|
||
|
|
||
|
cpptext
|
||
|
{
|
||
|
UAnimNode * GetAnimNode() { return this;}
|
||
|
// UAnimNode interface
|
||
|
|
||
|
/** Do any initialisation, and then call InitAnim on all children. Should not discard any existing anim state though. */
|
||
|
virtual void InitAnim( USkeletalMeshComponent* meshComp, UAnimNodeBlendBase* Parent );
|
||
|
/** Deferred Initialization, called only when the node is relevant in the tree. */
|
||
|
virtual void DeferredInitAnim() {}
|
||
|
/** Call DeferredInitAnim() if the node required it. Recurses through the Tree. Increase UAnimNode::CurrentSeachTag before calling. */
|
||
|
virtual void CallDeferredInitAnim();
|
||
|
|
||
|
/** AnimSets have been updated, update all animations */
|
||
|
virtual void AnimSetsUpdated() {}
|
||
|
|
||
|
/**
|
||
|
* Called just after a node has been copied from its AnimTreeTemplate version.
|
||
|
* This is called on the copy, and SourceNode is the node within the AnimTreeTemplate.
|
||
|
*/
|
||
|
virtual void PostAnimNodeInstance(UAnimNode* SourceNode, TMap<UAnimNode*,UAnimNode*>& SrcToDestNodeMap) {}
|
||
|
|
||
|
/**
|
||
|
* Called when we need to reset our values to the source. This is called on a node that already has all pointers set up correctly
|
||
|
*/
|
||
|
virtual void ResetAnimNodeToSource(UAnimNode *SourceNode);
|
||
|
|
||
|
/**
|
||
|
* Update this node, then call TickAnim on all children.
|
||
|
* @param DeltaSeconds Amount of time to advance this node.
|
||
|
* @param TotalWeight The eventual weight that this node will have in the final blend. This is the multiplication of weights of all nodes above this one.
|
||
|
*/
|
||
|
virtual void TickAnim(FLOAT DeltaSeconds) {}
|
||
|
|
||
|
/** Parent node is requesting a blend out. Give node a chance to delay that. */
|
||
|
virtual UBOOL CanBlendOutFrom() { return TRUE; }
|
||
|
|
||
|
/** parent node is requesting a blend in. Give node a chance to delay that. */
|
||
|
virtual UBOOL CanBlendTo() { return TRUE; }
|
||
|
|
||
|
/**
|
||
|
* Add this node and all children to array. Node are added so a parent is always before its children in the array.
|
||
|
* @param bForceTraversal Disables optimization when calling this from the root. (precached AnimTickArray returned).
|
||
|
*/
|
||
|
void GetNodes(TArray<UAnimNode*>& Nodes, bool bForceTraversal=FALSE);
|
||
|
|
||
|
/** Add this node and all children of the specified class to array. Node are added so a parent is always before its children in the array. */
|
||
|
void GetNodesByClass(TArray<class UAnimNode*>& Nodes, class UClass* BaseClass);
|
||
|
|
||
|
/** Return an array with all UAnimNodeSequence childs, including this node. */
|
||
|
void GetAnimSeqNodes(TArray<UAnimNodeSequence*>& Nodes, FName InSynchGroupName=NAME_None);
|
||
|
|
||
|
virtual void BuildParentNodesArray();
|
||
|
/** Used for building array of AnimNodes in 'tick' order - that is, all parents of a node are added to array before it. */
|
||
|
virtual void BuildTickArray(TArray<UAnimNode*>& OutTickArray) {}
|
||
|
|
||
|
/**
|
||
|
* Get the local transform for each bone. If a blend, will recursively ask children and blend etc.
|
||
|
* DesiredBones should be in strictly increasing order.
|
||
|
*/
|
||
|
virtual void GetBoneAtoms(FBoneAtomArray& Atoms, const TArray<BYTE>& DesiredBones, FBoneAtom& RootMotionDelta, INT& bHasRootMotion, FCurveKeyArray& CurveKeys);
|
||
|
|
||
|
/**
|
||
|
* Will copy the cached results into the OutAtoms array if they are up to date and return TRUE
|
||
|
* If cache is not up to date, does nothing and retuns FALSE.
|
||
|
*/
|
||
|
virtual UBOOL GetCachedResults(FBoneAtomArray& OutAtoms, FBoneAtom& OutRootMotionDelta, INT& bOutHasRootMotion, FCurveKeyArray& OutCurveKeys, INT NumDesiredBones);
|
||
|
|
||
|
/** Save the supplied array of BoneAtoms in the CachedBoneAtoms. */
|
||
|
virtual UBOOL ShouldSaveCachedResults();
|
||
|
void SaveCachedResults(const FBoneAtomArray& NewAtoms, const FBoneAtom& NewRootMotionDelta, INT bNewHasRootMotion, const FCurveKeyArray& NewCurveKeys, INT NumDesiredBones);
|
||
|
|
||
|
/**
|
||
|
* Whether we should keep the cached result for the next frame or not
|
||
|
* This is to avoid keeping cached result once it ticks.
|
||
|
* It will release cache result if this returns FALSE
|
||
|
**/
|
||
|
virtual UBOOL ShouldKeepCachedResult() { return FALSE; }
|
||
|
|
||
|
/**
|
||
|
* Clear Cached Result
|
||
|
**/
|
||
|
virtual void ClearCachedResult();
|
||
|
|
||
|
/** Get notification that this node has become relevant for the final blend. ie TotalWeight is now > 0 */
|
||
|
virtual void OnBecomeRelevant();
|
||
|
|
||
|
/** Get notification that this node is no longer relevant for the final blend. ie TotalWeight is now == 0 */
|
||
|
virtual void OnCeaseRelevant();
|
||
|
|
||
|
/** Utility for counting the number of parents of this node that have been ticked. */
|
||
|
UBOOL WereAllParentsTicked() const;
|
||
|
|
||
|
/** Returns TRUE if this node is a child of Node */
|
||
|
UBOOL IsChildOf(UAnimNode* Node);
|
||
|
|
||
|
/** Returns TRUE if this node is a child of Node */
|
||
|
UBOOL IsChildOf_Internal(UAnimNode* Node);
|
||
|
|
||
|
/** Optimisation way to see if this is a UAnimTree */
|
||
|
virtual UAnimTree* GetAnimTree() { return NULL; }
|
||
|
|
||
|
virtual void SetAnim( FName SequenceName ) {}
|
||
|
virtual void SetPosition( FLOAT NewTime, UBOOL bFireNotifies ) {}
|
||
|
|
||
|
/** Override these functions to disable loading of editor only nodes */
|
||
|
virtual UBOOL NeedsLoadForClient() const;
|
||
|
virtual UBOOL NeedsLoadForServer() const;
|
||
|
|
||
|
/// ANIMTREE EDITOR
|
||
|
|
||
|
/**
|
||
|
* Draws this node 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) { DrawAnimNode(Canvas, SelectedNodes, bShowWeight); }
|
||
|
|
||
|
/**
|
||
|
* Draws this anim node 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 DrawAnimNode(FCanvas* Canvas, const TArray<UAnimObject*>& SelectedNodes, UBOOL bShowWeight) {}
|
||
|
|
||
|
/** Return title to display for this Node in the AnimTree editor. */
|
||
|
virtual FString GetNodeTitle() { return TEXT(""); }
|
||
|
|
||
|
/** For editor use. */
|
||
|
virtual FIntPoint GetConnectionLocation(INT ConnType, int ConnIndex);
|
||
|
|
||
|
/** Return the number of sliders */
|
||
|
virtual INT GetNumSliders() const { return 0; }
|
||
|
|
||
|
/** Return the slider type of slider Index */
|
||
|
virtual ESliderType GetSliderType(INT InIndex) const { return ST_1D; }
|
||
|
|
||
|
/** Return current position of slider for this node in the AnimTreeEditor. Return value should be within 0.0 to 1.0 range. */
|
||
|
virtual FLOAT GetSliderPosition(INT SliderIndex, INT ValueIndex) { return 0.f; }
|
||
|
|
||
|
/** Called when slider is moved in the AnimTreeEditor. NewSliderValue is in range 0.0 to 1.0. */
|
||
|
virtual void HandleSliderMove(INT SliderIndex, INT ValueIndex, FLOAT NewSliderValue) {}
|
||
|
|
||
|
/** Get the number to draw under the slider to show the current value being previewed. */
|
||
|
virtual FString GetSliderDrawValue(INT SliderIndex) { return FString(TEXT("")); }
|
||
|
|
||
|
/** internal code for GetNodes(); should only be called from GetNodes() or from the GetNodesInternal() of this node's parent */
|
||
|
virtual void GetNodesInternal(TArray<UAnimNode*>& Nodes);
|
||
|
|
||
|
/** Called after (copy/)pasted - reset values or re-link if needed**/
|
||
|
virtual void OnPaste();
|
||
|
|
||
|
// STATIC ANIMTREE UTILS
|
||
|
|
||
|
/** flag to prevent calling GetNodesInternal() from anywhere besides GetNodes() or another GetNodesInternal(), since
|
||
|
* we can't make it private/protected because UAnimNodeBlendBase needs to be able to call it on its children
|
||
|
*/
|
||
|
static UBOOL bNodeSearching;
|
||
|
/** current tag value used for SearchTag on nodes being iterated over. Incremented every time a new search is started */
|
||
|
static INT CurrentSearchTag;
|
||
|
/** Array to keep track of those nodes requiring an actual clear of the cache */
|
||
|
static TArray<UAnimNode*> NodesRequiringCacheClear;
|
||
|
|
||
|
/**
|
||
|
* Fills the Atoms array with the specified skeletal mesh reference pose.
|
||
|
*
|
||
|
* @param Atoms [out] Output array of relative bone transforms. Must be the same length as RefSkel when calling function.
|
||
|
* @param DesiredBones Indices of bones we want to modify. Parents must occur before children.
|
||
|
* @param RefSkel Input reference skeleton to create atoms from.
|
||
|
*/
|
||
|
static void FillWithRefPose(TArray<FBoneAtom>& Atoms, const TArray<BYTE>& DesiredBones, const TArray<struct FMeshBone>& RefSkel);
|
||
|
static void FillWithRefPose(FBoneAtomArray& Atoms, const TArray<BYTE>& DesiredBones, const TArray<struct FMeshBone>& RefSkel);
|
||
|
|
||
|
/** Utility for taking an array of bone indices and ensuring that all parents are present (ie. all bones between those in the array and the root are present). */
|
||
|
static void EnsureParentsPresent( TArray<BYTE>& BoneIndices, USkeletalMesh* SkelMesh );
|
||
|
|
||
|
/** Utility functions to ease off Casting */
|
||
|
virtual class UAnimNodeSlot* GetAnimNodeSlot() { return NULL; }
|
||
|
virtual class UAnimNodeAimOffset* GetAnimNodeAimOffset() { return NULL; }
|
||
|
virtual class UAnimNodeSequence* GetAnimNodeSequence() { return NULL; }
|
||
|
}
|
||
|
|
||
|
/** Called from InitAnim. Allows initialization of script-side properties of this node. */
|
||
|
event OnInit();
|
||
|
/** Get notification that this node has become relevant for the final blend. ie TotalWeight is now > 0 */
|
||
|
event OnBecomeRelevant();
|
||
|
/** Get notification that this node is no longer relevant for the final blend. ie TotalWeight is now == 0 */
|
||
|
event OnCeaseRelevant();
|
||
|
|
||
|
/**
|
||
|
* Find an Animation Node in the Animation Tree whose NodeName matches InNodeName.
|
||
|
* Will search this node and all below it.
|
||
|
* Warning: The search is O(n^2), so for large AnimTrees, cache result.
|
||
|
*/
|
||
|
native final function AnimNode FindAnimNode(name InNodeName);
|
||
|
|
||
|
native function PlayAnim(bool bLoop = false, float Rate = 1.0f, float StartTime = 0.0f);
|
||
|
native function StopAnim();
|
||
|
// calls PlayAnim with the current settings
|
||
|
native function ReplayAnim();
|
||
|
|