From 835127ac21690d3e896dd12cbecc5f52dce79784 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Tue, 14 Feb 2023 12:39:58 +0100 Subject: [PATCH] Add **Animation Instance Data node to Anim Graph** for caching value per-model --- Source/Editor/Surface/Archetypes/Animation.cs | 13 +++++++++++++ Source/Engine/Animations/Graph/AnimGraph.Base.cpp | 11 +++++++++-- Source/Engine/Animations/Graph/AnimGraph.h | 7 +++++++ .../Animations/Graph/AnimGroup.Animation.cpp | 14 +++++++++++++- 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/Source/Editor/Surface/Archetypes/Animation.cs b/Source/Editor/Surface/Archetypes/Animation.cs index dd214e8fc..b951f5f70 100644 --- a/Source/Editor/Surface/Archetypes/Animation.cs +++ b/Source/Editor/Surface/Archetypes/Animation.cs @@ -973,6 +973,19 @@ namespace FlaxEditor.Surface.Archetypes NodeElementArchetype.Factory.TextBox(30, Surface.Constants.LayoutOffsetY, 140, TextBox.DefaultHeight, 0, false), } }, + new NodeArchetype + { + TypeID = 33, + Title = "Animation Instance Data", + Description = "Caches custom data per-instance and allow sampling it. Can be used to randomize animation play offset to offer randomization for crowds reusing the same graph.", + Flags = NodeFlags.AnimGraph, + Size = new Float2(240, 20), + Elements = new[] + { + NodeElementArchetype.Factory.Output(0, "Get", typeof(Float4), 0), + NodeElementArchetype.Factory.Input(0, "Init", true, typeof(Float4), 1), + } + }, }; } } diff --git a/Source/Engine/Animations/Graph/AnimGraph.Base.cpp b/Source/Engine/Animations/Graph/AnimGraph.Base.cpp index 3205337ad..d7cdbeecd 100644 --- a/Source/Engine/Animations/Graph/AnimGraph.Base.cpp +++ b/Source/Engine/Animations/Graph/AnimGraph.Base.cpp @@ -115,6 +115,11 @@ void SlotBucketInit(AnimGraphInstanceData::Bucket& bucket) bucket.Slot.LoopsLeft = 0; } +void InstanceDataBucketInit(AnimGraphInstanceData::Bucket& bucket) +{ + bucket.InstanceData.Init = true; +} + bool SortMultiBlend1D(const byte& a, const byte& b, AnimGraphNode* n) { // Sort items by X location from the lowest to the highest @@ -432,10 +437,12 @@ bool AnimGraphBase::onNodeLoaded(Node* n) } // Animation Slot case 32: - { ADD_BUCKET(SlotBucketInit); break; - } + // Animation Instance Data + case 33: + ADD_BUCKET(InstanceDataBucketInit); + break; } break; // Custom diff --git a/Source/Engine/Animations/Graph/AnimGraph.h b/Source/Engine/Animations/Graph/AnimGraph.h index 6f469dcb6..aeb91fbd0 100644 --- a/Source/Engine/Animations/Graph/AnimGraph.h +++ b/Source/Engine/Animations/Graph/AnimGraph.h @@ -315,6 +315,12 @@ public: int32 LoopsLeft; }; + struct InstanceDataBucket + { + bool Init; + float Data[4]; + }; + /// /// The single data storage bucket for the instanced animation graph node. Used to store the node state (playback position, state, transition data). /// @@ -327,6 +333,7 @@ public: BlendPoseBucket BlendPose; StateMachineBucket StateMachine; SlotBucket Slot; + InstanceDataBucket InstanceData; }; }; diff --git a/Source/Engine/Animations/Graph/AnimGroup.Animation.cpp b/Source/Engine/Animations/Graph/AnimGroup.Animation.cpp index 9b74ff347..86aa42ff6 100644 --- a/Source/Engine/Animations/Graph/AnimGroup.Animation.cpp +++ b/Source/Engine/Animations/Graph/AnimGroup.Animation.cpp @@ -2035,10 +2035,22 @@ void AnimGraphExecutor::ProcessGroupAnimation(Box* boxBase, Node* nodeBase, Valu } break; } + // Animation Instance Data + case 33: + { + auto& bucket = context.Data->State[node->BucketIndex].InstanceData; + if (bucket.Init) + { + bucket.Init = false; + *(Float4*)bucket.Data = (Float4)tryGetValue(node->GetBox(1), Value::Zero); + } + value = *(Float4*)bucket.Data; + break; + } default: break; } - context.ValueCache.Add(boxBase, value); + context.ValueCache[boxBase] = value; } void AnimGraphExecutor::ProcessGroupFunction(Box* boxBase, Node* node, Value& value)