diff --git a/Source/Editor/Surface/Archetypes/Animation.StateMachine.cs b/Source/Editor/Surface/Archetypes/Animation.StateMachine.cs index abe66d3cc..bb4bc724d 100644 --- a/Source/Editor/Surface/Archetypes/Animation.StateMachine.cs +++ b/Source/Editor/Surface/Archetypes/Animation.StateMachine.cs @@ -653,6 +653,7 @@ namespace FlaxEditor.Surface.Archetypes protected Rectangle _renameButtonRect; private bool _cursorChanged = false; private bool _textRectHovered = false; + private bool _debugActive; /// /// The transitions list from this state to the others. @@ -1090,6 +1091,16 @@ namespace FlaxEditor.Surface.Archetypes // TODO: maybe update only on actual transitions change? UpdateTransitions(); + + // Debug current state + if (((AnimGraphSurface)Surface).TryGetTraceEvent(this, out var traceEvent)) + { + _debugActive = true; + } + else + { + _debugActive = false; + } } /// @@ -1130,6 +1141,10 @@ namespace FlaxEditor.Surface.Archetypes // Close button Render2D.DrawSprite(style.Cross, _closeButtonRect, _closeButtonRect.Contains(_mousePosition) ? style.Foreground : style.ForegroundGrey); + + // Debug outline + if (_debugActive) + Render2D.DrawRectangle(_textRect.MakeExpanded(1.0f), style.ProgressNormal); } /// diff --git a/Source/Engine/Animations/Graph/AnimGraph.h b/Source/Engine/Animations/Graph/AnimGraph.h index d8acae234..a774e6b85 100644 --- a/Source/Engine/Animations/Graph/AnimGraph.h +++ b/Source/Engine/Animations/Graph/AnimGraph.h @@ -803,6 +803,8 @@ struct AnimGraphContext ChunkedArray PoseCache; int32 PoseCacheSize; Dictionary ValueCache; + + AnimGraphTraceEvent& AddTraceEvent(const AnimGraphNode* node); }; /// diff --git a/Source/Engine/Animations/Graph/AnimGroup.Animation.cpp b/Source/Engine/Animations/Graph/AnimGroup.Animation.cpp index 0fab934ca..57829e8fd 100644 --- a/Source/Engine/Animations/Graph/AnimGroup.Animation.cpp +++ b/Source/Engine/Animations/Graph/AnimGroup.Animation.cpp @@ -52,6 +52,17 @@ void RetargetSkeletonNode(const SkeletonData& sourceSkeleton, const SkeletonData node = value; } +AnimGraphTraceEvent& AnimGraphContext::AddTraceEvent(const AnimGraphNode* node) +{ + auto& trace = Data->TraceEvents.AddOne(); + trace.Value = 0.0f; + trace.NodeId = node->ID; + const auto* nodePath = NodePath.Get(); + for (int32 i = 0; i < NodePath.Count(); i++) + trace.NodePath[i] = nodePath[i]; + return trace; +} + int32 AnimGraphExecutor::GetRootNodeIndex(Animation* anim) { // TODO: cache the root node index (use dictionary with Animation* -> int32 for fast lookups) @@ -223,13 +234,9 @@ void AnimGraphExecutor::ProcessAnimation(AnimGraphImpulse* nodes, AnimGraphNode* auto& context = Context.Get(); if (context.Data->EnableTracing) { - auto& trace = context.Data->TraceEvents.AddOne(); + auto& trace = context.AddTraceEvent(node); trace.Asset = anim; trace.Value = animPos; - trace.NodeId = node->ID; - const auto* nodePath = context.NodePath.Get(); - for (int32 i = 0; i < context.NodePath.Count(); i++) - trace.NodePath[i] = nodePath[i]; } // Evaluate nested animations @@ -502,11 +509,19 @@ Variant AnimGraphExecutor::SampleState(AnimGraphContext& context, const AnimGrap auto& data = state->Data.State; if (data.Graph == nullptr || data.Graph->GetRootNode() == nullptr) return Value::Null; + + // Add to trace + if (context.Data->EnableTracing) + { + auto& trace = context.AddTraceEvent(state); + } + ANIM_GRAPH_PROFILE_EVENT("Evaluate State"); context.NodePath.Add(state->ID); auto rootNode = data.Graph->GetRootNode(); auto result = eatBox((Node*)rootNode, &rootNode->Boxes[0]); context.NodePath.Pop(); + return result; }