From a730c3b1af236d6e1aafa3d3059f29a2ae14c1c8 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Tue, 1 Jun 2021 10:27:57 +0200 Subject: [PATCH] Add using immediate DebugDraw for animated model skeleton drawing in Editor preview --- .../Viewport/Previews/AnimatedModelPreview.cs | 193 ++++++------------ 1 file changed, 57 insertions(+), 136 deletions(-) diff --git a/Source/Editor/Viewport/Previews/AnimatedModelPreview.cs b/Source/Editor/Viewport/Previews/AnimatedModelPreview.cs index 697a7c1c1..86ee3dc17 100644 --- a/Source/Editor/Viewport/Previews/AnimatedModelPreview.cs +++ b/Source/Editor/Viewport/Previews/AnimatedModelPreview.cs @@ -1,6 +1,5 @@ // Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. -using System.Collections.Generic; using FlaxEngine; using FlaxEditor.GUI.Input; using Object = FlaxEngine.Object; @@ -14,11 +13,7 @@ namespace FlaxEditor.Viewport.Previews public class AnimatedModelPreview : AssetPreview { private AnimatedModel _previewModel; - private StaticModel _previewNodesActor; - private Model _previewNodesModel; - private int _previewNodesCounter; - private List _previewNodesVB; - private List _previewNodesIB; + private bool _showNodes; /// /// Gets or sets the skinned model asset to preview. @@ -42,7 +37,19 @@ namespace FlaxEditor.Viewport.Previews /// /// Gets or sets a value indicating whether show animated model skeleton nodes debug view. /// - public bool ShowNodes { get; set; } = false; + public bool ShowNodes + { + get => _showNodes; + set + { + _showNodes = value; + if (value) + { + ShowDebugDraw = true; + ShowEditorPrimitives = true; + } + } + } /// /// Gets or sets a value indicating whether scale the model to the normalized bounds. @@ -72,17 +79,8 @@ namespace FlaxEditor.Viewport.Previews UpdateMode = AnimatedModel.AnimationUpdateMode.Manual }; - _previewNodesModel = FlaxEngine.Content.CreateVirtualAsset(); - _previewNodesModel.SetupLODs(new[] { 1 }); - _previewNodesActor = new StaticModel - { - Model = _previewNodesModel - }; - _previewNodesActor.SetMaterial(0, FlaxEngine.Content.LoadAsyncInternal(EditorAssets.WiresDebugMaterial)); - // Link actors for rendering Task.AddCustomActor(_previewModel); - Task.AddCustomActor(_previewNodesActor); if (useWidgets) { @@ -121,6 +119,49 @@ namespace FlaxEditor.Viewport.Previews } } + /// + protected override void OnDebugDraw(GPUContext context, ref RenderContext renderContext) + { + base.OnDebugDraw(context, ref renderContext); + + // Draw skeleton nodes + if (_showNodes) + { + _previewModel.GetCurrentPose(out var pose); + var nodes = _previewModel.SkinnedModel?.Nodes; + if (pose != null && pose.Length != 0 && nodes != null) + { + // Draw bounding box at the node locations + var nodesMask = NodesMask != null && NodesMask.Length == nodes.Length ? NodesMask : null; + var localBox = new OrientedBoundingBox(new Vector3(-1.0f), new Vector3(1.0f)); + for (int nodeIndex = 0; nodeIndex < pose.Length; nodeIndex++) + { + if (nodesMask != null && !nodesMask[nodeIndex]) + continue; + var transform = pose[nodeIndex]; + transform.Decompose(out var scale, out Matrix _, out _); + transform = Matrix.Invert(Matrix.Scaling(scale)) * transform; + var box = localBox * transform; + DebugDraw.DrawWireBox(box, Color.Green, 0, false); + } + + // Nodes connections + for (int nodeIndex = 0; nodeIndex < nodes.Length; nodeIndex++) + { + int parentIndex = nodes[nodeIndex].ParentIndex; + if (parentIndex != -1) + { + if (nodesMask != null && (!nodesMask[nodeIndex] || !nodesMask[parentIndex])) + continue; + var parentPos = pose[parentIndex].TranslationVector; + var bonePos = pose[nodeIndex].TranslationVector; + DebugDraw.DrawLine(parentPos, bonePos, Color.Green, 0, false); + } + } + } + } + } + /// public override void Update(float deltaTime) { @@ -131,122 +172,6 @@ namespace FlaxEditor.Viewport.Previews { _previewModel.UpdateAnimation(); } - - // Update the nodes debug (once every few frames) - _previewNodesActor.Transform = _previewModel.Transform; - var updateNodesCount = PlayAnimation || _previewNodesVB?.Count == 0 ? 1 : 10; - _previewNodesActor.IsActive = ShowNodes; - if (_previewNodesCounter++ % updateNodesCount == 0 && ShowNodes) - { - _previewModel.GetCurrentPose(out var pose); - var nodes = _previewModel.SkinnedModel?.Nodes; - if (pose == null || pose.Length == 0 || nodes == null) - { - _previewNodesActor.IsActive = false; - } - else - { - if (_previewNodesVB == null) - _previewNodesVB = new List(1024 * 2); - else - _previewNodesVB.Clear(); - if (_previewNodesIB == null) - _previewNodesIB = new List(1024 * 3); - else - _previewNodesIB.Clear(); - - // Draw bounding box at the node locations - var nodesMask = NodesMask != null && NodesMask.Length == nodes.Length ? NodesMask : null; - var localBox = new OrientedBoundingBox(new Vector3(-1.0f), new Vector3(1.0f)); - for (int nodeIndex = 0; nodeIndex < pose.Length; nodeIndex++) - { - if (nodesMask != null && !nodesMask[nodeIndex]) - continue; - - var transform = pose[nodeIndex]; - transform.Decompose(out var scale, out Matrix _, out _); - transform = Matrix.Invert(Matrix.Scaling(scale)) * transform; - - // Some inlined code to improve performance - var box = localBox * transform; - // - var iStart = _previewNodesVB.Count; - box.GetCorners(_previewNodesVB); - // - _previewNodesIB.Add(iStart + 0); - _previewNodesIB.Add(iStart + 1); - _previewNodesIB.Add(iStart + 0); - // - _previewNodesIB.Add(iStart + 0); - _previewNodesIB.Add(iStart + 4); - _previewNodesIB.Add(iStart + 0); - // - _previewNodesIB.Add(iStart + 1); - _previewNodesIB.Add(iStart + 2); - _previewNodesIB.Add(iStart + 1); - // - _previewNodesIB.Add(iStart + 1); - _previewNodesIB.Add(iStart + 5); - _previewNodesIB.Add(iStart + 1); - // - _previewNodesIB.Add(iStart + 2); - _previewNodesIB.Add(iStart + 3); - _previewNodesIB.Add(iStart + 2); - // - _previewNodesIB.Add(iStart + 2); - _previewNodesIB.Add(iStart + 6); - _previewNodesIB.Add(iStart + 2); - // - _previewNodesIB.Add(iStart + 3); - _previewNodesIB.Add(iStart + 7); - _previewNodesIB.Add(iStart + 3); - // - _previewNodesIB.Add(iStart + 4); - _previewNodesIB.Add(iStart + 5); - _previewNodesIB.Add(iStart + 4); - // - _previewNodesIB.Add(iStart + 4); - _previewNodesIB.Add(iStart + 7); - _previewNodesIB.Add(iStart + 4); - // - _previewNodesIB.Add(iStart + 5); - _previewNodesIB.Add(iStart + 6); - _previewNodesIB.Add(iStart + 5); - // - _previewNodesIB.Add(iStart + 6); - _previewNodesIB.Add(iStart + 7); - _previewNodesIB.Add(iStart + 6); - // - } - - // Nodes connections - for (int nodeIndex = 0; nodeIndex < nodes.Length; nodeIndex++) - { - int parentIndex = nodes[nodeIndex].ParentIndex; - - if (parentIndex != -1) - { - if (nodesMask != null && (!nodesMask[nodeIndex] || !nodesMask[parentIndex])) - continue; - - var parentPos = pose[parentIndex].TranslationVector; - var bonePos = pose[nodeIndex].TranslationVector; - - var iStart = _previewNodesVB.Count; - _previewNodesVB.Add(parentPos); - _previewNodesVB.Add(bonePos); - _previewNodesIB.Add(iStart + 0); - _previewNodesIB.Add(iStart + 1); - _previewNodesIB.Add(iStart + 0); - } - } - - if (_previewNodesIB.Count > 0) - _previewNodesModel.LODs[0].Meshes[0].UpdateMesh(_previewNodesVB, _previewNodesIB); - else - _previewNodesActor.IsActive = false; - } - } } /// @@ -265,11 +190,7 @@ namespace FlaxEditor.Viewport.Previews /// public override void OnDestroy() { - // Ensure to cleanup created actor objects - _previewNodesActor.Model = null; Object.Destroy(ref _previewModel); - Object.Destroy(ref _previewNodesActor); - Object.Destroy(ref _previewNodesModel); NodesMask = null; base.OnDestroy();