/** * 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 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 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 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 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& 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& 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& Nodes, class UClass* BaseClass); /** Return an array with all UAnimNodeSequence childs, including this node. */ void GetAnimSeqNodes(TArray& 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& 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& 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& 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& 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& 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 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& Atoms, const TArray& DesiredBones, const TArray& RefSkel); static void FillWithRefPose(FBoneAtomArray& Atoms, const TArray& DesiredBones, const TArray& 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& 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();