From fa67d0581e113c511e59ba6a0314cc9c08ae4936 Mon Sep 17 00:00:00 2001 From: Nils Hausfeld Date: Sun, 9 Jun 2024 13:45:53 +0200 Subject: [PATCH 01/51] - Added optional description panel to visject CM - Enbaled description panel for visual scripting - Archetype description now gets drawn in description panel --- .../Editor/Surface/ContextMenu/VisjectCM.cs | 44 ++++++++++++++++++- .../Surface/ContextMenu/VisjectCMItem.cs | 7 +++ .../Surface/VisjectSurface.ContextMenu.cs | 1 + Source/Editor/Surface/VisjectSurface.cs | 5 +++ Source/Editor/Surface/VisualScriptSurface.cs | 3 ++ 5 files changed, 58 insertions(+), 2 deletions(-) diff --git a/Source/Editor/Surface/ContextMenu/VisjectCM.cs b/Source/Editor/Surface/ContextMenu/VisjectCM.cs index ae4cef3dc..005c164fd 100644 --- a/Source/Editor/Surface/ContextMenu/VisjectCM.cs +++ b/Source/Editor/Surface/ContextMenu/VisjectCM.cs @@ -51,6 +51,10 @@ namespace FlaxEditor.Surface.ContextMenu private Elements.Box _selectedBox; private NodeArchetype _parameterGetNodeArchetype; private NodeArchetype _parameterSetNodeArchetype; + private bool _useDescriptionPanel; + private string _currentDescriptionText; + private Panel _descriptionPanel; + private Label _descriptionLabel; /// /// The selected item @@ -82,6 +86,11 @@ namespace FlaxEditor.Surface.ContextMenu /// public bool CanSetParameters; + /// + /// True if the surface should make use of a description panel drawn at the bottom of the context menu + /// + public bool UseDescriptionPanel; + /// /// The groups archetypes. Cannot be null. /// @@ -127,9 +136,11 @@ namespace FlaxEditor.Surface.ContextMenu _parameterGetNodeArchetype = info.ParameterGetNodeArchetype ?? Archetypes.Parameters.Nodes[0]; if (info.CanSetParameters) _parameterSetNodeArchetype = info.ParameterSetNodeArchetype ?? Archetypes.Parameters.Nodes[3]; + _useDescriptionPanel = info.UseDescriptionPanel; + float descriptionHeight = 75; // Context menu dimensions - Size = new Float2(300, 400); + Size = new Float2(300, 400 + (_useDescriptionPanel ? descriptionHeight : 0)); var headerPanel = new Panel(ScrollBars.None) { @@ -187,7 +198,7 @@ namespace FlaxEditor.Surface.ContextMenu // Create first panel (for scrollbar) var panel1 = new Panel(ScrollBars.Vertical) { - Bounds = new Rectangle(0, _searchBox.Bottom + 1, Width, Height - _searchBox.Bottom - 2), + Bounds = new Rectangle(0, _searchBox.Bottom + 1, Width, Height - _searchBox.Bottom - (_useDescriptionPanel ? descriptionHeight : 0) - 2), Parent = this }; @@ -202,6 +213,27 @@ namespace FlaxEditor.Surface.ContextMenu }; _groupsPanel = panel2; + // Create description panel if enabled + if (_useDescriptionPanel) + { + var descriptionPanel = new Panel(ScrollBars.None) + { + Parent = this, + Bounds = new Rectangle(0, Height - descriptionHeight, Width, descriptionHeight), + BackgroundColor = Style.Current.BackgroundNormal, + }; + _descriptionPanel = descriptionPanel; + + var descriptionLabel = new Label(8,8,Width-16,Height-16) + { + Parent = _descriptionPanel, + HorizontalAlignment = TextAlignment.Near, + VerticalAlignment = TextAlignment.Near, + Wrapping = TextWrapping.WrapWords, + }; + _descriptionLabel = descriptionLabel; + } + // Init groups var nodes = new List(); foreach (var groupArchetype in info.Groups) @@ -549,6 +581,14 @@ namespace FlaxEditor.Surface.ContextMenu _groups[i].Open(animate); } + public void SetDescriptionText(string text) + { + if(!_useDescriptionPanel) + return; + _currentDescriptionText = text; + _descriptionLabel.Text = _currentDescriptionText; + } + /// /// Resets the view. /// diff --git a/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs b/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs index 9d582c491..ede6775e7 100644 --- a/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs +++ b/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs @@ -338,6 +338,13 @@ namespace FlaxEditor.Surface.ContextMenu return base.OnMouseUp(location, button); } + /// + public override void OnMouseEnter(Float2 location) + { + base.OnMouseEnter(location); + Group.ContextMenu.SetDescriptionText(_archetype.Description); + } + /// public override void OnMouseLeave() { diff --git a/Source/Editor/Surface/VisjectSurface.ContextMenu.cs b/Source/Editor/Surface/VisjectSurface.ContextMenu.cs index 7f284420d..54f4e14e6 100644 --- a/Source/Editor/Surface/VisjectSurface.ContextMenu.cs +++ b/Source/Editor/Surface/VisjectSurface.ContextMenu.cs @@ -237,6 +237,7 @@ namespace FlaxEditor.Surface return new VisjectCM(new VisjectCM.InitInfo { CanSetParameters = CanSetParameters, + UseDescriptionPanel = UseContextMenuDescriptionPanel, Groups = NodeArchetypes, CanSpawnNode = CanUseNodeType, ParametersGetter = () => Parameters, diff --git a/Source/Editor/Surface/VisjectSurface.cs b/Source/Editor/Surface/VisjectSurface.cs index 78277dbe2..b3869f304 100644 --- a/Source/Editor/Surface/VisjectSurface.cs +++ b/Source/Editor/Surface/VisjectSurface.cs @@ -535,6 +535,11 @@ namespace FlaxEditor.Surface /// public virtual bool CanSetParameters => false; + /// + /// True of the context menu should make use of a description panel drawn at the bottom of the menu + /// + public virtual bool UseContextMenuDescriptionPanel => false; + /// /// Gets a value indicating whether surface supports/allows live previewing graph modifications due to value sliders and color pickers. True by default but disabled for shader surfaces that generate and compile shader source at flight. /// diff --git a/Source/Editor/Surface/VisualScriptSurface.cs b/Source/Editor/Surface/VisualScriptSurface.cs index ee0a3c6d6..f32bd2ea0 100644 --- a/Source/Editor/Surface/VisualScriptSurface.cs +++ b/Source/Editor/Surface/VisualScriptSurface.cs @@ -174,6 +174,9 @@ namespace FlaxEditor.Surface /// public override bool CanSetParameters => true; + /// + public override bool UseContextMenuDescriptionPanel => true; + /// public override bool CanUseNodeType(GroupArchetype groupArchetype, NodeArchetype nodeArchetype) { From bd06ed9c148c62374826f02b62aeedca445c09bd Mon Sep 17 00:00:00 2001 From: Nils Hausfeld Date: Sun, 9 Jun 2024 23:42:48 +0200 Subject: [PATCH 02/51] - Archetypes now fetch signature and description independently - Added larger label for signature to description panel --- Source/Editor/Surface/Archetypes/Particles.cs | 2 +- .../Editor/Surface/ContextMenu/VisjectCM.cs | 23 +++++-- .../Surface/ContextMenu/VisjectCMItem.cs | 4 +- Source/Editor/Surface/NodeArchetype.cs | 6 ++ Source/Editor/Surface/SurfaceNode.cs | 2 +- Source/Editor/Surface/SurfaceUtils.cs | 63 +++++++++++-------- Source/Editor/Surface/VisualScriptSurface.cs | 13 ++-- 7 files changed, 75 insertions(+), 38 deletions(-) diff --git a/Source/Editor/Surface/Archetypes/Particles.cs b/Source/Editor/Surface/Archetypes/Particles.cs index 081f53e30..9166cb0d9 100644 --- a/Source/Editor/Surface/Archetypes/Particles.cs +++ b/Source/Editor/Surface/Archetypes/Particles.cs @@ -122,7 +122,7 @@ namespace FlaxEditor.Surface.Archetypes { Name = module.Title, Tag = module.TypeID, - TooltipText = module.Description, + TooltipText = $"{module.Signature}\n{module.Description}", }); } cm.ItemClicked += item => AddModule((ushort)item.Tag); diff --git a/Source/Editor/Surface/ContextMenu/VisjectCM.cs b/Source/Editor/Surface/ContextMenu/VisjectCM.cs index 005c164fd..182d18b5d 100644 --- a/Source/Editor/Surface/ContextMenu/VisjectCM.cs +++ b/Source/Editor/Surface/ContextMenu/VisjectCM.cs @@ -52,8 +52,8 @@ namespace FlaxEditor.Surface.ContextMenu private NodeArchetype _parameterGetNodeArchetype; private NodeArchetype _parameterSetNodeArchetype; private bool _useDescriptionPanel; - private string _currentDescriptionText; private Panel _descriptionPanel; + private Label _descriptionSignatureLabel; private Label _descriptionLabel; /// @@ -224,7 +224,20 @@ namespace FlaxEditor.Surface.ContextMenu }; _descriptionPanel = descriptionPanel; - var descriptionLabel = new Label(8,8,Width-16,Height-16) + var signatureFontReference = new FontReference(Style.Current.FontLarge.Asset, 11); + var signatureLabel = new Label(8, 8, Width - 16, Height - 16) + { + Parent = _descriptionPanel, + HorizontalAlignment = TextAlignment.Near, + VerticalAlignment = TextAlignment.Near, + Wrapping = TextWrapping.WrapWords, + Font = signatureFontReference, + Bold = true, + Italic = true, + }; + _descriptionSignatureLabel = signatureLabel; + + var descriptionLabel = new Label(8, 40, Width - 16, Height - 16) { Parent = _descriptionPanel, HorizontalAlignment = TextAlignment.Near, @@ -581,12 +594,12 @@ namespace FlaxEditor.Surface.ContextMenu _groups[i].Open(animate); } - public void SetDescriptionText(string text) + public void SetDescriptionText(string header, string text) { if(!_useDescriptionPanel) return; - _currentDescriptionText = text; - _descriptionLabel.Text = _currentDescriptionText; + _descriptionSignatureLabel.Text = header; + _descriptionLabel.Text = text; } /// diff --git a/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs b/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs index ede6775e7..8d9fceba7 100644 --- a/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs +++ b/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs @@ -62,7 +62,7 @@ namespace FlaxEditor.Surface.ContextMenu Group = group; _groupArchetype = groupArchetype; _archetype = archetype; - TooltipText = _archetype.Description; + TooltipText = $"{_archetype.Signature}\n{_archetype.Description}"; } /// @@ -342,7 +342,7 @@ namespace FlaxEditor.Surface.ContextMenu public override void OnMouseEnter(Float2 location) { base.OnMouseEnter(location); - Group.ContextMenu.SetDescriptionText(_archetype.Description); + Group.ContextMenu.SetDescriptionText(_archetype.Signature, _archetype.Description); } /// diff --git a/Source/Editor/Surface/NodeArchetype.cs b/Source/Editor/Surface/NodeArchetype.cs index d0e3f2291..efcec6b62 100644 --- a/Source/Editor/Surface/NodeArchetype.cs +++ b/Source/Editor/Surface/NodeArchetype.cs @@ -134,6 +134,11 @@ namespace FlaxEditor.Surface /// public string SubTitle; + /// + /// Node signature for tooltip and description purposes + /// + public string Signature; + /// /// Short node description. /// @@ -210,6 +215,7 @@ namespace FlaxEditor.Surface Flags = Flags, Title = Title, SubTitle = SubTitle, + Signature = Signature, Description = Description, AlternativeTitles = (string[])AlternativeTitles?.Clone(), Tag = Tag, diff --git a/Source/Editor/Surface/SurfaceNode.cs b/Source/Editor/Surface/SurfaceNode.cs index 0eb739d72..07dc4f5e9 100644 --- a/Source/Editor/Surface/SurfaceNode.cs +++ b/Source/Editor/Surface/SurfaceNode.cs @@ -124,7 +124,7 @@ namespace FlaxEditor.Surface Archetype = nodeArch; GroupArchetype = groupArch; AutoFocus = false; - TooltipText = nodeArch.Description; + TooltipText = TooltipText = $"{nodeArch.Signature}\n{nodeArch.Description}"; CullChildren = false; BackgroundColor = Style.Current.BackgroundNormal; diff --git a/Source/Editor/Surface/SurfaceUtils.cs b/Source/Editor/Surface/SurfaceUtils.cs index 9bec6c179..936aa52eb 100644 --- a/Source/Editor/Surface/SurfaceUtils.cs +++ b/Source/Editor/Surface/SurfaceUtils.cs @@ -440,12 +440,24 @@ namespace FlaxEditor.Surface return sb.ToString(); } - internal static string GetVisualScriptMemberInfoDescription(ScriptMemberInfo member) + internal static string GetVisualScriptMemberInfoSignature(ScriptMemberInfo member, bool appendPropertyInfo = true) { var name = member.Name; var declaringType = member.DeclaringType; var valueType = member.ValueType; + // Getter/setter method of the property - we can return early here + bool isGetterOrSetter = name.StartsWith("get_") || name.StartsWith("set_"); + if (member.IsMethod && isGetterOrSetter) + { + var flags = member.IsStatic ? BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly : BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly; + var property = declaringType.GetMembers(name.Substring(4), MemberTypes.Property, flags); + if (property != null && property.Length != 0) + { + return GetVisualScriptMemberInfoDescription(property[0]); + } + } + var sb = new StringBuilder(); if (member.IsStatic) sb.Append("static "); @@ -456,34 +468,22 @@ namespace FlaxEditor.Surface sb.Append(declaringType.Name); sb.Append('.'); sb.Append(name); - if (member.IsMethod) + + // Is a method and not a property + if (member.IsMethod && !isGetterOrSetter) { - // Getter/setter method of the property - if (name.StartsWith("get_") || name.StartsWith("set_")) + sb.Append('('); + var parameters = member.GetParameters(); + for (int i = 0; i < parameters.Length; i++) { - var flags = member.IsStatic ? BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly : BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly; - var property = declaringType.GetMembers(name.Substring(4), MemberTypes.Property, flags); - if (property != null && property.Length != 0) - { - return GetVisualScriptMemberInfoDescription(property[0]); - } - } - // Method - else - { - sb.Append('('); - var parameters = member.GetParameters(); - for (int i = 0; i < parameters.Length; i++) - { - if (i != 0) - sb.Append(", "); - ref var param = ref parameters[i]; - param.ToString(sb); - } - sb.Append(')'); + if (i != 0) + sb.Append(", "); + ref var param = ref parameters[i]; + param.ToString(sb); } + sb.Append(')'); } - else if (member.IsProperty) + else if (member.IsProperty && appendPropertyInfo) { sb.Append(' '); sb.Append('{'); @@ -495,6 +495,19 @@ namespace FlaxEditor.Surface sb.Append('}'); } + return sb.ToString(); + } + + internal static string GetVisualScriptMemberShortDescription(ScriptMemberInfo member) + { + return Editor.Instance.CodeDocs.GetTooltip(member); + } + + internal static string GetVisualScriptMemberInfoDescription(ScriptMemberInfo member) + { + var signature = GetVisualScriptMemberInfoSignature(member); + var sb = new StringBuilder(signature); + // Tooltip var tooltip = Editor.Instance.CodeDocs.GetTooltip(member); if (!string.IsNullOrEmpty(tooltip)) diff --git a/Source/Editor/Surface/VisualScriptSurface.cs b/Source/Editor/Surface/VisualScriptSurface.cs index f32bd2ea0..39a705ff9 100644 --- a/Source/Editor/Surface/VisualScriptSurface.cs +++ b/Source/Editor/Surface/VisualScriptSurface.cs @@ -370,7 +370,8 @@ namespace FlaxEditor.Surface node.DefaultValues[2] = parameters.Length; node.Flags &= ~NodeFlags.NoSpawnViaGUI; node.Title = SurfaceUtils.GetMethodDisplayName((string)node.DefaultValues[1]); - node.Description = SurfaceUtils.GetVisualScriptMemberInfoDescription(member); + node.Signature = SurfaceUtils.GetVisualScriptMemberInfoSignature(member); + node.Description = SurfaceUtils.GetVisualScriptMemberShortDescription(member); node.SubTitle = string.Format(" (in {0})", scriptTypeName); node.Tag = member; @@ -418,7 +419,8 @@ namespace FlaxEditor.Surface node.DefaultValues[3] = member.IsStatic; node.Flags &= ~NodeFlags.NoSpawnViaGUI; node.Title = "Get " + name; - node.Description = SurfaceUtils.GetVisualScriptMemberInfoDescription(member); + node.Signature = SurfaceUtils.GetVisualScriptMemberInfoSignature(member); + node.Description = SurfaceUtils.GetVisualScriptMemberShortDescription(member); node.SubTitle = string.Format(" (in {0})", scriptTypeName); // Create group archetype @@ -452,7 +454,8 @@ namespace FlaxEditor.Surface node.DefaultValues[3] = member.IsStatic; node.Flags &= ~NodeFlags.NoSpawnViaGUI; node.Title = "Set " + name; - node.Description = SurfaceUtils.GetVisualScriptMemberInfoDescription(member); + node.Signature = SurfaceUtils.GetVisualScriptMemberInfoSignature(member); + node.Description = SurfaceUtils.GetVisualScriptMemberShortDescription(member); node.SubTitle = string.Format(" (in {0})", scriptTypeName); // Create group archetype @@ -510,7 +513,8 @@ namespace FlaxEditor.Surface bindNode.DefaultValues[1] = name; bindNode.Flags &= ~NodeFlags.NoSpawnViaGUI; bindNode.Title = "Bind " + name; - bindNode.Description = SurfaceUtils.GetVisualScriptMemberInfoDescription(member); + bindNode.Signature = SurfaceUtils.GetVisualScriptMemberInfoSignature(member); + bindNode.Description = SurfaceUtils.GetVisualScriptMemberShortDescription(member); bindNode.SubTitle = string.Format(" (in {0})", scriptTypeName); ((IList)group.Archetypes).Add(bindNode); @@ -520,6 +524,7 @@ namespace FlaxEditor.Surface unbindNode.DefaultValues[1] = name; unbindNode.Flags &= ~NodeFlags.NoSpawnViaGUI; unbindNode.Title = "Unbind " + name; + unbindNode.Signature = bindNode.Signature; unbindNode.Description = bindNode.Description; unbindNode.SubTitle = bindNode.SubTitle; ((IList)group.Archetypes).Add(unbindNode); From ed8c7bc33846083e504aae0698373d2a80ac749a Mon Sep 17 00:00:00 2001 From: Nils Hausfeld Date: Sun, 9 Jun 2024 23:52:34 +0200 Subject: [PATCH 03/51] - Format change --- Source/Editor/Surface/ContextMenu/VisjectCM.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Editor/Surface/ContextMenu/VisjectCM.cs b/Source/Editor/Surface/ContextMenu/VisjectCM.cs index 182d18b5d..2b922297c 100644 --- a/Source/Editor/Surface/ContextMenu/VisjectCM.cs +++ b/Source/Editor/Surface/ContextMenu/VisjectCM.cs @@ -225,7 +225,7 @@ namespace FlaxEditor.Surface.ContextMenu _descriptionPanel = descriptionPanel; var signatureFontReference = new FontReference(Style.Current.FontLarge.Asset, 11); - var signatureLabel = new Label(8, 8, Width - 16, Height - 16) + var signatureLabel = new Label(8, 12, Width - 16, Height - 16) { Parent = _descriptionPanel, HorizontalAlignment = TextAlignment.Near, From da6883489ebb87399725f4e61a279964d3a2cadc Mon Sep 17 00:00:00 2001 From: Nils Hausfeld Date: Mon, 10 Jun 2024 12:03:34 +0200 Subject: [PATCH 04/51] - Added description panel resizing --- .../Editor/Surface/ContextMenu/VisjectCM.cs | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/Source/Editor/Surface/ContextMenu/VisjectCM.cs b/Source/Editor/Surface/ContextMenu/VisjectCM.cs index 2b922297c..aaac3c9d3 100644 --- a/Source/Editor/Surface/ContextMenu/VisjectCM.cs +++ b/Source/Editor/Surface/ContextMenu/VisjectCM.cs @@ -138,9 +138,8 @@ namespace FlaxEditor.Surface.ContextMenu _parameterSetNodeArchetype = info.ParameterSetNodeArchetype ?? Archetypes.Parameters.Nodes[3]; _useDescriptionPanel = info.UseDescriptionPanel; - float descriptionHeight = 75; // Context menu dimensions - Size = new Float2(300, 400 + (_useDescriptionPanel ? descriptionHeight : 0)); + Size = new Float2(300, 400); var headerPanel = new Panel(ScrollBars.None) { @@ -152,7 +151,7 @@ namespace FlaxEditor.Surface.ContextMenu }; // Title bar - var titleFontReference = new FontReference(Style.Current.FontLarge.Asset, 10); + var titleFontReference = new FontReference(Style.Current.FontMedium.Asset, 11); var titleLabel = new Label { Width = Width * 0.5f - 8f, @@ -198,7 +197,7 @@ namespace FlaxEditor.Surface.ContextMenu // Create first panel (for scrollbar) var panel1 = new Panel(ScrollBars.Vertical) { - Bounds = new Rectangle(0, _searchBox.Bottom + 1, Width, Height - _searchBox.Bottom - (_useDescriptionPanel ? descriptionHeight : 0) - 2), + Bounds = new Rectangle(0, _searchBox.Bottom + 1, Width, Height - _searchBox.Bottom - 2), Parent = this }; @@ -219,13 +218,13 @@ namespace FlaxEditor.Surface.ContextMenu var descriptionPanel = new Panel(ScrollBars.None) { Parent = this, - Bounds = new Rectangle(0, Height - descriptionHeight, Width, descriptionHeight), + Bounds = new Rectangle(0, Height, Width, 0), BackgroundColor = Style.Current.BackgroundNormal, }; _descriptionPanel = descriptionPanel; - var signatureFontReference = new FontReference(Style.Current.FontLarge.Asset, 11); - var signatureLabel = new Label(8, 12, Width - 16, Height - 16) + var signatureFontReference = new FontReference(Style.Current.FontMedium.Asset, 10); + var signatureLabel = new Label(8, 12, Width - 16, 0) { Parent = _descriptionPanel, HorizontalAlignment = TextAlignment.Near, @@ -234,16 +233,20 @@ namespace FlaxEditor.Surface.ContextMenu Font = signatureFontReference, Bold = true, Italic = true, + AutoHeight = true, }; + signatureLabel.SetAnchorPreset(AnchorPresets.TopLeft, true); _descriptionSignatureLabel = signatureLabel; - var descriptionLabel = new Label(8, 40, Width - 16, Height - 16) + var descriptionLabel = new Label(8, 0, Width - 16, 0) { Parent = _descriptionPanel, HorizontalAlignment = TextAlignment.Near, VerticalAlignment = TextAlignment.Near, Wrapping = TextWrapping.WrapWords, + AutoHeight = true, }; + descriptionLabel.SetAnchorPreset(AnchorPresets.TopLeft, true); _descriptionLabel = descriptionLabel; } @@ -598,8 +601,17 @@ namespace FlaxEditor.Surface.ContextMenu { if(!_useDescriptionPanel) return; + _descriptionSignatureLabel.Text = header; + var panelHeight = _descriptionSignatureLabel.Height; + + _descriptionLabel.Y = _descriptionSignatureLabel.Bounds.Bottom + 8f; _descriptionLabel.Text = text; + + panelHeight += _descriptionLabel.Height + 8f + 24f; + _descriptionPanel.Height = panelHeight; + Size = new Float2(300, 400 + _descriptionPanel.Height); + UpdateWindowSize(); } /// From 1da00264a057df8fc4fb5d17c62a766697734627 Mon Sep 17 00:00:00 2001 From: Nils Hausfeld Date: Mon, 10 Jun 2024 18:45:03 +0200 Subject: [PATCH 05/51] - Description panel now updates when navigating items with keyboard - First test of drawing images in description panel (showing class type) - Layout and style changes to work with images and make evertything a bit tighter --- Source/Editor/Surface/AnimGraphSurface.cs | 2 + .../Editor/Surface/ContextMenu/VisjectCM.cs | 99 ++++++++++++++----- .../Surface/ContextMenu/VisjectCMItem.cs | 10 +- .../Surface/VisjectSurface.ContextMenu.cs | 1 + 4 files changed, 86 insertions(+), 26 deletions(-) diff --git a/Source/Editor/Surface/AnimGraphSurface.cs b/Source/Editor/Surface/AnimGraphSurface.cs index 4e8b6f11e..ea0d9d32f 100644 --- a/Source/Editor/Surface/AnimGraphSurface.cs +++ b/Source/Editor/Surface/AnimGraphSurface.cs @@ -197,6 +197,7 @@ namespace FlaxEditor.Surface { Groups = StateMachineGroupArchetypes, CanSpawnNode = (_, _) => true, + Style = Style, }); _cmStateMachineMenu.ShowExpanded = true; } @@ -214,6 +215,7 @@ namespace FlaxEditor.Surface CanSpawnNode = CanUseNodeType, ParametersGetter = null, CustomNodesGroup = GetCustomNodes(), + Style = Style, }); _cmStateMachineTransitionMenu.AddGroup(StateMachineTransitionGroupArchetype, false); } diff --git a/Source/Editor/Surface/ContextMenu/VisjectCM.cs b/Source/Editor/Surface/ContextMenu/VisjectCM.cs index aaac3c9d3..ce2b5d12b 100644 --- a/Source/Editor/Surface/ContextMenu/VisjectCM.cs +++ b/Source/Editor/Surface/ContextMenu/VisjectCM.cs @@ -51,15 +51,29 @@ namespace FlaxEditor.Surface.ContextMenu private Elements.Box _selectedBox; private NodeArchetype _parameterGetNodeArchetype; private NodeArchetype _parameterSetNodeArchetype; - private bool _useDescriptionPanel; - private Panel _descriptionPanel; - private Label _descriptionSignatureLabel; - private Label _descriptionLabel; + + // Description panel elements + private readonly bool _useDescriptionPanel; + private readonly Panel _descriptionPanel; + private readonly Image _descriptionClassImage; + private readonly Label _descriptionSignatureLabel; + private readonly Label _descriptionLabel; + + + private VisjectCMItem _selectedItem; /// /// The selected item /// - public VisjectCMItem SelectedItem; + public VisjectCMItem SelectedItem + { + get => _selectedItem; + set + { + _selectedItem = value; + _selectedItem?.OnSelect(); + } + } /// /// Event fired when any item in this popup menu gets clicked. @@ -120,6 +134,11 @@ namespace FlaxEditor.Surface.ContextMenu /// The parameter setter node archetype to spawn when adding the parameter getter. Can be null. /// public NodeArchetype ParameterSetNodeArchetype; + + /// + /// The surface style to use to draw images in the description panel + /// + public SurfaceStyle Style; } /// @@ -151,7 +170,7 @@ namespace FlaxEditor.Surface.ContextMenu }; // Title bar - var titleFontReference = new FontReference(Style.Current.FontMedium.Asset, 11); + var titleFontReference = new FontReference(Style.Current.FontLarge.Asset, 10); var titleLabel = new Label { Width = Width * 0.5f - 8f, @@ -200,7 +219,6 @@ namespace FlaxEditor.Surface.ContextMenu Bounds = new Rectangle(0, _searchBox.Bottom + 1, Width, Height - _searchBox.Bottom - 2), Parent = this }; - _panel1 = panel1; // Create second panel (for groups arrangement) @@ -215,16 +233,25 @@ namespace FlaxEditor.Surface.ContextMenu // Create description panel if enabled if (_useDescriptionPanel) { - var descriptionPanel = new Panel(ScrollBars.None) + _descriptionPanel = new Panel(ScrollBars.None) { Parent = this, Bounds = new Rectangle(0, Height, Width, 0), BackgroundColor = Style.Current.BackgroundNormal, }; - _descriptionPanel = descriptionPanel; - var signatureFontReference = new FontReference(Style.Current.FontMedium.Asset, 10); - var signatureLabel = new Label(8, 12, Width - 16, 0) + var spriteHandle = info.Style.Icons.BoxClose; + _descriptionClassImage = new Image(8, 12, 20, 20) + { + Parent = _descriptionPanel, + Brush = new SpriteBrush(spriteHandle), + Color = Color.Aqua, + MouseOverColor = Color.Aqua, + AutoFocus = false, + }; + + var signatureFontReference = new FontReference(Style.Current.FontMedium.Asset, 9f); + _descriptionSignatureLabel = new Label(32, 8, Width - 40, 0) { Parent = _descriptionPanel, HorizontalAlignment = TextAlignment.Near, @@ -232,22 +259,20 @@ namespace FlaxEditor.Surface.ContextMenu Wrapping = TextWrapping.WrapWords, Font = signatureFontReference, Bold = true, - Italic = true, AutoHeight = true, }; - signatureLabel.SetAnchorPreset(AnchorPresets.TopLeft, true); - _descriptionSignatureLabel = signatureLabel; - - var descriptionLabel = new Label(8, 0, Width - 16, 0) + _descriptionSignatureLabel.SetAnchorPreset(AnchorPresets.TopLeft, true); + + _descriptionLabel = new Label(32, 0, Width - 40, 0) { Parent = _descriptionPanel, HorizontalAlignment = TextAlignment.Near, VerticalAlignment = TextAlignment.Near, Wrapping = TextWrapping.WrapWords, + Font = signatureFontReference, AutoHeight = true, }; - descriptionLabel.SetAnchorPreset(AnchorPresets.TopLeft, true); - _descriptionLabel = descriptionLabel; + _descriptionLabel.SetAnchorPreset(AnchorPresets.TopLeft, true); } // Init groups @@ -597,20 +622,44 @@ namespace FlaxEditor.Surface.ContextMenu _groups[i].Open(animate); } - public void SetDescriptionText(string header, string text) + /// + /// Updates the description panel and shows information about the set archetype + /// + /// The node archetype + public void SetDescriptionPanelArchetype(NodeArchetype archetype) { if(!_useDescriptionPanel) return; + + if (archetype == null) + { + HideDescriptionPanel(); + return; + } - _descriptionSignatureLabel.Text = header; - var panelHeight = _descriptionSignatureLabel.Height; + Profiler.BeginEvent("VisjectCM.SetDescriptionPanelArchetype"); + + _descriptionSignatureLabel.Text = archetype.Signature; + float panelHeight = _descriptionSignatureLabel.Height; - _descriptionLabel.Y = _descriptionSignatureLabel.Bounds.Bottom + 8f; - _descriptionLabel.Text = text; + _descriptionLabel.Y = _descriptionSignatureLabel.Bounds.Bottom + 6f; + _descriptionLabel.Text = archetype.Description; - panelHeight += _descriptionLabel.Height + 8f + 24f; + panelHeight += _descriptionLabel.Height + 6f + 18f; + _descriptionPanel.Height = panelHeight; - Size = new Float2(300, 400 + _descriptionPanel.Height); + Height = 400 + Mathf.RoundToInt(_descriptionPanel.Height); + UpdateWindowSize(); + + Profiler.EndEvent(); + } + + /// + /// Hides the description panel and resets the context menu to its original size + /// + public void HideDescriptionPanel() + { + Height = 400; UpdateWindowSize(); } diff --git a/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs b/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs index 8d9fceba7..c0fba5586 100644 --- a/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs +++ b/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs @@ -315,6 +315,14 @@ namespace FlaxEditor.Surface.ContextMenu } } + /// + /// Callback when selected by the visject CM + /// + public void OnSelect() + { + Group.ContextMenu.SetDescriptionPanelArchetype(_archetype); + } + /// public override bool OnMouseDown(Float2 location, MouseButton button) { @@ -342,7 +350,7 @@ namespace FlaxEditor.Surface.ContextMenu public override void OnMouseEnter(Float2 location) { base.OnMouseEnter(location); - Group.ContextMenu.SetDescriptionText(_archetype.Signature, _archetype.Description); + Group.ContextMenu.SetDescriptionPanelArchetype(_archetype); } /// diff --git a/Source/Editor/Surface/VisjectSurface.ContextMenu.cs b/Source/Editor/Surface/VisjectSurface.ContextMenu.cs index 54f4e14e6..604394769 100644 --- a/Source/Editor/Surface/VisjectSurface.ContextMenu.cs +++ b/Source/Editor/Surface/VisjectSurface.ContextMenu.cs @@ -243,6 +243,7 @@ namespace FlaxEditor.Surface ParametersGetter = () => Parameters, CustomNodesGroup = GetCustomNodes(), ParameterGetNodeArchetype = GetParameterGetterNodeArchetype(out _), + Style = Style, }); } From 99c10e5ed3c6037c751e4d2227941900c3978062 Mon Sep 17 00:00:00 2001 From: Nils Hausfeld Date: Mon, 10 Jun 2024 23:14:24 +0200 Subject: [PATCH 06/51] - Now correctly fetching signature and description for properties - Minor code cleanup --- .../Editor/Surface/ContextMenu/VisjectCM.cs | 19 ++++++++++++++--- Source/Editor/Surface/SurfaceUtils.cs | 21 ++++++++++++++++--- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/Source/Editor/Surface/ContextMenu/VisjectCM.cs b/Source/Editor/Surface/ContextMenu/VisjectCM.cs index ce2b5d12b..2844d16b0 100644 --- a/Source/Editor/Surface/ContextMenu/VisjectCM.cs +++ b/Source/Editor/Surface/ContextMenu/VisjectCM.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Linq; using FlaxEditor.GUI.ContextMenu; using FlaxEditor.GUI.Input; +using FlaxEditor.Scripting; using FlaxEngine; using FlaxEngine.GUI; using FlaxEngine.Utilities; @@ -638,15 +639,27 @@ namespace FlaxEditor.Surface.ContextMenu } Profiler.BeginEvent("VisjectCM.SetDescriptionPanelArchetype"); - - _descriptionSignatureLabel.Text = archetype.Signature; + + if (archetype.Tag is ScriptMemberInfo memberInfo) + { + var name = memberInfo.Name; + if (memberInfo.IsMethod && memberInfo.Name.StartsWith("get_") || memberInfo.Name.StartsWith("set_")) + { + name = memberInfo.Name.Substring(4); + } + + _descriptionSignatureLabel.Text = memberInfo.DeclaringType + "." + name; + } + else + _descriptionSignatureLabel.Text = archetype.Signature; + float panelHeight = _descriptionSignatureLabel.Height; _descriptionLabel.Y = _descriptionSignatureLabel.Bounds.Bottom + 6f; _descriptionLabel.Text = archetype.Description; panelHeight += _descriptionLabel.Height + 6f + 18f; - + _descriptionPanel.Height = panelHeight; Height = 400 + Mathf.RoundToInt(_descriptionPanel.Height); UpdateWindowSize(); diff --git a/Source/Editor/Surface/SurfaceUtils.cs b/Source/Editor/Surface/SurfaceUtils.cs index 936aa52eb..8e14787b6 100644 --- a/Source/Editor/Surface/SurfaceUtils.cs +++ b/Source/Editor/Surface/SurfaceUtils.cs @@ -440,7 +440,7 @@ namespace FlaxEditor.Surface return sb.ToString(); } - internal static string GetVisualScriptMemberInfoSignature(ScriptMemberInfo member, bool appendPropertyInfo = true) + internal static string GetVisualScriptMemberInfoSignature(ScriptMemberInfo member) { var name = member.Name; var declaringType = member.DeclaringType; @@ -454,7 +454,7 @@ namespace FlaxEditor.Surface var property = declaringType.GetMembers(name.Substring(4), MemberTypes.Property, flags); if (property != null && property.Length != 0) { - return GetVisualScriptMemberInfoDescription(property[0]); + return GetVisualScriptMemberInfoSignature(property[0]); } } @@ -483,7 +483,7 @@ namespace FlaxEditor.Surface } sb.Append(')'); } - else if (member.IsProperty && appendPropertyInfo) + else if (member.IsProperty) { sb.Append(' '); sb.Append('{'); @@ -500,6 +500,21 @@ namespace FlaxEditor.Surface internal static string GetVisualScriptMemberShortDescription(ScriptMemberInfo member) { + var name = member.Name; + var declaringType = member.DeclaringType; + + // Getter/setter method of the property - we can return early here + bool isGetterOrSetter = name.StartsWith("get_") || name.StartsWith("set_"); + if (member.IsMethod && isGetterOrSetter) + { + var flags = member.IsStatic ? BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly : BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly; + var property = declaringType.GetMembers(name.Substring(4), MemberTypes.Property, flags); + if (property != null && property.Length != 0) + { + return GetVisualScriptMemberShortDescription(property[0]); + } + } + return Editor.Instance.CodeDocs.GetTooltip(member); } From 5059cef0654fdcee63477828399506a28ac03445 Mon Sep 17 00:00:00 2001 From: Nils Hausfeld Date: Mon, 10 Jun 2024 23:24:34 +0200 Subject: [PATCH 07/51] - Description panel declaring type icon now updates its color --- Source/Editor/Surface/ContextMenu/VisjectCM.cs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/Source/Editor/Surface/ContextMenu/VisjectCM.cs b/Source/Editor/Surface/ContextMenu/VisjectCM.cs index 2844d16b0..00afa803d 100644 --- a/Source/Editor/Surface/ContextMenu/VisjectCM.cs +++ b/Source/Editor/Surface/ContextMenu/VisjectCM.cs @@ -59,6 +59,7 @@ namespace FlaxEditor.Surface.ContextMenu private readonly Image _descriptionClassImage; private readonly Label _descriptionSignatureLabel; private readonly Label _descriptionLabel; + private readonly SurfaceStyle _surfaceStyle; private VisjectCMItem _selectedItem; @@ -157,6 +158,7 @@ namespace FlaxEditor.Surface.ContextMenu if (info.CanSetParameters) _parameterSetNodeArchetype = info.ParameterSetNodeArchetype ?? Archetypes.Parameters.Nodes[3]; _useDescriptionPanel = info.UseDescriptionPanel; + _surfaceStyle = info.Style; // Context menu dimensions Size = new Float2(300, 400); @@ -639,7 +641,8 @@ namespace FlaxEditor.Surface.ContextMenu } Profiler.BeginEvent("VisjectCM.SetDescriptionPanelArchetype"); - + + ScriptType declaringType; if (archetype.Tag is ScriptMemberInfo memberInfo) { var name = memberInfo.Name; @@ -647,12 +650,20 @@ namespace FlaxEditor.Surface.ContextMenu { name = memberInfo.Name.Substring(4); } - + + declaringType = memberInfo.DeclaringType; _descriptionSignatureLabel.Text = memberInfo.DeclaringType + "." + name; } else + { _descriptionSignatureLabel.Text = archetype.Signature; + declaringType = archetype.DefaultType; + } + _surfaceStyle.GetConnectionColor(declaringType, archetype.ConnectionsHints, out var typeColor); + _descriptionClassImage.Color = typeColor; + _descriptionClassImage.MouseOverColor = typeColor; + float panelHeight = _descriptionSignatureLabel.Height; _descriptionLabel.Y = _descriptionSignatureLabel.Bounds.Bottom + 6f; From df404507b59170a8115a37e26f2ae2f40e1143fb Mon Sep 17 00:00:00 2001 From: Nils Hausfeld Date: Wed, 12 Jun 2024 19:20:09 +0200 Subject: [PATCH 08/51] - Now showing inputs and outputs in a very buggy and dirty way --- .../Editor/Surface/ContextMenu/VisjectCM.cs | 98 ++++++++++++++++++- 1 file changed, 97 insertions(+), 1 deletion(-) diff --git a/Source/Editor/Surface/ContextMenu/VisjectCM.cs b/Source/Editor/Surface/ContextMenu/VisjectCM.cs index 00afa803d..0a85e7bdf 100644 --- a/Source/Editor/Surface/ContextMenu/VisjectCM.cs +++ b/Source/Editor/Surface/ContextMenu/VisjectCM.cs @@ -60,6 +60,8 @@ namespace FlaxEditor.Surface.ContextMenu private readonly Label _descriptionSignatureLabel; private readonly Label _descriptionLabel; private readonly SurfaceStyle _surfaceStyle; + private readonly VerticalPanel _descriptionInputPanel; + private readonly VerticalPanel _descriptionOutputPanel; private VisjectCMItem _selectedItem; @@ -276,6 +278,22 @@ namespace FlaxEditor.Surface.ContextMenu AutoHeight = true, }; _descriptionLabel.SetAnchorPreset(AnchorPresets.TopLeft, true); + + _descriptionInputPanel = new VerticalPanel() + { + Parent = _descriptionPanel, + Width = Width * 0.5f, + AnchorPreset = AnchorPresets.TopLeft, + AutoSize = true, + }; + + _descriptionOutputPanel = new VerticalPanel() + { + Parent = _descriptionPanel, + X = Width * 0.5f, + Width = Width * 0.5f, + AutoSize = true, + }; } // Init groups @@ -643,6 +661,10 @@ namespace FlaxEditor.Surface.ContextMenu Profiler.BeginEvent("VisjectCM.SetDescriptionPanelArchetype"); ScriptType declaringType; + + _descriptionInputPanel.RemoveChildren(); + _descriptionOutputPanel.RemoveChildren(); + if (archetype.Tag is ScriptMemberInfo memberInfo) { var name = memberInfo.Name; @@ -652,12 +674,80 @@ namespace FlaxEditor.Surface.ContextMenu } declaringType = memberInfo.DeclaringType; - _descriptionSignatureLabel.Text = memberInfo.DeclaringType + "." + name; + _descriptionSignatureLabel.Text = memberInfo.DeclaringType + "." + name; + + if(!memberInfo.IsStatic) + _descriptionInputPanel.AddChild(new Label(0,0,100, 16) + { + Text = $">Instance ({memberInfo.DeclaringType.Name})", + HorizontalAlignment = TextAlignment.Near, + VerticalAlignment = TextAlignment.Near, + Wrapping = TextWrapping.NoWrap, + }).SetAnchorPreset(AnchorPresets.TopLeft, true); + + if (memberInfo.ValueType != ScriptType.Null || memberInfo.ValueType != ScriptType.Void) + { + _descriptionOutputPanel.AddChild(new Label(0,0,100, 16) + { + Text = $">Return ({memberInfo.ValueType.Name})", + HorizontalAlignment = TextAlignment.Near, + VerticalAlignment = TextAlignment.Near, + Wrapping = TextWrapping.NoWrap, + }).SetAnchorPreset(AnchorPresets.TopLeft, true); + } + + for(int i = 0; i < memberInfo.ParametersCount; i++) + { + var param = memberInfo.GetParameters()[i]; + if (param.IsOut) + { + _descriptionOutputPanel.AddChild(new Label(0,0,100, 16) + { + Text = $"{param.Name} ({param.Type.Name})", + HorizontalAlignment = TextAlignment.Near, + VerticalAlignment = TextAlignment.Near, + Wrapping = TextWrapping.NoWrap, + }).SetAnchorPreset(AnchorPresets.TopLeft, true); + + continue; + } + _descriptionInputPanel.AddChild(new Label(0,0,100, 16) + { + Text = $"{param.Name} ({param.Type.Name})", + HorizontalAlignment = TextAlignment.Near, + VerticalAlignment = TextAlignment.Near, + Wrapping = TextWrapping.NoWrap, + }).SetAnchorPreset(AnchorPresets.TopLeft, true); + } } else { _descriptionSignatureLabel.Text = archetype.Signature; declaringType = archetype.DefaultType; + + foreach (var element in archetype.Elements) + { + if (element.Type == NodeElementType.Input) + { + _descriptionInputPanel.AddChild(new Label(0,0,100, 16) + { + Text = element.Text, + HorizontalAlignment = TextAlignment.Near, + VerticalAlignment = TextAlignment.Near, + Wrapping = TextWrapping.NoWrap, + }).SetAnchorPreset(AnchorPresets.TopLeft, true); + } + else if (element.Type == NodeElementType.Output) + { + _descriptionOutputPanel.AddChild(new Label(0,0,100, 16) + { + Text = element.Text, + HorizontalAlignment = TextAlignment.Near, + VerticalAlignment = TextAlignment.Near, + Wrapping = TextWrapping.NoWrap, + }).SetAnchorPreset(AnchorPresets.TopLeft, true); + } + } } _surfaceStyle.GetConnectionColor(declaringType, archetype.ConnectionsHints, out var typeColor); @@ -671,10 +761,16 @@ namespace FlaxEditor.Surface.ContextMenu panelHeight += _descriptionLabel.Height + 6f + 18f; + _descriptionInputPanel.Y = panelHeight; + _descriptionOutputPanel.Y = panelHeight; + + panelHeight += Mathf.Max(_descriptionInputPanel.Height, _descriptionOutputPanel.Height); _descriptionPanel.Height = panelHeight; Height = 400 + Mathf.RoundToInt(_descriptionPanel.Height); UpdateWindowSize(); + PerformLayout(); + Profiler.EndEvent(); } From 1be136bd2e087cf16604b7446c388458cac3ace0 Mon Sep 17 00:00:00 2001 From: Nils Hausfeld Date: Wed, 12 Jun 2024 21:07:35 +0200 Subject: [PATCH 09/51] - Now drawing icon type for inputs/outputs for archetypes with their attached memberinfo --- .../Editor/Surface/ContextMenu/VisjectCM.cs | 48 ++++++++++++++++--- 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/Source/Editor/Surface/ContextMenu/VisjectCM.cs b/Source/Editor/Surface/ContextMenu/VisjectCM.cs index 0a85e7bdf..b2b7507d5 100644 --- a/Source/Editor/Surface/ContextMenu/VisjectCM.cs +++ b/Source/Editor/Surface/ContextMenu/VisjectCM.cs @@ -661,10 +661,12 @@ namespace FlaxEditor.Surface.ContextMenu Profiler.BeginEvent("VisjectCM.SetDescriptionPanelArchetype"); ScriptType declaringType; + Color typeColor; _descriptionInputPanel.RemoveChildren(); _descriptionOutputPanel.RemoveChildren(); + var spriteHandle = _surfaceStyle.Icons.BoxOpen; if (archetype.Tag is ScriptMemberInfo memberInfo) { var name = memberInfo.Name; @@ -675,8 +677,17 @@ namespace FlaxEditor.Surface.ContextMenu declaringType = memberInfo.DeclaringType; _descriptionSignatureLabel.Text = memberInfo.DeclaringType + "." + name; - - if(!memberInfo.IsStatic) + + if (!memberInfo.IsStatic) + { + _surfaceStyle.GetConnectionColor(declaringType, archetype.ConnectionsHints, out typeColor); + _descriptionInputPanel.AddChild(new Image(2, 0, 12, 12) + { + Brush = new SpriteBrush(spriteHandle), + Color = typeColor, + MouseOverColor = typeColor, + AutoFocus = false, + }).SetAnchorPreset(AnchorPresets.TopLeft, true); _descriptionInputPanel.AddChild(new Label(0,0,100, 16) { Text = $">Instance ({memberInfo.DeclaringType.Name})", @@ -684,9 +695,18 @@ namespace FlaxEditor.Surface.ContextMenu VerticalAlignment = TextAlignment.Near, Wrapping = TextWrapping.NoWrap, }).SetAnchorPreset(AnchorPresets.TopLeft, true); + } - if (memberInfo.ValueType != ScriptType.Null || memberInfo.ValueType != ScriptType.Void) + if (memberInfo.ValueType != ScriptType.Null && memberInfo.ValueType != ScriptType.Void) { + _surfaceStyle.GetConnectionColor(memberInfo.ValueType, archetype.ConnectionsHints, out typeColor); + _descriptionOutputPanel.AddChild(new Image(2, 0, 12, 12) + { + Brush = new SpriteBrush(spriteHandle), + Color = typeColor, + MouseOverColor = typeColor, + AutoFocus = false, + }).SetAnchorPreset(AnchorPresets.TopLeft, true); _descriptionOutputPanel.AddChild(new Label(0,0,100, 16) { Text = $">Return ({memberInfo.ValueType.Name})", @@ -699,9 +719,17 @@ namespace FlaxEditor.Surface.ContextMenu for(int i = 0; i < memberInfo.ParametersCount; i++) { var param = memberInfo.GetParameters()[i]; + _surfaceStyle.GetConnectionColor(param.Type, archetype.ConnectionsHints, out typeColor); if (param.IsOut) { - _descriptionOutputPanel.AddChild(new Label(0,0,100, 16) + _descriptionOutputPanel.AddChild(new Image(2, 0, 12, 12) + { + Brush = new SpriteBrush(spriteHandle), + Color = typeColor, + MouseOverColor = typeColor, + AutoFocus = false, + }).SetAnchorPreset(AnchorPresets.TopLeft, true); + _descriptionOutputPanel.AddChild(new Label(12,0,100, 16) { Text = $"{param.Name} ({param.Type.Name})", HorizontalAlignment = TextAlignment.Near, @@ -711,7 +739,15 @@ namespace FlaxEditor.Surface.ContextMenu continue; } - _descriptionInputPanel.AddChild(new Label(0,0,100, 16) + + _descriptionInputPanel.AddChild(new Image(2, 0, 12, 12) + { + Brush = new SpriteBrush(spriteHandle), + Color = typeColor, + MouseOverColor = typeColor, + AutoFocus = false, + }).SetAnchorPreset(AnchorPresets.TopLeft, true); + _descriptionInputPanel.AddChild(new Label(12,0,100, 16) { Text = $"{param.Name} ({param.Type.Name})", HorizontalAlignment = TextAlignment.Near, @@ -750,7 +786,7 @@ namespace FlaxEditor.Surface.ContextMenu } } - _surfaceStyle.GetConnectionColor(declaringType, archetype.ConnectionsHints, out var typeColor); + _surfaceStyle.GetConnectionColor(declaringType, archetype.ConnectionsHints, out typeColor); _descriptionClassImage.Color = typeColor; _descriptionClassImage.MouseOverColor = typeColor; From 36bdd6cbd07c24b78cf89df299575aa377c76554 Mon Sep 17 00:00:00 2001 From: Nils Hausfeld Date: Thu, 13 Jun 2024 19:04:46 +0200 Subject: [PATCH 10/51] - Refactored some code handling the input/output elements - Added member information to all cached nodes to be able to fetch their informations --- .../Editor/Surface/ContextMenu/VisjectCM.cs | 144 +++++++++--------- Source/Editor/Surface/VisualScriptSurface.cs | 4 + 2 files changed, 76 insertions(+), 72 deletions(-) diff --git a/Source/Editor/Surface/ContextMenu/VisjectCM.cs b/Source/Editor/Surface/ContextMenu/VisjectCM.cs index b2b7507d5..e386fa668 100644 --- a/Source/Editor/Surface/ContextMenu/VisjectCM.cs +++ b/Source/Editor/Surface/ContextMenu/VisjectCM.cs @@ -667,6 +667,7 @@ namespace FlaxEditor.Surface.ContextMenu _descriptionOutputPanel.RemoveChildren(); var spriteHandle = _surfaceStyle.Icons.BoxOpen; + if (archetype.Tag is ScriptMemberInfo memberInfo) { var name = memberInfo.Name; @@ -681,39 +682,13 @@ namespace FlaxEditor.Surface.ContextMenu if (!memberInfo.IsStatic) { _surfaceStyle.GetConnectionColor(declaringType, archetype.ConnectionsHints, out typeColor); - _descriptionInputPanel.AddChild(new Image(2, 0, 12, 12) - { - Brush = new SpriteBrush(spriteHandle), - Color = typeColor, - MouseOverColor = typeColor, - AutoFocus = false, - }).SetAnchorPreset(AnchorPresets.TopLeft, true); - _descriptionInputPanel.AddChild(new Label(0,0,100, 16) - { - Text = $">Instance ({memberInfo.DeclaringType.Name})", - HorizontalAlignment = TextAlignment.Near, - VerticalAlignment = TextAlignment.Near, - Wrapping = TextWrapping.NoWrap, - }).SetAnchorPreset(AnchorPresets.TopLeft, true); + AddInputElement(spriteHandle, typeColor, $">Instance ({memberInfo.DeclaringType.Name})"); } if (memberInfo.ValueType != ScriptType.Null && memberInfo.ValueType != ScriptType.Void) { _surfaceStyle.GetConnectionColor(memberInfo.ValueType, archetype.ConnectionsHints, out typeColor); - _descriptionOutputPanel.AddChild(new Image(2, 0, 12, 12) - { - Brush = new SpriteBrush(spriteHandle), - Color = typeColor, - MouseOverColor = typeColor, - AutoFocus = false, - }).SetAnchorPreset(AnchorPresets.TopLeft, true); - _descriptionOutputPanel.AddChild(new Label(0,0,100, 16) - { - Text = $">Return ({memberInfo.ValueType.Name})", - HorizontalAlignment = TextAlignment.Near, - VerticalAlignment = TextAlignment.Near, - Wrapping = TextWrapping.NoWrap, - }).SetAnchorPreset(AnchorPresets.TopLeft, true); + AddOutputElement(spriteHandle, typeColor, $">Return ({memberInfo.ValueType.Name})"); } for(int i = 0; i < memberInfo.ParametersCount; i++) @@ -722,38 +697,11 @@ namespace FlaxEditor.Surface.ContextMenu _surfaceStyle.GetConnectionColor(param.Type, archetype.ConnectionsHints, out typeColor); if (param.IsOut) { - _descriptionOutputPanel.AddChild(new Image(2, 0, 12, 12) - { - Brush = new SpriteBrush(spriteHandle), - Color = typeColor, - MouseOverColor = typeColor, - AutoFocus = false, - }).SetAnchorPreset(AnchorPresets.TopLeft, true); - _descriptionOutputPanel.AddChild(new Label(12,0,100, 16) - { - Text = $"{param.Name} ({param.Type.Name})", - HorizontalAlignment = TextAlignment.Near, - VerticalAlignment = TextAlignment.Near, - Wrapping = TextWrapping.NoWrap, - }).SetAnchorPreset(AnchorPresets.TopLeft, true); - + AddOutputElement(spriteHandle, typeColor, $"{param.Name} ({param.Type.Name})"); continue; } - - _descriptionInputPanel.AddChild(new Image(2, 0, 12, 12) - { - Brush = new SpriteBrush(spriteHandle), - Color = typeColor, - MouseOverColor = typeColor, - AutoFocus = false, - }).SetAnchorPreset(AnchorPresets.TopLeft, true); - _descriptionInputPanel.AddChild(new Label(12,0,100, 16) - { - Text = $"{param.Name} ({param.Type.Name})", - HorizontalAlignment = TextAlignment.Near, - VerticalAlignment = TextAlignment.Near, - Wrapping = TextWrapping.NoWrap, - }).SetAnchorPreset(AnchorPresets.TopLeft, true); + + AddInputElement(spriteHandle, typeColor, $"{param.Name} ({param.Type.Name})"); } } else @@ -761,27 +709,18 @@ namespace FlaxEditor.Surface.ContextMenu _descriptionSignatureLabel.Text = archetype.Signature; declaringType = archetype.DefaultType; + Debug.Log(archetype.Elements); foreach (var element in archetype.Elements) { if (element.Type == NodeElementType.Input) { - _descriptionInputPanel.AddChild(new Label(0,0,100, 16) - { - Text = element.Text, - HorizontalAlignment = TextAlignment.Near, - VerticalAlignment = TextAlignment.Near, - Wrapping = TextWrapping.NoWrap, - }).SetAnchorPreset(AnchorPresets.TopLeft, true); + _surfaceStyle.GetConnectionColor(element.ConnectionsType, archetype.ConnectionsHints, out typeColor); + AddInputElement(spriteHandle, typeColor, element.Text); } else if (element.Type == NodeElementType.Output) { - _descriptionOutputPanel.AddChild(new Label(0,0,100, 16) - { - Text = element.Text, - HorizontalAlignment = TextAlignment.Near, - VerticalAlignment = TextAlignment.Near, - Wrapping = TextWrapping.NoWrap, - }).SetAnchorPreset(AnchorPresets.TopLeft, true); + _surfaceStyle.GetConnectionColor(element.ConnectionsType, archetype.ConnectionsHints, out typeColor); + AddOutputElement(spriteHandle, typeColor, element.Text); } } } @@ -810,6 +749,67 @@ namespace FlaxEditor.Surface.ContextMenu Profiler.EndEvent(); } + private void AddInputElement(SpriteHandle sprite, Color typeColor, string text) + { + var elementPanel = new Panel() + { + Width = Width * 0.5f, + Height = 16, + Parent = _descriptionInputPanel, + AnchorPreset = AnchorPresets.TopLeft + }; + + elementPanel.AddChild(new Image(2, 0, 12, 12) + { + Brush = new SpriteBrush(sprite), + Color = typeColor, + MouseOverColor = typeColor, + AutoFocus = false, + }).SetAnchorPreset(AnchorPresets.TopLeft, true); + + var elementText = new Label(16, 0, Width * 0.5f - 32, 16) + { + Text = text, + HorizontalAlignment = TextAlignment.Near, + VerticalAlignment = TextAlignment.Near, + Wrapping = TextWrapping.WrapWords, + AutoHeight = true, + }; + elementText.SetAnchorPreset(AnchorPresets.TopLeft, true); + elementPanel.AddChild(elementText); + elementPanel.Height = elementText.Height; + } + + private void AddOutputElement(SpriteHandle sprite, Color typeColor, string text) + { + var elementPanel = new Panel() + { + Width = Width * 0.5f, + Height = 16, + Parent = _descriptionOutputPanel, + AnchorPreset = AnchorPresets.TopLeft + }; + + elementPanel.AddChild(new Image(2, 0, 12, 12) + { + Brush = new SpriteBrush(sprite), + Color = typeColor, + MouseOverColor = typeColor, + AutoFocus = false, + }).SetAnchorPreset(AnchorPresets.TopLeft, true); + + var elementText = new Label(16, 0, Width * 0.5f - 32, 16) + { + Text = text, + HorizontalAlignment = TextAlignment.Near, + VerticalAlignment = TextAlignment.Near, + Wrapping = TextWrapping.NoWrap, + }; + elementText.SetAnchorPreset(AnchorPresets.TopLeft, true); + elementPanel.AddChild(elementText); + elementPanel.Height = elementText.Height; + } + /// /// Hides the description panel and resets the context menu to its original size /// diff --git a/Source/Editor/Surface/VisualScriptSurface.cs b/Source/Editor/Surface/VisualScriptSurface.cs index 39a705ff9..7ee3a381b 100644 --- a/Source/Editor/Surface/VisualScriptSurface.cs +++ b/Source/Editor/Surface/VisualScriptSurface.cs @@ -422,6 +422,7 @@ namespace FlaxEditor.Surface node.Signature = SurfaceUtils.GetVisualScriptMemberInfoSignature(member); node.Description = SurfaceUtils.GetVisualScriptMemberShortDescription(member); node.SubTitle = string.Format(" (in {0})", scriptTypeName); + node.Tag = member; // Create group archetype var groupKey = new KeyValuePair(scriptTypeName, 16); @@ -457,6 +458,7 @@ namespace FlaxEditor.Surface node.Signature = SurfaceUtils.GetVisualScriptMemberInfoSignature(member); node.Description = SurfaceUtils.GetVisualScriptMemberShortDescription(member); node.SubTitle = string.Format(" (in {0})", scriptTypeName); + node.Tag = member; // Create group archetype var groupKey = new KeyValuePair(scriptTypeName, 16); @@ -516,6 +518,7 @@ namespace FlaxEditor.Surface bindNode.Signature = SurfaceUtils.GetVisualScriptMemberInfoSignature(member); bindNode.Description = SurfaceUtils.GetVisualScriptMemberShortDescription(member); bindNode.SubTitle = string.Format(" (in {0})", scriptTypeName); + bindNode.Tag = member; ((IList)group.Archetypes).Add(bindNode); // Add Unbind event node @@ -527,6 +530,7 @@ namespace FlaxEditor.Surface unbindNode.Signature = bindNode.Signature; unbindNode.Description = bindNode.Description; unbindNode.SubTitle = bindNode.SubTitle; + unbindNode.Tag = member; ((IList)group.Archetypes).Add(unbindNode); #if DEBUG_EVENTS_SEARCHING From 67f3f89bf76b2eb1d91d0b70e3c4c65fb73717fa Mon Sep 17 00:00:00 2001 From: Nils Hausfeld Date: Thu, 13 Jun 2024 22:03:41 +0200 Subject: [PATCH 11/51] - Override node inputs/outputs now also get shown - Added special treatment for enum, pack and unpack nodes in order to also show their inputs/outputs --- .../Editor/Surface/ContextMenu/VisjectCM.cs | 69 ++++++++++++++++--- Source/Editor/Surface/VisualScriptSurface.cs | 1 + 2 files changed, 60 insertions(+), 10 deletions(-) diff --git a/Source/Editor/Surface/ContextMenu/VisjectCM.cs b/Source/Editor/Surface/ContextMenu/VisjectCM.cs index e386fa668..15e1448b0 100644 --- a/Source/Editor/Surface/ContextMenu/VisjectCM.cs +++ b/Source/Editor/Surface/ContextMenu/VisjectCM.cs @@ -2,7 +2,9 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; +using System.Reflection; using FlaxEditor.GUI.ContextMenu; using FlaxEditor.GUI.Input; using FlaxEditor.Scripting; @@ -688,7 +690,10 @@ namespace FlaxEditor.Surface.ContextMenu if (memberInfo.ValueType != ScriptType.Null && memberInfo.ValueType != ScriptType.Void) { _surfaceStyle.GetConnectionColor(memberInfo.ValueType, archetype.ConnectionsHints, out typeColor); - AddOutputElement(spriteHandle, typeColor, $">Return ({memberInfo.ValueType.Name})"); + if (memberInfo.IsField && archetype.Title.StartsWith("Set ")) + AddInputElement(spriteHandle, typeColor, $"({memberInfo.ValueType.Name})"); + else + AddOutputElement(spriteHandle, typeColor, $">Return ({memberInfo.ValueType.Name})"); } for(int i = 0; i < memberInfo.ParametersCount; i++) @@ -708,19 +713,63 @@ namespace FlaxEditor.Surface.ContextMenu { _descriptionSignatureLabel.Text = archetype.Signature; declaringType = archetype.DefaultType; - - Debug.Log(archetype.Elements); - foreach (var element in archetype.Elements) + + // Special handling for Pack nodes + if (archetype.TypeID == 26) { - if (element.Type == NodeElementType.Input) + var outputType = TypeUtils.GetType((string)archetype.DefaultValues[0]); + _surfaceStyle.GetConnectionColor(outputType, archetype.ConnectionsHints, out typeColor); + AddOutputElement(spriteHandle, typeColor, $"{outputType.Name}"); + + var fields = outputType.GetMembers(BindingFlags.Public | BindingFlags.Instance).Where(x => x.IsField).ToArray(); + var fieldsLength = fields.Length; + for (var i = 0; i < fieldsLength; i++) { - _surfaceStyle.GetConnectionColor(element.ConnectionsType, archetype.ConnectionsHints, out typeColor); - AddInputElement(spriteHandle, typeColor, element.Text); + var field = fields[i]; + _surfaceStyle.GetConnectionColor(field.ValueType, archetype.ConnectionsHints, out typeColor); + AddInputElement(spriteHandle, typeColor, $"{field.Name} ({field.ValueType.Name})"); } - else if (element.Type == NodeElementType.Output) + } + else if (archetype.TypeID == 36) + { + var inputType = TypeUtils.GetType((string)archetype.DefaultValues[0]); + _surfaceStyle.GetConnectionColor(inputType, archetype.ConnectionsHints, out typeColor); + AddInputElement(spriteHandle, typeColor, $"{inputType.Name}"); + + var fields = inputType.GetMembers(BindingFlags.Public | BindingFlags.Instance).Where(x => x.IsField).ToArray(); + var fieldsLength = fields.Length; + for (var i = 0; i < fieldsLength; i++) { - _surfaceStyle.GetConnectionColor(element.ConnectionsType, archetype.ConnectionsHints, out typeColor); - AddOutputElement(spriteHandle, typeColor, element.Text); + var field = fields[i]; + _surfaceStyle.GetConnectionColor(field.ValueType, archetype.ConnectionsHints, out typeColor); + AddOutputElement(spriteHandle, typeColor, $"{field.Name} ({field.ValueType.Name})"); + } + } + else + { + foreach (var element in archetype.Elements) + { + if (element.Type == NodeElementType.Input) + { + _surfaceStyle.GetConnectionColor(element.ConnectionsType, archetype.ConnectionsHints, out typeColor); + AddInputElement(spriteHandle, typeColor, $"{element.Text} ({element.Type.ToString()})"); + } + else if (element.Type == NodeElementType.Output) + { + // TODO: better check for enums + switch (archetype.TypeID) + { + case 11: + var t = new ScriptType(archetype.DefaultValues[0].GetType()); + _surfaceStyle.GetConnectionColor(t, archetype.ConnectionsHints, out typeColor); + AddOutputElement(spriteHandle, typeColor, $"{t.Name}"); + break; + default: + _surfaceStyle.GetConnectionColor(element.ConnectionsType, archetype.ConnectionsHints, out typeColor); + AddOutputElement(spriteHandle, typeColor, $"{element.Text} ({element.Type.ToString()})"); + break; + } + } } } } diff --git a/Source/Editor/Surface/VisualScriptSurface.cs b/Source/Editor/Surface/VisualScriptSurface.cs index 7ee3a381b..f7fafeef8 100644 --- a/Source/Editor/Surface/VisualScriptSurface.cs +++ b/Source/Editor/Surface/VisualScriptSurface.cs @@ -242,6 +242,7 @@ namespace FlaxEditor.Surface node.DefaultValues[0] = name; node.DefaultValues[1] = parameters.Length; node.Title = "Override " + name; + node.Tag = member; nodes.Add(node); } } From 804e652b6d0441b7a5914062ac24ae436a4ab49e Mon Sep 17 00:00:00 2001 From: Nils Hausfeld Date: Fri, 14 Jun 2024 20:39:39 +0200 Subject: [PATCH 12/51] - Now using the connectionhints when no connectionstype is available - Some special treatment for Array and Dictionary Constants, kinda dirty --- .../Editor/Surface/ContextMenu/VisjectCM.cs | 46 +++++++++++++++---- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/Source/Editor/Surface/ContextMenu/VisjectCM.cs b/Source/Editor/Surface/ContextMenu/VisjectCM.cs index 15e1448b0..80fb4ecb6 100644 --- a/Source/Editor/Surface/ContextMenu/VisjectCM.cs +++ b/Source/Editor/Surface/ContextMenu/VisjectCM.cs @@ -8,6 +8,7 @@ using System.Reflection; using FlaxEditor.GUI.ContextMenu; using FlaxEditor.GUI.Input; using FlaxEditor.Scripting; +using FlaxEditor.Surface.Archetypes; using FlaxEngine; using FlaxEngine.GUI; using FlaxEngine.Utilities; @@ -702,7 +703,7 @@ namespace FlaxEditor.Surface.ContextMenu _surfaceStyle.GetConnectionColor(param.Type, archetype.ConnectionsHints, out typeColor); if (param.IsOut) { - AddOutputElement(spriteHandle, typeColor, $"{param.Name} ({param.Type.Name})"); + AddOutputElement(spriteHandle, typeColor, $">{param.Name} ({param.Type.Name})"); continue; } @@ -751,23 +752,48 @@ namespace FlaxEditor.Surface.ContextMenu { if (element.Type == NodeElementType.Input) { - _surfaceStyle.GetConnectionColor(element.ConnectionsType, archetype.ConnectionsHints, out typeColor); - AddInputElement(spriteHandle, typeColor, $"{element.Text} ({element.Type.ToString()})"); + var connectionsType = element.ConnectionsType; + _surfaceStyle.GetConnectionColor(connectionsType, archetype.ConnectionsHints, out typeColor); + + if (connectionsType == null) + { + if(archetype == Archetypes.Constants.Nodes[12]) + AddInputElement(spriteHandle, typeColor, $"-{element.Text} ({ConnectionsHint.Array.ToString()})"); + else if (archetype == Archetypes.Constants.Nodes[13]) + AddInputElement(spriteHandle, typeColor, $"-{element.Text} ({ConnectionsHint.Dictionary.ToString()})"); + else + AddInputElement(spriteHandle, typeColor, $"-{element.Text} ({archetype.ConnectionsHints.ToString()})"); + continue; + } + + AddInputElement(spriteHandle, typeColor, $"{element.Text} ({element.ConnectionsType.Name})"); } else if (element.Type == NodeElementType.Output) { // TODO: better check for enums - switch (archetype.TypeID) + if (archetype == Archetypes.Constants.Nodes[10]) { - case 11: var t = new ScriptType(archetype.DefaultValues[0].GetType()); _surfaceStyle.GetConnectionColor(t, archetype.ConnectionsHints, out typeColor); AddOutputElement(spriteHandle, typeColor, $"{t.Name}"); - break; - default: - _surfaceStyle.GetConnectionColor(element.ConnectionsType, archetype.ConnectionsHints, out typeColor); - AddOutputElement(spriteHandle, typeColor, $"{element.Text} ({element.Type.ToString()})"); - break; + } + else + { + var connectionsType = element.ConnectionsType; + _surfaceStyle.GetConnectionColor(connectionsType, archetype.ConnectionsHints, out typeColor); + + if (connectionsType == null) + { + if(archetype == Archetypes.Constants.Nodes[12]) + AddOutputElement(spriteHandle, typeColor, $"-{element.Text} ({ConnectionsHint.Array.ToString()})"); + else if (archetype == Archetypes.Constants.Nodes[13]) + AddOutputElement(spriteHandle, typeColor, $"-{element.Text} ({ConnectionsHint.Dictionary.ToString()})"); + else + AddOutputElement(spriteHandle, typeColor, $"-{element.Text} ({archetype.ConnectionsHints.ToString()})"); + continue; + } + + AddOutputElement(spriteHandle, typeColor, $"-{element.Text} ({connectionsType.Name})"); } } } From 46cc4c72e79240397a1dffcbd0909f98e531071e Mon Sep 17 00:00:00 2001 From: Nils Hausfeld Date: Sat, 15 Jun 2024 19:47:48 +0200 Subject: [PATCH 13/51] - Refactored and cleaned up a bunch of redundant code --- .../Editor/Surface/ContextMenu/VisjectCM.cs | 133 ++++-------------- 1 file changed, 29 insertions(+), 104 deletions(-) diff --git a/Source/Editor/Surface/ContextMenu/VisjectCM.cs b/Source/Editor/Surface/ContextMenu/VisjectCM.cs index 80fb4ecb6..a7737b4de 100644 --- a/Source/Editor/Surface/ContextMenu/VisjectCM.cs +++ b/Source/Editor/Surface/ContextMenu/VisjectCM.cs @@ -664,12 +664,11 @@ namespace FlaxEditor.Surface.ContextMenu Profiler.BeginEvent("VisjectCM.SetDescriptionPanelArchetype"); ScriptType declaringType; - Color typeColor; + string elementName, elementTypeName; _descriptionInputPanel.RemoveChildren(); _descriptionOutputPanel.RemoveChildren(); - var spriteHandle = _surfaceStyle.Icons.BoxOpen; if (archetype.Tag is ScriptMemberInfo memberInfo) { @@ -683,31 +682,26 @@ namespace FlaxEditor.Surface.ContextMenu _descriptionSignatureLabel.Text = memberInfo.DeclaringType + "." + name; if (!memberInfo.IsStatic) - { - _surfaceStyle.GetConnectionColor(declaringType, archetype.ConnectionsHints, out typeColor); - AddInputElement(spriteHandle, typeColor, $">Instance ({memberInfo.DeclaringType.Name})"); - } + AddInputOutputElement(archetype, declaringType, false, $">Instance ({memberInfo.DeclaringType.Name})"); if (memberInfo.ValueType != ScriptType.Null && memberInfo.ValueType != ScriptType.Void) { - _surfaceStyle.GetConnectionColor(memberInfo.ValueType, archetype.ConnectionsHints, out typeColor); if (memberInfo.IsField && archetype.Title.StartsWith("Set ")) - AddInputElement(spriteHandle, typeColor, $"({memberInfo.ValueType.Name})"); + AddInputOutputElement(archetype, memberInfo.ValueType, false, $"({memberInfo.ValueType.Name})"); else - AddOutputElement(spriteHandle, typeColor, $">Return ({memberInfo.ValueType.Name})"); + AddInputOutputElement(archetype, memberInfo.ValueType, true, $"Return ({memberInfo.ValueType.Name})"); } for(int i = 0; i < memberInfo.ParametersCount; i++) { var param = memberInfo.GetParameters()[i]; - _surfaceStyle.GetConnectionColor(param.Type, archetype.ConnectionsHints, out typeColor); if (param.IsOut) { - AddOutputElement(spriteHandle, typeColor, $">{param.Name} ({param.Type.Name})"); + AddInputOutputElement(archetype, param.Type, true, $">{param.Name} ({param.Type.Name})"); continue; } - AddInputElement(spriteHandle, typeColor, $"{param.Name} ({param.Type.Name})"); + AddInputOutputElement(archetype, param.Type, false, $">{param.Name} ({param.Type.Name})"); } } else @@ -716,93 +710,52 @@ namespace FlaxEditor.Surface.ContextMenu declaringType = archetype.DefaultType; // Special handling for Pack nodes - if (archetype.TypeID == 26) + if (archetype == Packing.Nodes[6] || archetype == Packing.Nodes[13]) { - var outputType = TypeUtils.GetType((string)archetype.DefaultValues[0]); - _surfaceStyle.GetConnectionColor(outputType, archetype.ConnectionsHints, out typeColor); - AddOutputElement(spriteHandle, typeColor, $"{outputType.Name}"); + bool isOutput = archetype == Packing.Nodes[6]; + var type = TypeUtils.GetType((string)archetype.DefaultValues[0]); + AddInputOutputElement(archetype, type, isOutput, $"{type.Name}"); - var fields = outputType.GetMembers(BindingFlags.Public | BindingFlags.Instance).Where(x => x.IsField).ToArray(); + var fields = type.GetMembers(BindingFlags.Public | BindingFlags.Instance).Where(x => x.IsField).ToArray(); var fieldsLength = fields.Length; for (var i = 0; i < fieldsLength; i++) { var field = fields[i]; - _surfaceStyle.GetConnectionColor(field.ValueType, archetype.ConnectionsHints, out typeColor); - AddInputElement(spriteHandle, typeColor, $"{field.Name} ({field.ValueType.Name})"); + AddInputOutputElement(archetype, field.ValueType, !isOutput, $"{field.Name} ({field.ValueType.Name})"); } } - else if (archetype.TypeID == 36) + else if (archetype == Archetypes.Constants.Nodes[10]) { - var inputType = TypeUtils.GetType((string)archetype.DefaultValues[0]); - _surfaceStyle.GetConnectionColor(inputType, archetype.ConnectionsHints, out typeColor); - AddInputElement(spriteHandle, typeColor, $"{inputType.Name}"); - - var fields = inputType.GetMembers(BindingFlags.Public | BindingFlags.Instance).Where(x => x.IsField).ToArray(); - var fieldsLength = fields.Length; - for (var i = 0; i < fieldsLength; i++) - { - var field = fields[i]; - _surfaceStyle.GetConnectionColor(field.ValueType, archetype.ConnectionsHints, out typeColor); - AddOutputElement(spriteHandle, typeColor, $"{field.Name} ({field.ValueType.Name})"); - } + var t = new ScriptType(archetype.DefaultValues[0].GetType()); + AddInputOutputElement(archetype, t, true, $"ENUM {t.Name}"); } else { foreach (var element in archetype.Elements) { - if (element.Type == NodeElementType.Input) + if (element.Type is NodeElementType.Input or NodeElementType.Output) { - var connectionsType = element.ConnectionsType; - _surfaceStyle.GetConnectionColor(connectionsType, archetype.ConnectionsHints, out typeColor); - - if (connectionsType == null) + bool isOutput = element.Type == NodeElementType.Output; + if (element.ConnectionsType == null) { if(archetype == Archetypes.Constants.Nodes[12]) - AddInputElement(spriteHandle, typeColor, $"-{element.Text} ({ConnectionsHint.Array.ToString()})"); + AddInputOutputElement(archetype, element.ConnectionsType, isOutput, $"-{element.Text} ({ConnectionsHint.Array.ToString()})"); else if (archetype == Archetypes.Constants.Nodes[13]) - AddInputElement(spriteHandle, typeColor, $"-{element.Text} ({ConnectionsHint.Dictionary.ToString()})"); + AddInputOutputElement(archetype, element.ConnectionsType, isOutput, $"-{element.Text} ({ConnectionsHint.Dictionary.ToString()})"); else - AddInputElement(spriteHandle, typeColor, $"-{element.Text} ({archetype.ConnectionsHints.ToString()})"); + AddInputOutputElement(archetype, element.ConnectionsType, isOutput, $"-{element.Text} ({archetype.ConnectionsHints.ToString()})"); continue; } - AddInputElement(spriteHandle, typeColor, $"{element.Text} ({element.ConnectionsType.Name})"); - } - else if (element.Type == NodeElementType.Output) - { - // TODO: better check for enums - if (archetype == Archetypes.Constants.Nodes[10]) - { - var t = new ScriptType(archetype.DefaultValues[0].GetType()); - _surfaceStyle.GetConnectionColor(t, archetype.ConnectionsHints, out typeColor); - AddOutputElement(spriteHandle, typeColor, $"{t.Name}"); - } - else - { - var connectionsType = element.ConnectionsType; - _surfaceStyle.GetConnectionColor(connectionsType, archetype.ConnectionsHints, out typeColor); - - if (connectionsType == null) - { - if(archetype == Archetypes.Constants.Nodes[12]) - AddOutputElement(spriteHandle, typeColor, $"-{element.Text} ({ConnectionsHint.Array.ToString()})"); - else if (archetype == Archetypes.Constants.Nodes[13]) - AddOutputElement(spriteHandle, typeColor, $"-{element.Text} ({ConnectionsHint.Dictionary.ToString()})"); - else - AddOutputElement(spriteHandle, typeColor, $"-{element.Text} ({archetype.ConnectionsHints.ToString()})"); - continue; - } - - AddOutputElement(spriteHandle, typeColor, $"-{element.Text} ({connectionsType.Name})"); - } + AddInputOutputElement(archetype, element.ConnectionsType, isOutput, $"-{element.Text} ({element.ConnectionsType.Name})"); } } } } - _surfaceStyle.GetConnectionColor(declaringType, archetype.ConnectionsHints, out typeColor); - _descriptionClassImage.Color = typeColor; - _descriptionClassImage.MouseOverColor = typeColor; + _surfaceStyle.GetConnectionColor(declaringType, archetype.ConnectionsHints, out var declaringTypeColor); + _descriptionClassImage.Color = declaringTypeColor; + _descriptionClassImage.MouseOverColor = declaringTypeColor; float panelHeight = _descriptionSignatureLabel.Height; @@ -824,16 +777,18 @@ namespace FlaxEditor.Surface.ContextMenu Profiler.EndEvent(); } - private void AddInputElement(SpriteHandle sprite, Color typeColor, string text) + private void AddInputOutputElement(NodeArchetype nodeArchetype, ScriptType type, bool isOutput, string text) { var elementPanel = new Panel() { + Parent = isOutput ? _descriptionOutputPanel : _descriptionInputPanel, Width = Width * 0.5f, Height = 16, - Parent = _descriptionInputPanel, AnchorPreset = AnchorPresets.TopLeft }; + var sprite = _surfaceStyle.Icons.BoxOpen; + _surfaceStyle.GetConnectionColor(type, nodeArchetype.ConnectionsHints, out var typeColor); elementPanel.AddChild(new Image(2, 0, 12, 12) { Brush = new SpriteBrush(sprite), @@ -855,36 +810,6 @@ namespace FlaxEditor.Surface.ContextMenu elementPanel.Height = elementText.Height; } - private void AddOutputElement(SpriteHandle sprite, Color typeColor, string text) - { - var elementPanel = new Panel() - { - Width = Width * 0.5f, - Height = 16, - Parent = _descriptionOutputPanel, - AnchorPreset = AnchorPresets.TopLeft - }; - - elementPanel.AddChild(new Image(2, 0, 12, 12) - { - Brush = new SpriteBrush(sprite), - Color = typeColor, - MouseOverColor = typeColor, - AutoFocus = false, - }).SetAnchorPreset(AnchorPresets.TopLeft, true); - - var elementText = new Label(16, 0, Width * 0.5f - 32, 16) - { - Text = text, - HorizontalAlignment = TextAlignment.Near, - VerticalAlignment = TextAlignment.Near, - Wrapping = TextWrapping.NoWrap, - }; - elementText.SetAnchorPreset(AnchorPresets.TopLeft, true); - elementPanel.AddChild(elementText); - elementPanel.Height = elementText.Height; - } - /// /// Hides the description panel and resets the context menu to its original size /// From 0fd8de80295225043f75a82b2fa9a1b692841920 Mon Sep 17 00:00:00 2001 From: Nils Hausfeld Date: Sat, 15 Jun 2024 22:13:05 +0200 Subject: [PATCH 14/51] - Added custom func to fetch information for nodes that need special treatment like Array, Enum or Un/Pack nodes - More refactoring and cleanup --- Source/Editor/Surface/Archetypes/Constants.cs | 24 +++++++++ Source/Editor/Surface/Archetypes/Packing.cs | 32 ++++++++++++ .../Editor/Surface/ContextMenu/VisjectCM.cs | 50 ++++++++----------- Source/Editor/Surface/NodeArchetype.cs | 13 ++++- 4 files changed, 88 insertions(+), 31 deletions(-) diff --git a/Source/Editor/Surface/Archetypes/Constants.cs b/Source/Editor/Surface/Archetypes/Constants.cs index b94bc34cb..8cce34332 100644 --- a/Source/Editor/Surface/Archetypes/Constants.cs +++ b/Source/Editor/Surface/Archetypes/Constants.cs @@ -7,6 +7,8 @@ using Real = System.Single; #endif using System; +using System.Collections; +using System.Collections.Generic; using System.Linq; using FlaxEditor.CustomEditors.Editors; using FlaxEditor.GUI; @@ -182,6 +184,13 @@ namespace FlaxEditor.Surface.Archetypes base.OnDestroy(); } + + internal static void GetInputOutputDescription(NodeArchetype nodeArch, out (string, ScriptType)[] inputs, out (string, ScriptType)[] outputs) + { + var type = new ScriptType(nodeArch.DefaultValues[0].GetType()); + inputs = null; + outputs = [(type.Name, type)]; + } } private class ArrayNode : SurfaceNode @@ -321,6 +330,12 @@ namespace FlaxEditor.Surface.Archetypes array.SetValue(value, box.ID - 1); SetValue(0, array); } + + internal static void GetInputOutputDescription(NodeArchetype nodeArch, out (string, ScriptType)[] inputs, out (string, ScriptType)[] outputs) + { + inputs = null; + outputs = [("", new ScriptType(typeof(Array)))]; + } } private class DictionaryNode : SurfaceNode @@ -449,6 +464,12 @@ namespace FlaxEditor.Surface.Archetypes array.SetValue(value, box.ID - 1); SetValue(0, array); } + + internal static void GetInputOutputDescription(NodeArchetype nodeArch, out (string, ScriptType)[] inputs, out (string, ScriptType)[] outputs) + { + inputs = null; + outputs = [("", new ScriptType(typeof(Dictionary)))]; + } } /// @@ -743,6 +764,7 @@ namespace FlaxEditor.Surface.Archetypes Title = "Enum", Create = (id, context, arch, groupArch) => new EnumNode(id, context, arch, groupArch), Description = "Enum constant value.", + GetInputOutputDescription = EnumNode.GetInputOutputDescription, Flags = NodeFlags.VisualScriptGraph | NodeFlags.AnimGraph | NodeFlags.NoSpawnViaGUI, Size = new Float2(180, 20), DefaultValues = new object[] @@ -779,6 +801,7 @@ namespace FlaxEditor.Surface.Archetypes Title = "Array", Create = (id, context, arch, groupArch) => new ArrayNode(id, context, arch, groupArch), Description = "Constant array value.", + GetInputOutputDescription = ArrayNode.GetInputOutputDescription, Flags = NodeFlags.VisualScriptGraph | NodeFlags.AnimGraph, Size = new Float2(150, 20), DefaultValues = new object[] { new int[] { 0, 1, 2 } }, @@ -790,6 +813,7 @@ namespace FlaxEditor.Surface.Archetypes Title = "Dictionary", Create = (id, context, arch, groupArch) => new DictionaryNode(id, context, arch, groupArch), Description = "Creates an empty dictionary.", + GetInputOutputDescription = DictionaryNode.GetInputOutputDescription, Flags = NodeFlags.VisualScriptGraph | NodeFlags.AnimGraph, Size = new Float2(150, 40), DefaultValues = new object[] { typeof(int).FullName, typeof(string).FullName }, diff --git a/Source/Editor/Surface/Archetypes/Packing.cs b/Source/Editor/Surface/Archetypes/Packing.cs index 40244c2ca..5e84d615a 100644 --- a/Source/Editor/Surface/Archetypes/Packing.cs +++ b/Source/Editor/Surface/Archetypes/Packing.cs @@ -245,6 +245,21 @@ namespace FlaxEditor.Surface.Archetypes } return false; } + + internal static void GetInputOutputDescription(NodeArchetype nodeArch, out (string, ScriptType)[] inputs, out (string, ScriptType)[] outputs) + { + var type = TypeUtils.GetType((string)nodeArch.DefaultValues[0]); + outputs = [(type.Name, type)]; + + var fields = type.GetMembers(BindingFlags.Public | BindingFlags.Instance).Where(x => x.IsField).ToArray(); + var fieldsLength = fields.Length; + inputs = new (string, ScriptType)[fieldsLength]; + for (var i = 0; i < fieldsLength; i++) + { + var field = fields[i]; + inputs[i] = (field.Name, field.ValueType); + } + } } private sealed class UnpackStructureNode : StructureNode @@ -283,6 +298,21 @@ namespace FlaxEditor.Surface.Archetypes } return false; } + + internal static void GetInputOutputDescription(NodeArchetype nodeArch, out (string, ScriptType)[] inputs, out (string, ScriptType)[] outputs) + { + var type = TypeUtils.GetType((string)nodeArch.DefaultValues[0]); + inputs = [(type.Name, type)]; + + var fields = type.GetMembers(BindingFlags.Public | BindingFlags.Instance).Where(x => x.IsField).ToArray(); + var fieldsLength = fields.Length; + outputs = new (string, ScriptType)[fieldsLength]; + for (var i = 0; i < fieldsLength; i++) + { + var field = fields[i]; + outputs[i] = (field.Name, field.ValueType); + } + } } /// @@ -411,6 +441,7 @@ namespace FlaxEditor.Surface.Archetypes Create = (id, context, arch, groupArch) => new PackStructureNode(id, context, arch, groupArch), IsInputCompatible = PackStructureNode.IsInputCompatible, IsOutputCompatible = PackStructureNode.IsOutputCompatible, + GetInputOutputDescription = PackStructureNode.GetInputOutputDescription, Description = "Makes the structure data to from the components.", Flags = NodeFlags.VisualScriptGraph | NodeFlags.AnimGraph | NodeFlags.NoSpawnViaGUI, Size = new Float2(180, 20), @@ -523,6 +554,7 @@ namespace FlaxEditor.Surface.Archetypes Create = (id, context, arch, groupArch) => new UnpackStructureNode(id, context, arch, groupArch), IsInputCompatible = UnpackStructureNode.IsInputCompatible, IsOutputCompatible = UnpackStructureNode.IsOutputCompatible, + GetInputOutputDescription = UnpackStructureNode.GetInputOutputDescription, Description = "Breaks the structure data to allow extracting components from it.", Flags = NodeFlags.VisualScriptGraph | NodeFlags.AnimGraph | NodeFlags.NoSpawnViaGUI, Size = new Float2(180, 20), diff --git a/Source/Editor/Surface/ContextMenu/VisjectCM.cs b/Source/Editor/Surface/ContextMenu/VisjectCM.cs index a7737b4de..c2518519a 100644 --- a/Source/Editor/Surface/ContextMenu/VisjectCM.cs +++ b/Source/Editor/Surface/ContextMenu/VisjectCM.cs @@ -663,13 +663,10 @@ namespace FlaxEditor.Surface.ContextMenu Profiler.BeginEvent("VisjectCM.SetDescriptionPanelArchetype"); - ScriptType declaringType; - string elementName, elementTypeName; - _descriptionInputPanel.RemoveChildren(); _descriptionOutputPanel.RemoveChildren(); - + ScriptType declaringType; if (archetype.Tag is ScriptMemberInfo memberInfo) { var name = memberInfo.Name; @@ -710,24 +707,25 @@ namespace FlaxEditor.Surface.ContextMenu declaringType = archetype.DefaultType; // Special handling for Pack nodes - if (archetype == Packing.Nodes[6] || archetype == Packing.Nodes[13]) + if (archetype.GetInputOutputDescription != null) { - bool isOutput = archetype == Packing.Nodes[6]; - var type = TypeUtils.GetType((string)archetype.DefaultValues[0]); - AddInputOutputElement(archetype, type, isOutput, $"{type.Name}"); - - var fields = type.GetMembers(BindingFlags.Public | BindingFlags.Instance).Where(x => x.IsField).ToArray(); - var fieldsLength = fields.Length; - for (var i = 0; i < fieldsLength; i++) + archetype.GetInputOutputDescription.Invoke(archetype, out (string, ScriptType)[] inputs, out (string, ScriptType)[] outputs); + + if (inputs != null) { - var field = fields[i]; - AddInputOutputElement(archetype, field.ValueType, !isOutput, $"{field.Name} ({field.ValueType.Name})"); + for (int i = 0; i < inputs.Length; i++) + { + AddInputOutputElement(archetype, inputs[i].Item2, false, $"{inputs[i].Item1} ({inputs[i].Item2.Name})"); + } + } + + if (outputs != null) + { + for (int i = 0; i < outputs.Length; i++) + { + AddInputOutputElement(archetype, outputs[i].Item2, true, $"{outputs[i].Item1} ({outputs[i].Item2.Name})"); + } } - } - else if (archetype == Archetypes.Constants.Nodes[10]) - { - var t = new ScriptType(archetype.DefaultValues[0].GetType()); - AddInputOutputElement(archetype, t, true, $"ENUM {t.Name}"); } else { @@ -737,17 +735,9 @@ namespace FlaxEditor.Surface.ContextMenu { bool isOutput = element.Type == NodeElementType.Output; if (element.ConnectionsType == null) - { - if(archetype == Archetypes.Constants.Nodes[12]) - AddInputOutputElement(archetype, element.ConnectionsType, isOutput, $"-{element.Text} ({ConnectionsHint.Array.ToString()})"); - else if (archetype == Archetypes.Constants.Nodes[13]) - AddInputOutputElement(archetype, element.ConnectionsType, isOutput, $"-{element.Text} ({ConnectionsHint.Dictionary.ToString()})"); - else - AddInputOutputElement(archetype, element.ConnectionsType, isOutput, $"-{element.Text} ({archetype.ConnectionsHints.ToString()})"); - continue; - } - - AddInputOutputElement(archetype, element.ConnectionsType, isOutput, $"-{element.Text} ({element.ConnectionsType.Name})"); + AddInputOutputElement(archetype, element.ConnectionsType, isOutput, $"-{element.Text} ({archetype.ConnectionsHints.ToString()})"); + else + AddInputOutputElement(archetype, element.ConnectionsType, isOutput, $"-{element.Text} ({element.ConnectionsType.Name})"); } } } diff --git a/Source/Editor/Surface/NodeArchetype.cs b/Source/Editor/Surface/NodeArchetype.cs index efcec6b62..63d731b72 100644 --- a/Source/Editor/Surface/NodeArchetype.cs +++ b/Source/Editor/Surface/NodeArchetype.cs @@ -90,10 +90,15 @@ namespace FlaxEditor.Surface public delegate SurfaceNode CreateCustomNodeFunc(uint id, VisjectSurfaceContext context, NodeArchetype nodeArch, GroupArchetype groupArch); /// - /// Checks if the given type is compatible with the given node archetype. Used for custom nodes + /// Checks if the given type is compatible with the given node archetype. Used for custom nodes. /// public delegate bool IsCompatible(NodeArchetype nodeArch, ScriptType portType, ConnectionsHint hint, VisjectSurfaceContext context); + /// + /// Gets description of inputs and outputs of the archetype. Used for special cases for the description panel. + /// + public delegate void GetElementsDescriptionFunc(NodeArchetype nodeArch, out (string, ScriptType)[] inputs, out (string, ScriptType)[] outputs); + /// /// Unique node type ID within a single group. /// @@ -144,6 +149,11 @@ namespace FlaxEditor.Surface /// public string Description; + /// + /// Custom function to get descriptions of input and output elements. Used for description panel (optional). + /// + public GetElementsDescriptionFunc GetInputOutputDescription; + /// /// Alternative node titles. /// @@ -217,6 +227,7 @@ namespace FlaxEditor.Surface SubTitle = SubTitle, Signature = Signature, Description = Description, + GetInputOutputDescription = GetInputOutputDescription, AlternativeTitles = (string[])AlternativeTitles?.Clone(), Tag = Tag, SortScore = SortScore, From 53006ac9adc51656d8943c442c3e3de34ba01a9f Mon Sep 17 00:00:00 2001 From: Nils Hausfeld Date: Sun, 16 Jun 2024 12:12:26 +0200 Subject: [PATCH 15/51] - Moved description panel code - Description panel now gets hidden when hiding the context menu - Cleanup when hiding description panel --- .../Editor/Surface/ContextMenu/VisjectCM.cs | 329 +++++++++--------- 1 file changed, 166 insertions(+), 163 deletions(-) diff --git a/Source/Editor/Surface/ContextMenu/VisjectCM.cs b/Source/Editor/Surface/ContextMenu/VisjectCM.cs index c2518519a..14160a304 100644 --- a/Source/Editor/Surface/ContextMenu/VisjectCM.cs +++ b/Source/Editor/Surface/ContextMenu/VisjectCM.cs @@ -646,169 +646,6 @@ namespace FlaxEditor.Surface.ContextMenu _groups[i].Open(animate); } - /// - /// Updates the description panel and shows information about the set archetype - /// - /// The node archetype - public void SetDescriptionPanelArchetype(NodeArchetype archetype) - { - if(!_useDescriptionPanel) - return; - - if (archetype == null) - { - HideDescriptionPanel(); - return; - } - - Profiler.BeginEvent("VisjectCM.SetDescriptionPanelArchetype"); - - _descriptionInputPanel.RemoveChildren(); - _descriptionOutputPanel.RemoveChildren(); - - ScriptType declaringType; - if (archetype.Tag is ScriptMemberInfo memberInfo) - { - var name = memberInfo.Name; - if (memberInfo.IsMethod && memberInfo.Name.StartsWith("get_") || memberInfo.Name.StartsWith("set_")) - { - name = memberInfo.Name.Substring(4); - } - - declaringType = memberInfo.DeclaringType; - _descriptionSignatureLabel.Text = memberInfo.DeclaringType + "." + name; - - if (!memberInfo.IsStatic) - AddInputOutputElement(archetype, declaringType, false, $">Instance ({memberInfo.DeclaringType.Name})"); - - if (memberInfo.ValueType != ScriptType.Null && memberInfo.ValueType != ScriptType.Void) - { - if (memberInfo.IsField && archetype.Title.StartsWith("Set ")) - AddInputOutputElement(archetype, memberInfo.ValueType, false, $"({memberInfo.ValueType.Name})"); - else - AddInputOutputElement(archetype, memberInfo.ValueType, true, $"Return ({memberInfo.ValueType.Name})"); - } - - for(int i = 0; i < memberInfo.ParametersCount; i++) - { - var param = memberInfo.GetParameters()[i]; - if (param.IsOut) - { - AddInputOutputElement(archetype, param.Type, true, $">{param.Name} ({param.Type.Name})"); - continue; - } - - AddInputOutputElement(archetype, param.Type, false, $">{param.Name} ({param.Type.Name})"); - } - } - else - { - _descriptionSignatureLabel.Text = archetype.Signature; - declaringType = archetype.DefaultType; - - // Special handling for Pack nodes - if (archetype.GetInputOutputDescription != null) - { - archetype.GetInputOutputDescription.Invoke(archetype, out (string, ScriptType)[] inputs, out (string, ScriptType)[] outputs); - - if (inputs != null) - { - for (int i = 0; i < inputs.Length; i++) - { - AddInputOutputElement(archetype, inputs[i].Item2, false, $"{inputs[i].Item1} ({inputs[i].Item2.Name})"); - } - } - - if (outputs != null) - { - for (int i = 0; i < outputs.Length; i++) - { - AddInputOutputElement(archetype, outputs[i].Item2, true, $"{outputs[i].Item1} ({outputs[i].Item2.Name})"); - } - } - } - else - { - foreach (var element in archetype.Elements) - { - if (element.Type is NodeElementType.Input or NodeElementType.Output) - { - bool isOutput = element.Type == NodeElementType.Output; - if (element.ConnectionsType == null) - AddInputOutputElement(archetype, element.ConnectionsType, isOutput, $"-{element.Text} ({archetype.ConnectionsHints.ToString()})"); - else - AddInputOutputElement(archetype, element.ConnectionsType, isOutput, $"-{element.Text} ({element.ConnectionsType.Name})"); - } - } - } - } - - _surfaceStyle.GetConnectionColor(declaringType, archetype.ConnectionsHints, out var declaringTypeColor); - _descriptionClassImage.Color = declaringTypeColor; - _descriptionClassImage.MouseOverColor = declaringTypeColor; - - float panelHeight = _descriptionSignatureLabel.Height; - - _descriptionLabel.Y = _descriptionSignatureLabel.Bounds.Bottom + 6f; - _descriptionLabel.Text = archetype.Description; - - panelHeight += _descriptionLabel.Height + 6f + 18f; - - _descriptionInputPanel.Y = panelHeight; - _descriptionOutputPanel.Y = panelHeight; - - panelHeight += Mathf.Max(_descriptionInputPanel.Height, _descriptionOutputPanel.Height); - _descriptionPanel.Height = panelHeight; - Height = 400 + Mathf.RoundToInt(_descriptionPanel.Height); - UpdateWindowSize(); - - PerformLayout(); - - Profiler.EndEvent(); - } - - private void AddInputOutputElement(NodeArchetype nodeArchetype, ScriptType type, bool isOutput, string text) - { - var elementPanel = new Panel() - { - Parent = isOutput ? _descriptionOutputPanel : _descriptionInputPanel, - Width = Width * 0.5f, - Height = 16, - AnchorPreset = AnchorPresets.TopLeft - }; - - var sprite = _surfaceStyle.Icons.BoxOpen; - _surfaceStyle.GetConnectionColor(type, nodeArchetype.ConnectionsHints, out var typeColor); - elementPanel.AddChild(new Image(2, 0, 12, 12) - { - Brush = new SpriteBrush(sprite), - Color = typeColor, - MouseOverColor = typeColor, - AutoFocus = false, - }).SetAnchorPreset(AnchorPresets.TopLeft, true); - - var elementText = new Label(16, 0, Width * 0.5f - 32, 16) - { - Text = text, - HorizontalAlignment = TextAlignment.Near, - VerticalAlignment = TextAlignment.Near, - Wrapping = TextWrapping.WrapWords, - AutoHeight = true, - }; - elementText.SetAnchorPreset(AnchorPresets.TopLeft, true); - elementPanel.AddChild(elementText); - elementPanel.Height = elementText.Height; - } - - /// - /// Hides the description panel and resets the context menu to its original size - /// - public void HideDescriptionPanel() - { - Height = 400; - UpdateWindowSize(); - } - /// /// Resets the view. /// @@ -953,9 +790,175 @@ namespace FlaxEditor.Surface.ContextMenu { Focus(null); + if(_useDescriptionPanel) + HideDescriptionPanel(); + base.Hide(); } + /// + /// Updates the description panel and shows information about the set archetype + /// + /// The node archetype + public void SetDescriptionPanelArchetype(NodeArchetype archetype) + { + if(!_useDescriptionPanel) + return; + + if (archetype == null) + { + HideDescriptionPanel(); + return; + } + + Profiler.BeginEvent("VisjectCM.SetDescriptionPanelArchetype"); + + _descriptionInputPanel.RemoveChildren(); + _descriptionOutputPanel.RemoveChildren(); + + ScriptType declaringType; + if (archetype.Tag is ScriptMemberInfo memberInfo) + { + var name = memberInfo.Name; + if (memberInfo.IsMethod && memberInfo.Name.StartsWith("get_") || memberInfo.Name.StartsWith("set_")) + { + name = memberInfo.Name.Substring(4); + } + + declaringType = memberInfo.DeclaringType; + _descriptionSignatureLabel.Text = memberInfo.DeclaringType + "." + name; + + if (!memberInfo.IsStatic) + AddInputOutputElement(archetype, declaringType, false, $">Instance ({memberInfo.DeclaringType.Name})"); + + if (memberInfo.ValueType != ScriptType.Null && memberInfo.ValueType != ScriptType.Void) + { + if (memberInfo.IsField && archetype.Title.StartsWith("Set ")) + AddInputOutputElement(archetype, memberInfo.ValueType, false, $"({memberInfo.ValueType.Name})"); + else + AddInputOutputElement(archetype, memberInfo.ValueType, true, $"Return ({memberInfo.ValueType.Name})"); + } + + for(int i = 0; i < memberInfo.ParametersCount; i++) + { + var param = memberInfo.GetParameters()[i]; + if (param.IsOut) + { + AddInputOutputElement(archetype, param.Type, true, $">{param.Name} ({param.Type.Name})"); + continue; + } + + AddInputOutputElement(archetype, param.Type, false, $">{param.Name} ({param.Type.Name})"); + } + } + else + { + _descriptionSignatureLabel.Text = string.IsNullOrEmpty(archetype.Signature) ? archetype.Title : archetype.Signature; + declaringType = archetype.DefaultType; + + // Special handling for Pack nodes + if (archetype.GetInputOutputDescription != null) + { + archetype.GetInputOutputDescription.Invoke(archetype, out (string, ScriptType)[] inputs, out (string, ScriptType)[] outputs); + + if (inputs != null) + { + for (int i = 0; i < inputs.Length; i++) + { + AddInputOutputElement(archetype, inputs[i].Item2, false, $"{inputs[i].Item1} ({inputs[i].Item2.Name})"); + } + } + + if (outputs != null) + { + for (int i = 0; i < outputs.Length; i++) + { + AddInputOutputElement(archetype, outputs[i].Item2, true, $"{outputs[i].Item1} ({outputs[i].Item2.Name})"); + } + } + } + else + { + foreach (var element in archetype.Elements) + { + if (element.Type is NodeElementType.Input or NodeElementType.Output) + { + bool isOutput = element.Type == NodeElementType.Output; + if (element.ConnectionsType == null) + AddInputOutputElement(archetype, element.ConnectionsType, isOutput, $"-{element.Text} ({archetype.ConnectionsHints.ToString()})"); + else + AddInputOutputElement(archetype, element.ConnectionsType, isOutput, $"-{element.Text} ({element.ConnectionsType.Name})"); + } + } + } + } + + _surfaceStyle.GetConnectionColor(declaringType, archetype.ConnectionsHints, out var declaringTypeColor); + _descriptionClassImage.Color = declaringTypeColor; + _descriptionClassImage.MouseOverColor = declaringTypeColor; + + float panelHeight = _descriptionSignatureLabel.Height; + + _descriptionLabel.Y = _descriptionSignatureLabel.Bounds.Bottom + 6f; + _descriptionLabel.Text = archetype.Description; + + panelHeight += _descriptionLabel.Height + 6f + 18f; + + _descriptionInputPanel.Y = panelHeight; + _descriptionOutputPanel.Y = panelHeight; + + panelHeight += Mathf.Max(_descriptionInputPanel.Height, _descriptionOutputPanel.Height); + _descriptionPanel.Height = panelHeight; + Height = 400 + Mathf.RoundToInt(_descriptionPanel.Height); + UpdateWindowSize(); + + Profiler.EndEvent(); + } + + private void AddInputOutputElement(NodeArchetype nodeArchetype, ScriptType type, bool isOutput, string text) + { + var elementPanel = new Panel() + { + Parent = isOutput ? _descriptionOutputPanel : _descriptionInputPanel, + Width = Width * 0.5f, + Height = 16, + AnchorPreset = AnchorPresets.TopLeft + }; + + var sprite = _surfaceStyle.Icons.BoxOpen; + _surfaceStyle.GetConnectionColor(type, nodeArchetype.ConnectionsHints, out var typeColor); + elementPanel.AddChild(new Image(2, 0, 12, 12) + { + Brush = new SpriteBrush(sprite), + Color = typeColor, + MouseOverColor = typeColor, + AutoFocus = false, + }).SetAnchorPreset(AnchorPresets.TopLeft, true); + + var elementText = new Label(16, 0, Width * 0.5f - 32, 16) + { + Text = text, + HorizontalAlignment = TextAlignment.Near, + VerticalAlignment = TextAlignment.Near, + Wrapping = TextWrapping.WrapWords, + AutoHeight = true, + }; + elementText.SetAnchorPreset(AnchorPresets.TopLeft, true); + elementPanel.AddChild(elementText); + elementPanel.Height = elementText.Height; + } + + /// + /// Hides the description panel and resets the context menu to its original size + /// + public void HideDescriptionPanel() + { + _descriptionInputPanel.RemoveChildren(); + _descriptionOutputPanel.RemoveChildren(); + Height = 400; + UpdateWindowSize(); + } + /// public override bool OnKeyDown(KeyboardKeys key) { From b0953e94948f5ad0691c14f65be0235111fb0c03 Mon Sep 17 00:00:00 2001 From: Nils Hausfeld Date: Sun, 16 Jun 2024 12:18:03 +0200 Subject: [PATCH 16/51] - Minor refactoring and cleanup --- Source/Editor/Surface/ContextMenu/VisjectCM.cs | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/Source/Editor/Surface/ContextMenu/VisjectCM.cs b/Source/Editor/Surface/ContextMenu/VisjectCM.cs index 14160a304..9f512b7ac 100644 --- a/Source/Editor/Surface/ContextMenu/VisjectCM.cs +++ b/Source/Editor/Surface/ContextMenu/VisjectCM.cs @@ -842,13 +842,7 @@ namespace FlaxEditor.Surface.ContextMenu for(int i = 0; i < memberInfo.ParametersCount; i++) { var param = memberInfo.GetParameters()[i]; - if (param.IsOut) - { - AddInputOutputElement(archetype, param.Type, true, $">{param.Name} ({param.Type.Name})"); - continue; - } - - AddInputOutputElement(archetype, param.Type, false, $">{param.Name} ({param.Type.Name})"); + AddInputOutputElement(archetype, param.Type, param.IsOut, $">{param.Name} ({param.Type.Name})"); } } else @@ -856,7 +850,6 @@ namespace FlaxEditor.Surface.ContextMenu _descriptionSignatureLabel.Text = string.IsNullOrEmpty(archetype.Signature) ? archetype.Title : archetype.Signature; declaringType = archetype.DefaultType; - // Special handling for Pack nodes if (archetype.GetInputOutputDescription != null) { archetype.GetInputOutputDescription.Invoke(archetype, out (string, ScriptType)[] inputs, out (string, ScriptType)[] outputs); @@ -866,7 +859,7 @@ namespace FlaxEditor.Surface.ContextMenu for (int i = 0; i < inputs.Length; i++) { AddInputOutputElement(archetype, inputs[i].Item2, false, $"{inputs[i].Item1} ({inputs[i].Item2.Name})"); - } + } } if (outputs != null) @@ -874,7 +867,7 @@ namespace FlaxEditor.Surface.ContextMenu for (int i = 0; i < outputs.Length; i++) { AddInputOutputElement(archetype, outputs[i].Item2, true, $"{outputs[i].Item1} ({outputs[i].Item2.Name})"); - } + } } } else @@ -951,7 +944,7 @@ namespace FlaxEditor.Surface.ContextMenu /// /// Hides the description panel and resets the context menu to its original size /// - public void HideDescriptionPanel() + private void HideDescriptionPanel() { _descriptionInputPanel.RemoveChildren(); _descriptionOutputPanel.RemoveChildren(); From 62778fc1e96d26afbe833c09a557de5042c8a874 Mon Sep 17 00:00:00 2001 From: Nils Hausfeld Date: Sun, 16 Jun 2024 12:37:46 +0200 Subject: [PATCH 17/51] - Increasing width of CM slightly when using description panel - Some padding and size changes - A tiny bit of cleanup --- .../Editor/Surface/ContextMenu/VisjectCM.cs | 28 ++++++++----------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/Source/Editor/Surface/ContextMenu/VisjectCM.cs b/Source/Editor/Surface/ContextMenu/VisjectCM.cs index 9f512b7ac..8f90e80cd 100644 --- a/Source/Editor/Surface/ContextMenu/VisjectCM.cs +++ b/Source/Editor/Surface/ContextMenu/VisjectCM.cs @@ -66,7 +66,6 @@ namespace FlaxEditor.Surface.ContextMenu private readonly VerticalPanel _descriptionInputPanel; private readonly VerticalPanel _descriptionOutputPanel; - private VisjectCMItem _selectedItem; /// @@ -75,7 +74,7 @@ namespace FlaxEditor.Surface.ContextMenu public VisjectCMItem SelectedItem { get => _selectedItem; - set + private set { _selectedItem = value; _selectedItem?.OnSelect(); @@ -166,7 +165,7 @@ namespace FlaxEditor.Surface.ContextMenu _surfaceStyle = info.Style; // Context menu dimensions - Size = new Float2(300, 400); + Size = new Float2(_useDescriptionPanel ? 350 : 300, 400); var headerPanel = new Panel(ScrollBars.None) { @@ -253,11 +252,8 @@ namespace FlaxEditor.Surface.ContextMenu { Parent = _descriptionPanel, Brush = new SpriteBrush(spriteHandle), - Color = Color.Aqua, - MouseOverColor = Color.Aqua, - AutoFocus = false, }; - + var signatureFontReference = new FontReference(Style.Current.FontMedium.Asset, 9f); _descriptionSignatureLabel = new Label(32, 8, Width - 40, 0) { @@ -285,16 +281,16 @@ namespace FlaxEditor.Surface.ContextMenu _descriptionInputPanel = new VerticalPanel() { Parent = _descriptionPanel, - Width = Width * 0.5f, - AnchorPreset = AnchorPresets.TopLeft, + X = 8, + Width = Width * 0.5f - 16, AutoSize = true, }; - + _descriptionOutputPanel = new VerticalPanel() { Parent = _descriptionPanel, - X = Width * 0.5f, - Width = Width * 0.5f, + X = Width * 0.5f + 8, + Width = Width * 0.5f - 16, AutoSize = true, }; } @@ -829,7 +825,7 @@ namespace FlaxEditor.Surface.ContextMenu _descriptionSignatureLabel.Text = memberInfo.DeclaringType + "." + name; if (!memberInfo.IsStatic) - AddInputOutputElement(archetype, declaringType, false, $">Instance ({memberInfo.DeclaringType.Name})"); + AddInputOutputElement(archetype, declaringType, false, $"Instance ({memberInfo.DeclaringType.Name})"); if (memberInfo.ValueType != ScriptType.Null && memberInfo.ValueType != ScriptType.Void) { @@ -842,7 +838,7 @@ namespace FlaxEditor.Surface.ContextMenu for(int i = 0; i < memberInfo.ParametersCount; i++) { var param = memberInfo.GetParameters()[i]; - AddInputOutputElement(archetype, param.Type, param.IsOut, $">{param.Name} ({param.Type.Name})"); + AddInputOutputElement(archetype, param.Type, param.IsOut, $"{param.Name} ({param.Type.Name})"); } } else @@ -878,9 +874,9 @@ namespace FlaxEditor.Surface.ContextMenu { bool isOutput = element.Type == NodeElementType.Output; if (element.ConnectionsType == null) - AddInputOutputElement(archetype, element.ConnectionsType, isOutput, $"-{element.Text} ({archetype.ConnectionsHints.ToString()})"); + AddInputOutputElement(archetype, element.ConnectionsType, isOutput, $"{element.Text} ({archetype.ConnectionsHints.ToString()})"); else - AddInputOutputElement(archetype, element.ConnectionsType, isOutput, $"-{element.Text} ({element.ConnectionsType.Name})"); + AddInputOutputElement(archetype, element.ConnectionsType, isOutput, $"{element.Text} ({element.ConnectionsType.Name})"); } } } From 4abe8587f30a4d8a7e39b02d2aa2966bb7bf0194 Mon Sep 17 00:00:00 2001 From: Nils Hausfeld Date: Sun, 16 Jun 2024 13:37:03 +0200 Subject: [PATCH 18/51] - Fixed some tooltip regressions - Defined signatures where necessary --- Source/Editor/Surface/ContextMenu/VisjectCMItem.cs | 12 +++++++++++- Source/Editor/Surface/SurfaceNode.cs | 12 +++++++++++- Source/Editor/Surface/SurfaceUtils.cs | 10 ++++------ .../Surface/VisjectSurfaceContext.Serialization.cs | 1 + Source/Editor/Surface/VisualScriptSurface.cs | 6 +++++- 5 files changed, 32 insertions(+), 9 deletions(-) diff --git a/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs b/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs index c0fba5586..370025360 100644 --- a/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs +++ b/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text; using FlaxEditor.Scripting; using FlaxEditor.Surface.Elements; using FlaxEditor.Utilities; @@ -62,7 +63,7 @@ namespace FlaxEditor.Surface.ContextMenu Group = group; _groupArchetype = groupArchetype; _archetype = archetype; - TooltipText = $"{_archetype.Signature}\n{_archetype.Description}"; + TooltipText = GetTooltip(); } /// @@ -323,6 +324,15 @@ namespace FlaxEditor.Surface.ContextMenu Group.ContextMenu.SetDescriptionPanelArchetype(_archetype); } + private string GetTooltip() + { + StringBuilder sb = new StringBuilder(); + if (!string.IsNullOrEmpty(_archetype.Signature)) + sb.Append(_archetype.Signature + "\n"); + sb.Append(_archetype.Description); + return sb.ToString(); + } + /// public override bool OnMouseDown(Float2 location, MouseButton button) { diff --git a/Source/Editor/Surface/SurfaceNode.cs b/Source/Editor/Surface/SurfaceNode.cs index 07dc4f5e9..1dbb8424b 100644 --- a/Source/Editor/Surface/SurfaceNode.cs +++ b/Source/Editor/Surface/SurfaceNode.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Text; using FlaxEditor.Scripting; using FlaxEditor.Surface.Elements; using FlaxEditor.Surface.Undo; @@ -124,7 +125,7 @@ namespace FlaxEditor.Surface Archetype = nodeArch; GroupArchetype = groupArch; AutoFocus = false; - TooltipText = TooltipText = $"{nodeArch.Signature}\n{nodeArch.Description}"; + TooltipText = GetTooltip(); CullChildren = false; BackgroundColor = Style.Current.BackgroundNormal; @@ -851,6 +852,15 @@ namespace FlaxEditor.Surface } } + private string GetTooltip() + { + StringBuilder sb = new StringBuilder(); + if (!string.IsNullOrEmpty(Archetype.Signature)) + sb.Append(Archetype.Signature + "\n"); + sb.Append(Archetype.Description); + return sb.ToString(); + } + /// protected override bool ShowTooltip => base.ShowTooltip && _headerRect.Contains(ref _mousePosition) && !Surface.IsLeftMouseButtonDown && !Surface.IsRightMouseButtonDown && !Surface.IsPrimaryMenuOpened; diff --git a/Source/Editor/Surface/SurfaceUtils.cs b/Source/Editor/Surface/SurfaceUtils.cs index 8e14787b6..6bc834b0a 100644 --- a/Source/Editor/Surface/SurfaceUtils.cs +++ b/Source/Editor/Surface/SurfaceUtils.cs @@ -447,8 +447,7 @@ namespace FlaxEditor.Surface var valueType = member.ValueType; // Getter/setter method of the property - we can return early here - bool isGetterOrSetter = name.StartsWith("get_") || name.StartsWith("set_"); - if (member.IsMethod && isGetterOrSetter) + if (member.IsMethod && (name.StartsWith("get_") || name.StartsWith("set_"))) { var flags = member.IsStatic ? BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly : BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly; var property = declaringType.GetMembers(name.Substring(4), MemberTypes.Property, flags); @@ -470,7 +469,7 @@ namespace FlaxEditor.Surface sb.Append(name); // Is a method and not a property - if (member.IsMethod && !isGetterOrSetter) + if (member.IsMethod) { sb.Append('('); var parameters = member.GetParameters(); @@ -504,8 +503,7 @@ namespace FlaxEditor.Surface var declaringType = member.DeclaringType; // Getter/setter method of the property - we can return early here - bool isGetterOrSetter = name.StartsWith("get_") || name.StartsWith("set_"); - if (member.IsMethod && isGetterOrSetter) + if (member.IsMethod && (name.StartsWith("get_") || name.StartsWith("set_"))) { var flags = member.IsStatic ? BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly : BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly; var property = declaringType.GetMembers(name.Substring(4), MemberTypes.Property, flags); @@ -524,7 +522,7 @@ namespace FlaxEditor.Surface var sb = new StringBuilder(signature); // Tooltip - var tooltip = Editor.Instance.CodeDocs.GetTooltip(member); + var tooltip = GetVisualScriptMemberShortDescription(member); if (!string.IsNullOrEmpty(tooltip)) sb.Append("\n").Append(tooltip); diff --git a/Source/Editor/Surface/VisjectSurfaceContext.Serialization.cs b/Source/Editor/Surface/VisjectSurfaceContext.Serialization.cs index 09147efac..97122f872 100644 --- a/Source/Editor/Surface/VisjectSurfaceContext.Serialization.cs +++ b/Source/Editor/Surface/VisjectSurfaceContext.Serialization.cs @@ -51,6 +51,7 @@ namespace FlaxEditor.Surface { TypeID = originalNodeId, Title = "Missing Node :(", + Signature = ":(", Description = ":(", Flags = NodeFlags.AllGraphs, Size = new Float2(200, 70), diff --git a/Source/Editor/Surface/VisualScriptSurface.cs b/Source/Editor/Surface/VisualScriptSurface.cs index f7fafeef8..e17453b0a 100644 --- a/Source/Editor/Surface/VisualScriptSurface.cs +++ b/Source/Editor/Surface/VisualScriptSurface.cs @@ -238,7 +238,8 @@ namespace FlaxEditor.Surface var node = (NodeArchetype)Archetypes.Function.Nodes[2].Clone(); node.Flags &= ~NodeFlags.NoSpawnViaGUI; - node.Description = Editor.Instance.CodeDocs.GetTooltip(member); + node.Signature = SurfaceUtils.GetVisualScriptMemberInfoSignature(member); + node.Description = SurfaceUtils.GetVisualScriptMemberShortDescription(member); node.DefaultValues[0] = name; node.DefaultValues[1] = parameters.Length; node.Title = "Override " + name; @@ -280,6 +281,7 @@ namespace FlaxEditor.Surface node.DefaultValues[0] = Activator.CreateInstance(scriptType.Type); node.Flags &= ~NodeFlags.NoSpawnViaGUI; node.Title = scriptTypeName; + node.Signature = scriptTypeName; node.Description = Editor.Instance.CodeDocs.GetTooltip(scriptType); // Create group archetype @@ -330,6 +332,7 @@ namespace FlaxEditor.Surface node.DefaultValues[0] = scriptTypeTypeName; node.Flags &= ~NodeFlags.NoSpawnViaGUI; node.Title = "Pack " + scriptTypeName; + node.Signature = "Pack " + scriptTypeName; node.Description = tooltip; ((IList)group.Archetypes).Add(node); @@ -338,6 +341,7 @@ namespace FlaxEditor.Surface node.DefaultValues[0] = scriptTypeTypeName; node.Flags &= ~NodeFlags.NoSpawnViaGUI; node.Title = "Unpack " + scriptTypeName; + node.Signature = "Unpack " + scriptTypeName; node.Description = tooltip; ((IList)group.Archetypes).Add(node); } From 5f939430eed2cac4c6466794fe589f94ba56da97 Mon Sep 17 00:00:00 2001 From: ExMatics HydrogenC <33123710+HydrogenC@users.noreply.github.com> Date: Mon, 17 Jun 2024 23:00:48 +0800 Subject: [PATCH 19/51] Initial commit for forward software reflection --- .../Features/ForwardShading.hlsl | 42 +++++++++++++++++++ .../Materials/ForwardMaterialShader.cpp | 1 + .../Materials/MaterialShaderFeatures.cpp | 12 ++++++ Source/Shaders/SSR.shader | 11 +++-- 4 files changed, 62 insertions(+), 4 deletions(-) diff --git a/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl b/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl index 9dbc19369..0df9abe9e 100644 --- a/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl +++ b/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl @@ -9,6 +9,10 @@ #define MATERIAL_REFLECTIONS_SSR 1 #if MATERIAL_REFLECTIONS == MATERIAL_REFLECTIONS_SSR #include "./Flax/SSR.hlsl" +#if USE_GLOBAL_SURFACE_ATLAS +#include "./Flax/GlobalSignDistanceField.hlsl" +#include "./Flax/GI/GlobalSurfaceAtlas.hlsl" +#endif #endif #endif #include "./Flax/Lighting.hlsl" @@ -27,12 +31,23 @@ LightData LocalLights[MAX_LOCAL_LIGHTS]; TextureCube EnvProbe : register(t__SRV__); TextureCube SkyLightTexture : register(t__SRV__); Texture2DArray DirectionalLightShadowMap : register(t__SRV__); +#if USE_GLOBAL_SURFACE_ATLAS +Texture3D GlobalSDFTex : register(t__SRV__); +Texture3D GlobalSDFMip : register(t__SRV__); +ByteAddressBuffer GlobalSurfaceAtlasChunks : register(t__SRV__); +ByteAddressBuffer RWGlobalSurfaceAtlasCulledObjects : register(t__SRV__); +Buffer GlobalSurfaceAtlasObjects : register(t__SRV__); +Texture2D GlobalSurfaceAtlasDepth : register(t__SRV__); +Texture2D GlobalSurfaceAtlasTex : register(t__SRV__); +#endif @4// Forward Shading: Utilities DECLARE_LIGHTSHADOWDATA_ACCESS(DirectionalLightShadow); @5// Forward Shading: Shaders // Pixel Shader function for Forward Pass META_PS(USE_FORWARD, FEATURE_LEVEL_ES2) +META_PERMUTATION_1(USE_GLOBAL_SURFACE_ATLAS=0) +META_PERMUTATION_1(USE_GLOBAL_SURFACE_ATLAS=1) void PS_Forward( in PixelInput input ,out float4 output : SV_Target0 @@ -125,6 +140,33 @@ void PS_Forward( float3 screenColor = sceneColorTexture.SampleLevel(SamplerPointClamp, hit.xy, 0).rgb; reflections = lerp(reflections, screenColor, hit.z); } + + // Fallback to software tracing if possible +#if USE_GLOBAL_SURFACE_ATLAS && CAN_USE_GLOBAL_SURFACE_ATLAS + + // If hit.z >= 0.9f then skip sdf tracing + if (hit.z < 0.9f) + { + // Don't use temporal effect in forward pass + float3 reflectWS = ScreenSpaceReflectionDirection(screenUV, gBuffer, gBufferData.ViewPos); + + GlobalSDFTrace sdfTrace; + float maxDistance = 100000; + float selfOcclusionBias = GlobalSDF.CascadeVoxelSize[0]; + sdfTrace.Init(gBuffer.WorldPos + gBuffer.Normal * selfOcclusionBias, reflectWS, 0.0f, maxDistance); + GlobalSDFHit sdfHit = RayTraceGlobalSDF(GlobalSDF, GlobalSDFTex, GlobalSDFMip, sdfTrace); + if (sdfHit.IsHit()) + { + float3 hitPosition = sdfHit.GetHitPosition(sdfTrace); + float surfaceThreshold = GetGlobalSurfaceAtlasThreshold(GlobalSDF, sdfHit); + float4 surfaceAtlas = SampleGlobalSurfaceAtlas(GlobalSurfaceAtlas, GlobalSurfaceAtlasChunks, RWGlobalSurfaceAtlasCulledObjects, GlobalSurfaceAtlasObjects, GlobalSurfaceAtlasDepth, GlobalSurfaceAtlasTex, hitPosition, -reflectWS, surfaceThreshold); + + float3 screenColor = sceneColorTexture.SampleLevel(SamplerPointClamp, hit.xy, 0).rgb; + reflections = lerp(surfaceAtlas, float4(screenColor, 1), hit.z); + } + } + +#endif #endif light.rgb += reflections * GetReflectionSpecularLighting(ViewPos, gBuffer) * light.a; diff --git a/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp b/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp index af2b30348..31c2f8166 100644 --- a/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp +++ b/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp @@ -178,6 +178,7 @@ bool ForwardMaterialShader::Load() psDesc.VS = _shader->GetVS("VS"); if (psDesc.VS == nullptr) return true; + psDesc.PS = _shader->GetPS("PS_Forward"); psDesc.DepthWriteEnable = false; psDesc.BlendMode = BlendingMode::AlphaBlend; diff --git a/Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp b/Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp index 43646cc0e..d385ec24f 100644 --- a/Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp +++ b/Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp @@ -5,6 +5,7 @@ #include "Engine/Graphics/Textures/GPUTexture.h" #include "Engine/Renderer/RenderList.h" #include "Engine/Renderer/ShadowsPass.h" +#include "Engine/Renderer/GlobalSignDistanceFieldPass.h" #if USE_EDITOR #include "Engine/Renderer/Lightmaps.h" #endif @@ -22,6 +23,8 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, SpanUnBindSR(envProbeShaderRegisterIndex); } + // Bind sdf resources if using software reflections + if (!GlobalSignDistanceFieldPass::Instance()->Render(params.RenderContext, params.GPUContext, bindingDataSDF) && + !GlobalSurfaceAtlasPass::Instance()->Render(params.RenderContext, params.GPUContext, bindingDataSurfaceAtlas)) + { + useGlobalSurfaceAtlas = true; + data.GlobalSDF = bindingDataSDF.Constants; + data.GlobalSurfaceAtlas = bindingDataSurfaceAtlas.Constants; + } + // Set local lights data.LocalLightsCount = 0; const BoundingSphere objectBounds(drawCall.ObjectPosition, drawCall.ObjectRadius); diff --git a/Source/Shaders/SSR.shader b/Source/Shaders/SSR.shader index a813bdf36..ca177ff09 100644 --- a/Source/Shaders/SSR.shader +++ b/Source/Shaders/SSR.shader @@ -133,11 +133,12 @@ float4 PS_RayTracePass(Quad_VS2PS input) : SV_Target0 return result; } - // Calculate reflection direction (the same TraceScreenSpaceReflection) - float3 reflectWS = ScreenSpaceReflectionDirection(input.TexCoord, gBuffer, gBufferData.ViewPos, TemporalEffect, TemporalTime, BRDFBias); - // Fallback to Global SDF and Global Surface Atlas tracing #if USE_GLOBAL_SURFACE_ATLAS && CAN_USE_GLOBAL_SURFACE_ATLAS + + // Calculate reflection direction (the same TraceScreenSpaceReflection) + float3 reflectWS = ScreenSpaceReflectionDirection(input.TexCoord, gBuffer, gBufferData.ViewPos, TemporalEffect, TemporalTime, BRDFBias); + GlobalSDFTrace sdfTrace; float maxDistance = 100000; float selfOcclusionBias = GlobalSDF.CascadeVoxelSize[0]; @@ -148,7 +149,9 @@ float4 PS_RayTracePass(Quad_VS2PS input) : SV_Target0 float3 hitPosition = sdfHit.GetHitPosition(sdfTrace); float surfaceThreshold = GetGlobalSurfaceAtlasThreshold(GlobalSDF, sdfHit); float4 surfaceAtlas = SampleGlobalSurfaceAtlas(GlobalSurfaceAtlas, GlobalSurfaceAtlasChunks, RWGlobalSurfaceAtlasCulledObjects, GlobalSurfaceAtlasObjects, GlobalSurfaceAtlasDepth, GlobalSurfaceAtlasTex, hitPosition, -reflectWS, surfaceThreshold); - result = lerp(surfaceAtlas, float4(result.rgb, 1), result.a); + // Now the sdf reflection part is significantly darker than the screen space part + // TODO: Maybe multiply surfaceAtlas by a constant to make it brighter + result = lerp(surfaceAtlas, float4(result.rgb, 1), result.a); } #endif From 9062c04ef0c7669ff21f55f7e7f15818c9a73577 Mon Sep 17 00:00:00 2001 From: ExMatics HydrogenC <33123710+HydrogenC@users.noreply.github.com> Date: Tue, 18 Jun 2024 21:25:12 +0800 Subject: [PATCH 20/51] Complete sdf reflections --- .../Features/ForwardShading.hlsl | 33 ++------ .../Features/SDFReflections.hlsl | 39 ++++++++++ .../Materials/ForwardMaterialShader.cpp | 2 + .../Materials/MaterialShaderFeatures.cpp | 75 ++++++++++++++++--- .../Materials/MaterialShaderFeatures.h | 21 ++++++ .../Renderer/GI/GlobalSurfaceAtlasPass.cpp | 11 +++ .../Renderer/GI/GlobalSurfaceAtlasPass.h | 8 ++ .../MaterialGenerator/MaterialGenerator.cpp | 2 + Source/Shaders/SSR.shader | 4 +- 9 files changed, 154 insertions(+), 41 deletions(-) create mode 100644 Content/Editor/MaterialTemplates/Features/SDFReflections.hlsl diff --git a/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl b/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl index 0df9abe9e..62e98ed1a 100644 --- a/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl +++ b/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl @@ -9,10 +9,6 @@ #define MATERIAL_REFLECTIONS_SSR 1 #if MATERIAL_REFLECTIONS == MATERIAL_REFLECTIONS_SSR #include "./Flax/SSR.hlsl" -#if USE_GLOBAL_SURFACE_ATLAS -#include "./Flax/GlobalSignDistanceField.hlsl" -#include "./Flax/GI/GlobalSurfaceAtlas.hlsl" -#endif #endif #endif #include "./Flax/Lighting.hlsl" @@ -31,15 +27,6 @@ LightData LocalLights[MAX_LOCAL_LIGHTS]; TextureCube EnvProbe : register(t__SRV__); TextureCube SkyLightTexture : register(t__SRV__); Texture2DArray DirectionalLightShadowMap : register(t__SRV__); -#if USE_GLOBAL_SURFACE_ATLAS -Texture3D GlobalSDFTex : register(t__SRV__); -Texture3D GlobalSDFMip : register(t__SRV__); -ByteAddressBuffer GlobalSurfaceAtlasChunks : register(t__SRV__); -ByteAddressBuffer RWGlobalSurfaceAtlasCulledObjects : register(t__SRV__); -Buffer GlobalSurfaceAtlasObjects : register(t__SRV__); -Texture2D GlobalSurfaceAtlasDepth : register(t__SRV__); -Texture2D GlobalSurfaceAtlasTex : register(t__SRV__); -#endif @4// Forward Shading: Utilities DECLARE_LIGHTSHADOWDATA_ACCESS(DirectionalLightShadow); @5// Forward Shading: Shaders @@ -82,7 +69,7 @@ void PS_Forward( gBuffer.Color = material.Color; gBuffer.Specular = material.Specular; gBuffer.AO = material.AO; - gBuffer.ViewPos = mul(float4(materialInput.WorldPosition, 1), ViewMatrix).xyz; + gBuffer.ViewPos = ViewPos; #if MATERIAL_SHADING_MODEL == SHADING_MODEL_SUBSURFACE gBuffer.CustomData = float4(material.SubsurfaceColor, material.Opacity); #elif MATERIAL_SHADING_MODEL == SHADING_MODEL_FOLIAGE @@ -148,21 +135,12 @@ void PS_Forward( if (hit.z < 0.9f) { // Don't use temporal effect in forward pass - float3 reflectWS = ScreenSpaceReflectionDirection(screenUV, gBuffer, gBufferData.ViewPos); + float3 reflectWS = ScreenSpaceReflectionDirection(screenUV, gBuffer, ViewPos); + float4 surfaceAtlas; - GlobalSDFTrace sdfTrace; - float maxDistance = 100000; - float selfOcclusionBias = GlobalSDF.CascadeVoxelSize[0]; - sdfTrace.Init(gBuffer.WorldPos + gBuffer.Normal * selfOcclusionBias, reflectWS, 0.0f, maxDistance); - GlobalSDFHit sdfHit = RayTraceGlobalSDF(GlobalSDF, GlobalSDFTex, GlobalSDFMip, sdfTrace); - if (sdfHit.IsHit()) - { - float3 hitPosition = sdfHit.GetHitPosition(sdfTrace); - float surfaceThreshold = GetGlobalSurfaceAtlasThreshold(GlobalSDF, sdfHit); - float4 surfaceAtlas = SampleGlobalSurfaceAtlas(GlobalSurfaceAtlas, GlobalSurfaceAtlasChunks, RWGlobalSurfaceAtlasCulledObjects, GlobalSurfaceAtlasObjects, GlobalSurfaceAtlasDepth, GlobalSurfaceAtlasTex, hitPosition, -reflectWS, surfaceThreshold); - + if(TraceSDFSoftwareReflections(gBuffer, reflectWS, surfaceAtlas)){ float3 screenColor = sceneColorTexture.SampleLevel(SamplerPointClamp, hit.xy, 0).rgb; - reflections = lerp(surfaceAtlas, float4(screenColor, 1), hit.z); + reflections = lerp(2 * surfaceAtlas, float4(screenColor, 1), hit.z); } } @@ -174,6 +152,7 @@ void PS_Forward( // Add lighting (apply ambient occlusion) output.rgb += light.rgb * gBuffer.AO; + output = #endif diff --git a/Content/Editor/MaterialTemplates/Features/SDFReflections.hlsl b/Content/Editor/MaterialTemplates/Features/SDFReflections.hlsl new file mode 100644 index 000000000..be3e6c831 --- /dev/null +++ b/Content/Editor/MaterialTemplates/Features/SDFReflections.hlsl @@ -0,0 +1,39 @@ +// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. + +@0// SDF Reflections: Defines +#define USE_GLOBAL_SURFACE_ATLAS 1 +@1// SDF Reflections: Includes +#include "./Flax/GlobalSignDistanceField.hlsl" +#include "./Flax/GI/GlobalSurfaceAtlas.hlsl" +@2// SDF Reflections: Constants +GlobalSDFData GlobalSDF; +GlobalSurfaceAtlasData GlobalSurfaceAtlas; +@3// SDF Reflections: Resources +Texture3D GlobalSDFTex : register(t__SRV__); +Texture3D GlobalSDFMip : register(t__SRV__); +ByteAddressBuffer GlobalSurfaceAtlasChunks : register(t__SRV__); +ByteAddressBuffer RWGlobalSurfaceAtlasCulledObjects : register(t__SRV__); +Buffer GlobalSurfaceAtlasObjects : register(t__SRV__); +Texture2D GlobalSurfaceAtlasDepth : register(t__SRV__); +Texture2D GlobalSurfaceAtlasTex : register(t__SRV__); +@4// SDF Reflections: Utilities +bool TraceSDFSoftwareReflections(GBufferSample gBuffer, float3 reflectWS, out float4 surfaceAtlas) +{ + GlobalSDFTrace sdfTrace; + float maxDistance = 100000; + float selfOcclusionBias = GlobalSDF.CascadeVoxelSize[0]; + sdfTrace.Init(gBuffer.WorldPos + gBuffer.Normal * selfOcclusionBias, reflectWS, 0.0f, maxDistance); + GlobalSDFHit sdfHit = RayTraceGlobalSDF(GlobalSDF, GlobalSDFTex, GlobalSDFMip, sdfTrace); + if (sdfHit.IsHit()) + { + float3 hitPosition = sdfHit.GetHitPosition(sdfTrace); + float surfaceThreshold = GetGlobalSurfaceAtlasThreshold(GlobalSDF, sdfHit); + surfaceAtlas = SampleGlobalSurfaceAtlas(GlobalSurfaceAtlas, GlobalSurfaceAtlasChunks, RWGlobalSurfaceAtlasCulledObjects, GlobalSurfaceAtlasObjects, GlobalSurfaceAtlasDepth, GlobalSurfaceAtlasTex, hitPosition, -reflectWS, surfaceThreshold); + + return true; + } + + return false; +} + +@5// SDF Reflections: Shaders diff --git a/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp b/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp index 31c2f8166..2b4237190 100644 --- a/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp +++ b/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp @@ -53,6 +53,8 @@ void ForwardMaterialShader::Bind(BindParameters& params) // Setup features if ((_info.FeaturesFlags & MaterialFeaturesFlags::GlobalIllumination) != MaterialFeaturesFlags::None) GlobalIlluminationFeature::Bind(params, cb, srv); + if ((_info.FeaturesFlags & MaterialFeaturesFlags::ScreenSpaceReflections) != MaterialFeaturesFlags::None) + SDFReflectionsFeature::Bind(params, cb, srv); ForwardShadingFeature::Bind(params, cb, srv); // Setup parameters diff --git a/Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp b/Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp index d385ec24f..5fa33b10f 100644 --- a/Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp +++ b/Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp @@ -100,15 +100,6 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, SpanUnBindSR(envProbeShaderRegisterIndex); } - // Bind sdf resources if using software reflections - if (!GlobalSignDistanceFieldPass::Instance()->Render(params.RenderContext, params.GPUContext, bindingDataSDF) && - !GlobalSurfaceAtlasPass::Instance()->Render(params.RenderContext, params.GPUContext, bindingDataSurfaceAtlas)) - { - useGlobalSurfaceAtlas = true; - data.GlobalSDF = bindingDataSDF.Constants; - data.GlobalSurfaceAtlas = bindingDataSurfaceAtlas.Constants; - } - // Set local lights data.LocalLightsCount = 0; const BoundingSphere objectBounds(drawCall.ObjectPosition, drawCall.ObjectRadius); @@ -143,13 +134,13 @@ bool LightmapFeature::Bind(MaterialShader::BindParameters& params, Span& c const bool useLightmap = EnumHasAnyFlags(params.RenderContext.View.Flags, ViewFlags::GI) #if USE_EDITOR - && EnableLightmapsUsage + && EnableLightmapsUsage #endif - && drawCall.Surface.Lightmap != nullptr; + && drawCall.Surface.Lightmap != nullptr; if (useLightmap) { // Bind lightmap textures - GPUTexture *lightmap0, *lightmap1, *lightmap2; + GPUTexture* lightmap0, * lightmap1, * lightmap2; drawCall.Features.Lightmap->GetTextures(&lightmap0, &lightmap1, &lightmap2); params.GPUContext->BindSR(srv + 0, lightmap0); params.GPUContext->BindSR(srv + 1, lightmap1); @@ -207,6 +198,61 @@ bool GlobalIlluminationFeature::Bind(MaterialShader::BindParameters& params, Spa return useGI; } +bool SDFReflectionsFeature::Bind(MaterialShader::BindParameters& params, Span& cb, int32& srv) +{ + auto& data = *(Data*)cb.Get(); + ASSERT_LOW_LAYER(cb.Length() >= sizeof(Data)); + + bool useSDFReflections = false; + if (EnumHasAnyFlags(params.RenderContext.View.Flags, ViewFlags::Reflections)) + { + switch (params.RenderContext.List->Settings.ScreenSpaceReflections.TraceMode) + { + case ReflectionsTraceMode::SoftwareTracing: + { + GlobalSignDistanceFieldPass::BindingData bindingDataSDF; + GlobalSurfaceAtlasPass::BindingData bindingDataSurfaceAtlas; + + if (!GlobalSignDistanceFieldPass::Instance()->Get(params.RenderContext.Buffers, bindingDataSDF) && + !GlobalSurfaceAtlasPass::Instance()->Get(params.RenderContext.Buffers, bindingDataSurfaceAtlas)) + { + useSDFReflections = true; + + // Bind DDGI data + data.GlobalSDF = bindingDataSDF.Constants; + data.GlobalSurfaceAtlas = bindingDataSurfaceAtlas.Constants; + + params.GPUContext->BindSR(srv + 0, bindingDataSDF.Texture ? bindingDataSDF.Texture->ViewVolume() : nullptr); + params.GPUContext->BindSR(srv + 1, bindingDataSDF.TextureMip ? bindingDataSDF.TextureMip->ViewVolume() : nullptr); + params.GPUContext->BindSR(srv + 2, bindingDataSurfaceAtlas.Chunks ? bindingDataSurfaceAtlas.Chunks->View() : nullptr); + params.GPUContext->BindSR(srv + 3, bindingDataSurfaceAtlas.CulledObjects ? bindingDataSurfaceAtlas.CulledObjects->View() : nullptr); + params.GPUContext->BindSR(srv + 4, bindingDataSurfaceAtlas.Objects ? bindingDataSurfaceAtlas.Objects->View() : nullptr); + params.GPUContext->BindSR(srv + 5, bindingDataSurfaceAtlas.AtlasDepth->View()); + params.GPUContext->BindSR(srv + 6, bindingDataSurfaceAtlas.AtlasLighting->View()); + } + break; + } + } + } + + if (!useSDFReflections) + { + data.GlobalSDF.CascadesCount = 0; + // Unbind SRVs to prevent issues + params.GPUContext->UnBindSR(srv + 0); + params.GPUContext->UnBindSR(srv + 1); + params.GPUContext->UnBindSR(srv + 2); + params.GPUContext->UnBindSR(srv + 3); + params.GPUContext->UnBindSR(srv + 4); + params.GPUContext->UnBindSR(srv + 5); + params.GPUContext->UnBindSR(srv + 6); + } + + cb = Span(cb.Get() + sizeof(Data), cb.Length() - sizeof(Data)); + srv += SRVs; + return useSDFReflections; +} + #if USE_EDITOR void ForwardShadingFeature::Generate(GeneratorData& data) @@ -234,6 +280,11 @@ void GlobalIlluminationFeature::Generate(GeneratorData& data) data.Template = TEXT("Features/GlobalIllumination.hlsl"); } +void SDFReflectionsFeature::Generate(GeneratorData& data) +{ + data.Template = TEXT("Features/SDFReflections.hlsl"); +} + void DistortionFeature::Generate(GeneratorData& data) { data.Template = TEXT("Features/Distortion.hlsl"); diff --git a/Source/Engine/Graphics/Materials/MaterialShaderFeatures.h b/Source/Engine/Graphics/Materials/MaterialShaderFeatures.h index 0df2e9a2e..5b85353a0 100644 --- a/Source/Engine/Graphics/Materials/MaterialShaderFeatures.h +++ b/Source/Engine/Graphics/Materials/MaterialShaderFeatures.h @@ -6,6 +6,8 @@ #include "Engine/Core/Math/Rectangle.h" #include "Engine/Core/Types/Span.h" #include "Engine/Renderer/GI/DynamicDiffuseGlobalIllumination.h" +#include "Engine/Renderer/GlobalSignDistanceFieldPass.h" +#include "Engine/Renderer/GI/GlobalSurfaceAtlasPass.h" // Material shader features are plugin-based functionalities that are reusable between different material domains. struct MaterialShaderFeature @@ -91,6 +93,25 @@ struct GlobalIlluminationFeature : MaterialShaderFeature #endif }; +// Material shader feature that adds SDF Reflections feature (software reflections). +struct SDFReflectionsFeature : MaterialShaderFeature +{ + enum { SRVs = 7 }; + + PACK_STRUCT(struct Data + { + GlobalSignDistanceFieldPass::ConstantsData GlobalSDF; + GlobalSurfaceAtlasPass::ConstantsData GlobalSurfaceAtlas; + }); + + + + static bool Bind(MaterialShader::BindParameters& params, Span& cb, int32& srv); +#if USE_EDITOR + static void Generate(GeneratorData& data); +#endif +}; + // Material shader feature that adds distortion vectors rendering pass. struct DistortionFeature : MaterialShaderFeature { diff --git a/Source/Engine/Renderer/GI/GlobalSurfaceAtlasPass.cpp b/Source/Engine/Renderer/GI/GlobalSurfaceAtlasPass.cpp index fb0faa27a..f2bc3169d 100644 --- a/Source/Engine/Renderer/GI/GlobalSurfaceAtlasPass.cpp +++ b/Source/Engine/Renderer/GI/GlobalSurfaceAtlasPass.cpp @@ -360,6 +360,17 @@ void GlobalSurfaceAtlasPass::Dispose() _shader = nullptr; } +bool GlobalSurfaceAtlasPass::Get(const RenderBuffers* buffers, BindingData& result) +{ + auto* surfaceAtlasData = buffers ? buffers->FindCustomBuffer(TEXT("GlobalSurfaceAtlas")) : nullptr; + if (surfaceAtlasData && surfaceAtlasData->LastFrameUsed + 1 >= Engine::FrameCount) // Allow to use Surface Atlas from the previous frame (not used currently) + { + result = surfaceAtlasData->Result; + return false; + } + return true; +} + bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* context, BindingData& result) { // Skip if not supported diff --git a/Source/Engine/Renderer/GI/GlobalSurfaceAtlasPass.h b/Source/Engine/Renderer/GI/GlobalSurfaceAtlasPass.h index 443b3a401..45d144767 100644 --- a/Source/Engine/Renderer/GI/GlobalSurfaceAtlasPass.h +++ b/Source/Engine/Renderer/GI/GlobalSurfaceAtlasPass.h @@ -65,6 +65,14 @@ private: void* _currentActorObject; public: + /// + /// Gets the Global Surface Atlas (only if enabled in Graphics Settings). + /// + /// The rendering context buffers. + /// The result Global Surface Atlas data for binding to the shaders. + /// True if there is no valid Global Surface Atlas rendered during this frame, otherwise false. + bool Get(const RenderBuffers* buffers, BindingData& result); + /// /// Renders the Global Surface Atlas. /// diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp index 8cacddf51..87e73871f 100644 --- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp +++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp @@ -199,6 +199,8 @@ bool MaterialGenerator::Generate(WriteStream& source, MaterialInfo& materialInfo ADD_FEATURE(DistortionFeature); if (materialInfo.BlendMode != MaterialBlendMode::Opaque && EnumHasAnyFlags(materialInfo.FeaturesFlags, MaterialFeaturesFlags::GlobalIllumination)) ADD_FEATURE(GlobalIlluminationFeature); + if (materialInfo.BlendMode != MaterialBlendMode::Opaque && EnumHasAnyFlags(materialInfo.FeaturesFlags, MaterialFeaturesFlags::ScreenSpaceReflections)) + ADD_FEATURE(SDFReflectionsFeature); if (materialInfo.BlendMode != MaterialBlendMode::Opaque) ADD_FEATURE(ForwardShadingFeature); break; diff --git a/Source/Shaders/SSR.shader b/Source/Shaders/SSR.shader index ca177ff09..de9cb891c 100644 --- a/Source/Shaders/SSR.shader +++ b/Source/Shaders/SSR.shader @@ -150,8 +150,8 @@ float4 PS_RayTracePass(Quad_VS2PS input) : SV_Target0 float surfaceThreshold = GetGlobalSurfaceAtlasThreshold(GlobalSDF, sdfHit); float4 surfaceAtlas = SampleGlobalSurfaceAtlas(GlobalSurfaceAtlas, GlobalSurfaceAtlasChunks, RWGlobalSurfaceAtlasCulledObjects, GlobalSurfaceAtlasObjects, GlobalSurfaceAtlasDepth, GlobalSurfaceAtlasTex, hitPosition, -reflectWS, surfaceThreshold); // Now the sdf reflection part is significantly darker than the screen space part - // TODO: Maybe multiply surfaceAtlas by a constant to make it brighter - result = lerp(surfaceAtlas, float4(result.rgb, 1), result.a); + // TODO: Maybe multiply surfaceAtlas by a constant to make it brighter, adding 2* looks fine + result = lerp(2 * surfaceAtlas, float4(result.rgb, 1), result.a); } #endif From 14ce4d4394d78808202ac43b6c4bdc612918a26e Mon Sep 17 00:00:00 2001 From: ExMatics HydrogenC <33123710+HydrogenC@users.noreply.github.com> Date: Tue, 18 Jun 2024 21:40:25 +0800 Subject: [PATCH 21/51] Cleanup and fix typo --- Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl | 4 +--- Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl b/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl index 62e98ed1a..c157ff6c2 100644 --- a/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl +++ b/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl @@ -33,8 +33,6 @@ DECLARE_LIGHTSHADOWDATA_ACCESS(DirectionalLightShadow); // Pixel Shader function for Forward Pass META_PS(USE_FORWARD, FEATURE_LEVEL_ES2) -META_PERMUTATION_1(USE_GLOBAL_SURFACE_ATLAS=0) -META_PERMUTATION_1(USE_GLOBAL_SURFACE_ATLAS=1) void PS_Forward( in PixelInput input ,out float4 output : SV_Target0 @@ -69,6 +67,7 @@ void PS_Forward( gBuffer.Color = material.Color; gBuffer.Specular = material.Specular; gBuffer.AO = material.AO; + // gBuffer.ViewPos is the view position in WORLD SPACE gBuffer.ViewPos = ViewPos; #if MATERIAL_SHADING_MODEL == SHADING_MODEL_SUBSURFACE gBuffer.CustomData = float4(material.SubsurfaceColor, material.Opacity); @@ -152,7 +151,6 @@ void PS_Forward( // Add lighting (apply ambient occlusion) output.rgb += light.rgb * gBuffer.AO; - output = #endif diff --git a/Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp b/Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp index 5fa33b10f..94c963b74 100644 --- a/Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp +++ b/Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp @@ -23,8 +23,6 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, Span Date: Tue, 18 Jun 2024 21:47:11 +0800 Subject: [PATCH 22/51] Remove debug code --- Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl | 2 +- Source/Shaders/SSR.shader | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl b/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl index c157ff6c2..914173c03 100644 --- a/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl +++ b/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl @@ -139,7 +139,7 @@ void PS_Forward( if(TraceSDFSoftwareReflections(gBuffer, reflectWS, surfaceAtlas)){ float3 screenColor = sceneColorTexture.SampleLevel(SamplerPointClamp, hit.xy, 0).rgb; - reflections = lerp(2 * surfaceAtlas, float4(screenColor, 1), hit.z); + reflections = lerp(surfaceAtlas, float4(screenColor, 1), hit.z); } } diff --git a/Source/Shaders/SSR.shader b/Source/Shaders/SSR.shader index de9cb891c..4e3a46e51 100644 --- a/Source/Shaders/SSR.shader +++ b/Source/Shaders/SSR.shader @@ -151,7 +151,7 @@ float4 PS_RayTracePass(Quad_VS2PS input) : SV_Target0 float4 surfaceAtlas = SampleGlobalSurfaceAtlas(GlobalSurfaceAtlas, GlobalSurfaceAtlasChunks, RWGlobalSurfaceAtlasCulledObjects, GlobalSurfaceAtlasObjects, GlobalSurfaceAtlasDepth, GlobalSurfaceAtlasTex, hitPosition, -reflectWS, surfaceThreshold); // Now the sdf reflection part is significantly darker than the screen space part // TODO: Maybe multiply surfaceAtlas by a constant to make it brighter, adding 2* looks fine - result = lerp(2 * surfaceAtlas, float4(result.rgb, 1), result.a); + result = lerp(surfaceAtlas, float4(result.rgb, 1), result.a); } #endif From d74b7fb304df94f3a4aa31730d26babc2e2a4d50 Mon Sep 17 00:00:00 2001 From: Nils Hausfeld Date: Tue, 18 Jun 2024 18:40:28 +0200 Subject: [PATCH 23/51] - Set description panel min height to reduce window jittering (workaround) --- Source/Editor/Surface/ContextMenu/VisjectCM.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Source/Editor/Surface/ContextMenu/VisjectCM.cs b/Source/Editor/Surface/ContextMenu/VisjectCM.cs index 8f90e80cd..23ff43364 100644 --- a/Source/Editor/Surface/ContextMenu/VisjectCM.cs +++ b/Source/Editor/Surface/ContextMenu/VisjectCM.cs @@ -897,8 +897,11 @@ namespace FlaxEditor.Surface.ContextMenu _descriptionOutputPanel.Y = panelHeight; panelHeight += Mathf.Max(_descriptionInputPanel.Height, _descriptionOutputPanel.Height); - _descriptionPanel.Height = panelHeight; - Height = 400 + Mathf.RoundToInt(_descriptionPanel.Height); + + // Forcing the description panel to at least have a height of 120 to not make the window size change too much in order to reduce jittering + // TODO: Remove the Mathf.Max and just set the height to panelHeight once the window jitter issue is fixed - Nils + _descriptionPanel.Height = Mathf.Max(120f, panelHeight); + Height = 400 + _descriptionPanel.Height; UpdateWindowSize(); Profiler.EndEvent(); From 3fd4bb622fd0861cb222a05f0ac4e1c84396af18 Mon Sep 17 00:00:00 2001 From: Nils Hausfeld Date: Tue, 18 Jun 2024 18:51:49 +0200 Subject: [PATCH 24/51] - Added editor option to toggle description panel for visual scripting --- Source/Editor/Options/InterfaceOptions.cs | 7 +++++++ Source/Editor/Surface/ContextMenu/VisjectCM.cs | 8 +++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Source/Editor/Options/InterfaceOptions.cs b/Source/Editor/Options/InterfaceOptions.cs index 360d1a7ed..286ec720d 100644 --- a/Source/Editor/Options/InterfaceOptions.cs +++ b/Source/Editor/Options/InterfaceOptions.cs @@ -368,6 +368,13 @@ namespace FlaxEditor.Options [EditorDisplay("Visject"), EditorOrder(550)] public float ConnectionCurvature { get; set; } = 1.0f; + /// + /// Gets or sets the visject connection curvature. + /// + [DefaultValue(true)] + [EditorDisplay("Visject"), EditorOrder(550)] + public bool VisualScriptingDescriptionPanel { get; set; } = true; + private static FontAsset DefaultFont => FlaxEngine.Content.LoadAsyncInternal(EditorAssets.PrimaryFont); private static FontAsset ConsoleFont => FlaxEngine.Content.LoadAsyncInternal(EditorAssets.InconsolataRegularFont); diff --git a/Source/Editor/Surface/ContextMenu/VisjectCM.cs b/Source/Editor/Surface/ContextMenu/VisjectCM.cs index 23ff43364..b25b4c6e0 100644 --- a/Source/Editor/Surface/ContextMenu/VisjectCM.cs +++ b/Source/Editor/Surface/ContextMenu/VisjectCM.cs @@ -58,6 +58,7 @@ namespace FlaxEditor.Surface.ContextMenu // Description panel elements private readonly bool _useDescriptionPanel; + private bool _descriptionPanelVisible; private readonly Panel _descriptionPanel; private readonly Image _descriptionClassImage; private readonly Label _descriptionSignatureLabel; @@ -801,7 +802,7 @@ namespace FlaxEditor.Surface.ContextMenu if(!_useDescriptionPanel) return; - if (archetype == null) + if (archetype == null || !Editor.Instance.Options.Options.Interface.VisualScriptingDescriptionPanel) { HideDescriptionPanel(); return; @@ -903,6 +904,7 @@ namespace FlaxEditor.Surface.ContextMenu _descriptionPanel.Height = Mathf.Max(120f, panelHeight); Height = 400 + _descriptionPanel.Height; UpdateWindowSize(); + _descriptionPanelVisible = true; Profiler.EndEvent(); } @@ -945,10 +947,14 @@ namespace FlaxEditor.Surface.ContextMenu /// private void HideDescriptionPanel() { + if(!_descriptionPanelVisible) + return; + _descriptionInputPanel.RemoveChildren(); _descriptionOutputPanel.RemoveChildren(); Height = 400; UpdateWindowSize(); + _descriptionPanelVisible = false; } /// From 37a3c4dbb508fd5ccf7dc8a48c397d193c2ff6d4 Mon Sep 17 00:00:00 2001 From: Nils Hausfeld Date: Tue, 18 Jun 2024 19:01:53 +0200 Subject: [PATCH 25/51] - Added separator line between description and inputs/outputs --- Source/Editor/Surface/ContextMenu/VisjectCM.cs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/Source/Editor/Surface/ContextMenu/VisjectCM.cs b/Source/Editor/Surface/ContextMenu/VisjectCM.cs index b25b4c6e0..2ebdc1c3b 100644 --- a/Source/Editor/Surface/ContextMenu/VisjectCM.cs +++ b/Source/Editor/Surface/ContextMenu/VisjectCM.cs @@ -60,6 +60,7 @@ namespace FlaxEditor.Surface.ContextMenu private readonly bool _useDescriptionPanel; private bool _descriptionPanelVisible; private readonly Panel _descriptionPanel; + private readonly Panel _descriptionPanelSeparator; private readonly Image _descriptionClassImage; private readonly Label _descriptionSignatureLabel; private readonly Label _descriptionLabel; @@ -279,6 +280,13 @@ namespace FlaxEditor.Surface.ContextMenu }; _descriptionLabel.SetAnchorPreset(AnchorPresets.TopLeft, true); + _descriptionPanelSeparator = new Panel(ScrollBars.None) + { + Parent = _descriptionPanel, + Bounds = new Rectangle(8, Height, Width - 16, 2), + BackgroundColor = Style.Current.BackgroundHighlighted, + }; + _descriptionInputPanel = new VerticalPanel() { Parent = _descriptionPanel, @@ -892,16 +900,18 @@ namespace FlaxEditor.Surface.ContextMenu _descriptionLabel.Y = _descriptionSignatureLabel.Bounds.Bottom + 6f; _descriptionLabel.Text = archetype.Description; - panelHeight += _descriptionLabel.Height + 6f + 18f; + _descriptionPanelSeparator.Y = _descriptionLabel.Bounds.Bottom + 8f; + + panelHeight += _descriptionLabel.Height + 32f; _descriptionInputPanel.Y = panelHeight; _descriptionOutputPanel.Y = panelHeight; panelHeight += Mathf.Max(_descriptionInputPanel.Height, _descriptionOutputPanel.Height); - // Forcing the description panel to at least have a height of 120 to not make the window size change too much in order to reduce jittering + // Forcing the description panel to at least have a minimum height to not make the window size change too much in order to reduce jittering // TODO: Remove the Mathf.Max and just set the height to panelHeight once the window jitter issue is fixed - Nils - _descriptionPanel.Height = Mathf.Max(120f, panelHeight); + _descriptionPanel.Height = Mathf.Max(135f, panelHeight); Height = 400 + _descriptionPanel.Height; UpdateWindowSize(); _descriptionPanelVisible = true; From a808ac5dc8b6aea975121c37140c665ce3365e9f Mon Sep 17 00:00:00 2001 From: Nils Hausfeld Date: Tue, 18 Jun 2024 19:44:07 +0200 Subject: [PATCH 26/51] - Added descriptions to Bitwise OR, XOR - Added description to Boolean XOR, NOR, NAND and updated AND, OR - Minor tooltip text fix --- Source/Editor/Surface/Archetypes/Bitwise.cs | 4 ++-- Source/Editor/Surface/Archetypes/Boolean.cs | 10 +++++----- Source/Editor/Surface/Archetypes/Particles.cs | 2 +- Source/Editor/Surface/ContextMenu/VisjectCMItem.cs | 6 +++--- Source/Editor/Surface/SurfaceNode.cs | 6 +++--- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Source/Editor/Surface/Archetypes/Bitwise.cs b/Source/Editor/Surface/Archetypes/Bitwise.cs index 5b96627f0..92616bcbc 100644 --- a/Source/Editor/Surface/Archetypes/Bitwise.cs +++ b/Source/Editor/Surface/Archetypes/Bitwise.cs @@ -59,8 +59,8 @@ namespace FlaxEditor.Surface.Archetypes { Op1(1, "Bitwise NOT", "Negates the value using bitwise operation", new[] { "!", "~" }), Op2(2, "Bitwise AND", "Performs a bitwise conjunction on two values", new[] { "&" }), - Op2(3, "Bitwise OR", "", new[] { "|" }), - Op2(4, "Bitwise XOR", "", new[] { "^" }), + Op2(3, "Bitwise OR", "Performs a bitwise disjunction on two values", new[] { "|" }), + Op2(4, "Bitwise XOR", "Performs a bitwise exclusive disjunction on two values", new[] { "^" }), }; } } diff --git a/Source/Editor/Surface/Archetypes/Boolean.cs b/Source/Editor/Surface/Archetypes/Boolean.cs index 268d7a360..73db196d6 100644 --- a/Source/Editor/Surface/Archetypes/Boolean.cs +++ b/Source/Editor/Surface/Archetypes/Boolean.cs @@ -58,11 +58,11 @@ namespace FlaxEditor.Surface.Archetypes public static NodeArchetype[] Nodes = { Op1(1, "Boolean NOT", "Negates the boolean value", new[] { "!", "~" }), - Op2(2, "Boolean AND", "Performs a logical conjunction on two values", new[] { "&&" }), - Op2(3, "Boolean OR", "Returns true if either (or both) of its operands is true", new[] { "||" }), - Op2(4, "Boolean XOR", "", new[] { "^" }), - Op2(5, "Boolean NOR", ""), - Op2(6, "Boolean NAND", ""), + Op2(2, "Boolean AND", "Performs a logical conjunction on two values. Returns true if both of its operands are true", new[] { "&&" }), + Op2(3, "Boolean OR", "Performs a logical disjunction on two values. Returns true if either (or both) of its operands is true", new[] { "||" }), + Op2(4, "Boolean XOR", "Performs a logical exclusive disjunction on two values. Returns true if both of its operands are different", new[] { "^" }), + Op2(5, "Boolean NOR", "Performs a logical disjunction on two values and negates it. Returns true if both of its operands are false"), + Op2(6, "Boolean NAND", "Performs a logical conjunction on two values and negates it. Returns true if either (or both) of its operands are false"), }; } } diff --git a/Source/Editor/Surface/Archetypes/Particles.cs b/Source/Editor/Surface/Archetypes/Particles.cs index 9166cb0d9..03df9a0a9 100644 --- a/Source/Editor/Surface/Archetypes/Particles.cs +++ b/Source/Editor/Surface/Archetypes/Particles.cs @@ -122,7 +122,7 @@ namespace FlaxEditor.Surface.Archetypes { Name = module.Title, Tag = module.TypeID, - TooltipText = $"{module.Signature}\n{module.Description}", + TooltipText = $"{(string.IsNullOrEmpty(module.Signature) ? module.Title : module.Signature)}\n{module.Description}", }); } cm.ItemClicked += item => AddModule((ushort)item.Tag); diff --git a/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs b/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs index 370025360..1d7b9fa8b 100644 --- a/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs +++ b/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs @@ -327,9 +327,9 @@ namespace FlaxEditor.Surface.ContextMenu private string GetTooltip() { StringBuilder sb = new StringBuilder(); - if (!string.IsNullOrEmpty(_archetype.Signature)) - sb.Append(_archetype.Signature + "\n"); - sb.Append(_archetype.Description); + sb.Append(string.IsNullOrEmpty(_archetype.Signature) ? _archetype.Title : _archetype.Signature); + if (!string.IsNullOrEmpty(_archetype.Description)) + sb.Append("\n" + _archetype.Description); return sb.ToString(); } diff --git a/Source/Editor/Surface/SurfaceNode.cs b/Source/Editor/Surface/SurfaceNode.cs index 1dbb8424b..10f079579 100644 --- a/Source/Editor/Surface/SurfaceNode.cs +++ b/Source/Editor/Surface/SurfaceNode.cs @@ -855,9 +855,9 @@ namespace FlaxEditor.Surface private string GetTooltip() { StringBuilder sb = new StringBuilder(); - if (!string.IsNullOrEmpty(Archetype.Signature)) - sb.Append(Archetype.Signature + "\n"); - sb.Append(Archetype.Description); + sb.Append(string.IsNullOrEmpty(Archetype.Signature) ? Archetype.Title : Archetype.Signature); + if (!string.IsNullOrEmpty(Archetype.Description)) + sb.Append("\n" + Archetype.Description); return sb.ToString(); } From a5b00fa718c9ce7a4e01ef84f5618ad2abcc3a0b Mon Sep 17 00:00:00 2001 From: ExMatics HydrogenC <33123710+HydrogenC@users.noreply.github.com> Date: Wed, 19 Jun 2024 10:58:27 +0800 Subject: [PATCH 27/51] Resolve problems in code review --- .../MaterialTemplates/Features/ForwardShading.hlsl | 4 ++-- .../MaterialTemplates/Features/SDFReflections.hlsl | 2 +- .../Graphics/Materials/ForwardMaterialShader.cpp | 7 ++++--- .../Tools/MaterialGenerator/MaterialGenerator.cpp | 11 +++++++---- Source/Shaders/GBufferCommon.hlsl | 1 + Source/Shaders/SSR.shader | 2 +- 6 files changed, 16 insertions(+), 11 deletions(-) diff --git a/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl b/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl index 914173c03..dc866c1ea 100644 --- a/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl +++ b/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl @@ -67,8 +67,8 @@ void PS_Forward( gBuffer.Color = material.Color; gBuffer.Specular = material.Specular; gBuffer.AO = material.AO; - // gBuffer.ViewPos is the view position in WORLD SPACE - gBuffer.ViewPos = ViewPos; + // gBuffer.ViewPos is the view space position of the pixel + gBuffer.ViewPos = mul(float4(materialInput.WorldPosition, 1), ViewMatrix).xyz; #if MATERIAL_SHADING_MODEL == SHADING_MODEL_SUBSURFACE gBuffer.CustomData = float4(material.SubsurfaceColor, material.Opacity); #elif MATERIAL_SHADING_MODEL == SHADING_MODEL_FOLIAGE diff --git a/Content/Editor/MaterialTemplates/Features/SDFReflections.hlsl b/Content/Editor/MaterialTemplates/Features/SDFReflections.hlsl index be3e6c831..a7177e686 100644 --- a/Content/Editor/MaterialTemplates/Features/SDFReflections.hlsl +++ b/Content/Editor/MaterialTemplates/Features/SDFReflections.hlsl @@ -20,7 +20,7 @@ Texture2D GlobalSurfaceAtlasTex : register(t__SRV__); bool TraceSDFSoftwareReflections(GBufferSample gBuffer, float3 reflectWS, out float4 surfaceAtlas) { GlobalSDFTrace sdfTrace; - float maxDistance = 100000; + float maxDistance = GLOBAL_SDF_WORLD_SIZE; float selfOcclusionBias = GlobalSDF.CascadeVoxelSize[0]; sdfTrace.Init(gBuffer.WorldPos + gBuffer.Normal * selfOcclusionBias, reflectWS, 0.0f, maxDistance); GlobalSDFHit sdfHit = RayTraceGlobalSDF(GlobalSDF, GlobalSDFTex, GlobalSDFMip, sdfTrace); diff --git a/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp b/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp index 2b4237190..fd9568bcf 100644 --- a/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp +++ b/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp @@ -51,10 +51,11 @@ void ForwardMaterialShader::Bind(BindParameters& params) int32 srv = 2; // Setup features - if ((_info.FeaturesFlags & MaterialFeaturesFlags::GlobalIllumination) != MaterialFeaturesFlags::None) + if ((_info.FeaturesFlags & MaterialFeaturesFlags::GlobalIllumination) != MaterialFeaturesFlags::None) { GlobalIlluminationFeature::Bind(params, cb, srv); - if ((_info.FeaturesFlags & MaterialFeaturesFlags::ScreenSpaceReflections) != MaterialFeaturesFlags::None) - SDFReflectionsFeature::Bind(params, cb, srv); + if ((_info.FeaturesFlags & MaterialFeaturesFlags::ScreenSpaceReflections) != MaterialFeaturesFlags::None) + SDFReflectionsFeature::Bind(params, cb, srv); + } ForwardShadingFeature::Bind(params, cb, srv); // Setup parameters diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp index 87e73871f..bff70e709 100644 --- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp +++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp @@ -197,10 +197,13 @@ bool MaterialGenerator::Generate(WriteStream& source, MaterialInfo& materialInfo ADD_FEATURE(DeferredShadingFeature); if (materialInfo.BlendMode != MaterialBlendMode::Opaque && (materialInfo.FeaturesFlags & MaterialFeaturesFlags::DisableDistortion) == MaterialFeaturesFlags::None) ADD_FEATURE(DistortionFeature); - if (materialInfo.BlendMode != MaterialBlendMode::Opaque && EnumHasAnyFlags(materialInfo.FeaturesFlags, MaterialFeaturesFlags::GlobalIllumination)) - ADD_FEATURE(GlobalIlluminationFeature); - if (materialInfo.BlendMode != MaterialBlendMode::Opaque && EnumHasAnyFlags(materialInfo.FeaturesFlags, MaterialFeaturesFlags::ScreenSpaceReflections)) - ADD_FEATURE(SDFReflectionsFeature); + if (materialInfo.BlendMode != MaterialBlendMode::Opaque && EnumHasAnyFlags(materialInfo.FeaturesFlags, MaterialFeaturesFlags::GlobalIllumination)) { + ADD_FEATURE(GlobalIlluminationFeature); + + // SDF Reflections is only valid when both GI and SSR is enabled + if (materialInfo.BlendMode != MaterialBlendMode::Opaque && EnumHasAnyFlags(materialInfo.FeaturesFlags, MaterialFeaturesFlags::ScreenSpaceReflections)) + ADD_FEATURE(SDFReflectionsFeature); + } if (materialInfo.BlendMode != MaterialBlendMode::Opaque) ADD_FEATURE(ForwardShadingFeature); break; diff --git a/Source/Shaders/GBufferCommon.hlsl b/Source/Shaders/GBufferCommon.hlsl index 88a6c3688..27095f000 100644 --- a/Source/Shaders/GBufferCommon.hlsl +++ b/Source/Shaders/GBufferCommon.hlsl @@ -14,6 +14,7 @@ struct GBufferSample float Metalness; float3 Color; float Specular; + // View space position of pixel, DIFFERENT FROM GBufferData.ViewPos float3 ViewPos; float AO; int ShadingModel; diff --git a/Source/Shaders/SSR.shader b/Source/Shaders/SSR.shader index 4e3a46e51..3aa3cbc60 100644 --- a/Source/Shaders/SSR.shader +++ b/Source/Shaders/SSR.shader @@ -140,7 +140,7 @@ float4 PS_RayTracePass(Quad_VS2PS input) : SV_Target0 float3 reflectWS = ScreenSpaceReflectionDirection(input.TexCoord, gBuffer, gBufferData.ViewPos, TemporalEffect, TemporalTime, BRDFBias); GlobalSDFTrace sdfTrace; - float maxDistance = 100000; + float maxDistance = GLOBAL_SDF_WORLD_SIZE; float selfOcclusionBias = GlobalSDF.CascadeVoxelSize[0]; sdfTrace.Init(gBuffer.WorldPos + gBuffer.Normal * selfOcclusionBias, reflectWS, 0.0f, maxDistance); GlobalSDFHit sdfHit = RayTraceGlobalSDF(GlobalSDF, GlobalSDFTex, GlobalSDFMip, sdfTrace); From cb1324fc2ddb582b35567f5879c5a5fbce263af8 Mon Sep 17 00:00:00 2001 From: Nils Hausfeld Date: Wed, 19 Jun 2024 20:56:25 +0200 Subject: [PATCH 28/51] - Now removing tags from tooltips - Capitalizing the first character of inputs/outpus - Removing & chars from input/output types to make it easier to read - Moving description signature down to make items without a description look less ugly --- .../Modules/SourceCodeEditing/CodeDocsModule.cs | 4 +++- Source/Editor/Surface/ContextMenu/VisjectCM.cs | 17 ++++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/Source/Editor/Modules/SourceCodeEditing/CodeDocsModule.cs b/Source/Editor/Modules/SourceCodeEditing/CodeDocsModule.cs index 610368a82..a26fe9924 100644 --- a/Source/Editor/Modules/SourceCodeEditing/CodeDocsModule.cs +++ b/Source/Editor/Modules/SourceCodeEditing/CodeDocsModule.cs @@ -316,7 +316,9 @@ namespace FlaxEditor.Modules.SourceCodeEditing var memberReader = xmlReader.ReadSubtree(); if (memberReader.ReadToDescendant("summary")) { - result[rawName] = memberReader.ReadInnerXml().Replace('\n', ' ').Trim(); + // Remove and replace them with the captured group (the content of the cref). Additionally, getting rid of prefixes + const string crefPattern = @""; + result[rawName] = Regex.Replace(memberReader.ReadInnerXml(), crefPattern, "$1").Replace('\n', ' ').Trim(); } } } diff --git a/Source/Editor/Surface/ContextMenu/VisjectCM.cs b/Source/Editor/Surface/ContextMenu/VisjectCM.cs index 2ebdc1c3b..b30e726dd 100644 --- a/Source/Editor/Surface/ContextMenu/VisjectCM.cs +++ b/Source/Editor/Surface/ContextMenu/VisjectCM.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; +using System.Text.RegularExpressions; using FlaxEditor.GUI.ContextMenu; using FlaxEditor.GUI.Input; using FlaxEditor.Scripting; @@ -897,8 +898,17 @@ namespace FlaxEditor.Surface.ContextMenu float panelHeight = _descriptionSignatureLabel.Height; - _descriptionLabel.Y = _descriptionSignatureLabel.Bounds.Bottom + 6f; - _descriptionLabel.Text = archetype.Description; + if (string.IsNullOrEmpty(archetype.Description)) + { + _descriptionSignatureLabel.Y = 15; + _descriptionLabel.Text = ""; + } + else + { + _descriptionSignatureLabel.Y = 8; + _descriptionLabel.Y = _descriptionSignatureLabel.Bounds.Bottom + 6f; + _descriptionLabel.Text = Regex.Replace(archetype.Description, @"\s{2,}", "\n"); + } _descriptionPanelSeparator.Y = _descriptionLabel.Bounds.Bottom + 8f; @@ -938,7 +948,8 @@ namespace FlaxEditor.Surface.ContextMenu MouseOverColor = typeColor, AutoFocus = false, }).SetAnchorPreset(AnchorPresets.TopLeft, true); - + + text = (char.ToUpper(text[0]) + text.Substring(1)).Replace("&", ""); var elementText = new Label(16, 0, Width * 0.5f - 32, 16) { Text = text, From d7a0c699904c76005de3c328a77bc0db561e1b65 Mon Sep 17 00:00:00 2001 From: Nils Hausfeld Date: Thu, 20 Jun 2024 00:18:11 +0200 Subject: [PATCH 29/51] - Some cleanup and tooltips --- Source/Editor/Options/InterfaceOptions.cs | 2 +- Source/Editor/Surface/AnimGraphSurface.cs | 2 - Source/Editor/Surface/Archetypes/Constants.cs | 4 +- Source/Editor/Surface/Archetypes/Packing.cs | 49 ++++++++++------- .../Editor/Surface/ContextMenu/VisjectCM.cs | 54 +++++++++---------- Source/Editor/Surface/NodeArchetype.cs | 2 +- Source/Editor/Surface/SurfaceUtils.cs | 3 +- .../VisjectSurfaceContext.Serialization.cs | 2 +- 8 files changed, 61 insertions(+), 57 deletions(-) diff --git a/Source/Editor/Options/InterfaceOptions.cs b/Source/Editor/Options/InterfaceOptions.cs index 286ec720d..d62dc8510 100644 --- a/Source/Editor/Options/InterfaceOptions.cs +++ b/Source/Editor/Options/InterfaceOptions.cs @@ -372,7 +372,7 @@ namespace FlaxEditor.Options /// Gets or sets the visject connection curvature. /// [DefaultValue(true)] - [EditorDisplay("Visject"), EditorOrder(550)] + [EditorDisplay("Visject"), EditorOrder(550), Tooltip("Shows/hides the description panel in the visual scripting context menu.")] public bool VisualScriptingDescriptionPanel { get; set; } = true; private static FontAsset DefaultFont => FlaxEngine.Content.LoadAsyncInternal(EditorAssets.PrimaryFont); diff --git a/Source/Editor/Surface/AnimGraphSurface.cs b/Source/Editor/Surface/AnimGraphSurface.cs index ea0d9d32f..4e8b6f11e 100644 --- a/Source/Editor/Surface/AnimGraphSurface.cs +++ b/Source/Editor/Surface/AnimGraphSurface.cs @@ -197,7 +197,6 @@ namespace FlaxEditor.Surface { Groups = StateMachineGroupArchetypes, CanSpawnNode = (_, _) => true, - Style = Style, }); _cmStateMachineMenu.ShowExpanded = true; } @@ -215,7 +214,6 @@ namespace FlaxEditor.Surface CanSpawnNode = CanUseNodeType, ParametersGetter = null, CustomNodesGroup = GetCustomNodes(), - Style = Style, }); _cmStateMachineTransitionMenu.AddGroup(StateMachineTransitionGroupArchetype, false); } diff --git a/Source/Editor/Surface/Archetypes/Constants.cs b/Source/Editor/Surface/Archetypes/Constants.cs index 8cce34332..59b554e6b 100644 --- a/Source/Editor/Surface/Archetypes/Constants.cs +++ b/Source/Editor/Surface/Archetypes/Constants.cs @@ -7,8 +7,6 @@ using Real = System.Single; #endif using System; -using System.Collections; -using System.Collections.Generic; using System.Linq; using FlaxEditor.CustomEditors.Editors; using FlaxEditor.GUI; @@ -468,7 +466,7 @@ namespace FlaxEditor.Surface.Archetypes internal static void GetInputOutputDescription(NodeArchetype nodeArch, out (string, ScriptType)[] inputs, out (string, ScriptType)[] outputs) { inputs = null; - outputs = [("", new ScriptType(typeof(Dictionary)))]; + outputs = [("", new ScriptType(typeof(System.Collections.Generic.Dictionary)))]; } } diff --git a/Source/Editor/Surface/Archetypes/Packing.cs b/Source/Editor/Surface/Archetypes/Packing.cs index 5e84d615a..88ed6a64d 100644 --- a/Source/Editor/Surface/Archetypes/Packing.cs +++ b/Source/Editor/Surface/Archetypes/Packing.cs @@ -248,17 +248,24 @@ namespace FlaxEditor.Surface.Archetypes internal static void GetInputOutputDescription(NodeArchetype nodeArch, out (string, ScriptType)[] inputs, out (string, ScriptType)[] outputs) { - var type = TypeUtils.GetType((string)nodeArch.DefaultValues[0]); - outputs = [(type.Name, type)]; - - var fields = type.GetMembers(BindingFlags.Public | BindingFlags.Instance).Where(x => x.IsField).ToArray(); - var fieldsLength = fields.Length; - inputs = new (string, ScriptType)[fieldsLength]; - for (var i = 0; i < fieldsLength; i++) + var typeName = (string)nodeArch.DefaultValues[0]; + var type = TypeUtils.GetType(typeName); + if (type) { - var field = fields[i]; - inputs[i] = (field.Name, field.ValueType); + var fields = type.GetMembers(BindingFlags.Public | BindingFlags.Instance).Where(x => x.IsField).ToArray(); + var fieldsLength = fields.Length; + inputs = new (string, ScriptType)[fieldsLength]; + for (var i = 0; i < fieldsLength; i++) + { + var field = fields[i]; + inputs[i] = (field.Name, field.ValueType); + } + + outputs = [(type.Name, type)]; } + + inputs = null; + outputs = null; } } @@ -301,17 +308,23 @@ namespace FlaxEditor.Surface.Archetypes internal static void GetInputOutputDescription(NodeArchetype nodeArch, out (string, ScriptType)[] inputs, out (string, ScriptType)[] outputs) { - var type = TypeUtils.GetType((string)nodeArch.DefaultValues[0]); - inputs = [(type.Name, type)]; - - var fields = type.GetMembers(BindingFlags.Public | BindingFlags.Instance).Where(x => x.IsField).ToArray(); - var fieldsLength = fields.Length; - outputs = new (string, ScriptType)[fieldsLength]; - for (var i = 0; i < fieldsLength; i++) + var typeName = (string)nodeArch.DefaultValues[0]; + var type = TypeUtils.GetType(typeName); + if (type) { - var field = fields[i]; - outputs[i] = (field.Name, field.ValueType); + inputs = [(type.Name, type)]; + + var fields = type.GetMembers(BindingFlags.Public | BindingFlags.Instance).Where(x => x.IsField).ToArray(); + var fieldsLength = fields.Length; + outputs = new (string, ScriptType)[fieldsLength]; + for (var i = 0; i < fieldsLength; i++) + { + var field = fields[i]; + outputs[i] = (field.Name, field.ValueType); + } } + inputs = null; + outputs = null; } } diff --git a/Source/Editor/Surface/ContextMenu/VisjectCM.cs b/Source/Editor/Surface/ContextMenu/VisjectCM.cs index b30e726dd..d6dd852b4 100644 --- a/Source/Editor/Surface/ContextMenu/VisjectCM.cs +++ b/Source/Editor/Surface/ContextMenu/VisjectCM.cs @@ -2,14 +2,11 @@ using System; using System.Collections.Generic; -using System.IO; using System.Linq; -using System.Reflection; using System.Text.RegularExpressions; using FlaxEditor.GUI.ContextMenu; using FlaxEditor.GUI.Input; using FlaxEditor.Scripting; -using FlaxEditor.Surface.Archetypes; using FlaxEngine; using FlaxEngine.GUI; using FlaxEngine.Utilities; @@ -62,13 +59,12 @@ namespace FlaxEditor.Surface.ContextMenu private bool _descriptionPanelVisible; private readonly Panel _descriptionPanel; private readonly Panel _descriptionPanelSeparator; - private readonly Image _descriptionClassImage; + private readonly Image _descriptionDeclaringClassImage; private readonly Label _descriptionSignatureLabel; private readonly Label _descriptionLabel; - private readonly SurfaceStyle _surfaceStyle; private readonly VerticalPanel _descriptionInputPanel; private readonly VerticalPanel _descriptionOutputPanel; - + private readonly SurfaceStyle _surfaceStyle; private VisjectCMItem _selectedItem; /// @@ -251,7 +247,7 @@ namespace FlaxEditor.Surface.ContextMenu }; var spriteHandle = info.Style.Icons.BoxClose; - _descriptionClassImage = new Image(8, 12, 20, 20) + _descriptionDeclaringClassImage = new Image(8, 12, 20, 20) { Parent = _descriptionPanel, Brush = new SpriteBrush(spriteHandle), @@ -816,12 +812,12 @@ namespace FlaxEditor.Surface.ContextMenu HideDescriptionPanel(); return; } - + Profiler.BeginEvent("VisjectCM.SetDescriptionPanelArchetype"); - + _descriptionInputPanel.RemoveChildren(); _descriptionOutputPanel.RemoveChildren(); - + ScriptType declaringType; if (archetype.Tag is ScriptMemberInfo memberInfo) { @@ -844,7 +840,7 @@ namespace FlaxEditor.Surface.ContextMenu else AddInputOutputElement(archetype, memberInfo.ValueType, true, $"Return ({memberInfo.ValueType.Name})"); } - + for(int i = 0; i < memberInfo.ParametersCount; i++) { var param = memberInfo.GetParameters()[i]; @@ -858,13 +854,13 @@ namespace FlaxEditor.Surface.ContextMenu if (archetype.GetInputOutputDescription != null) { - archetype.GetInputOutputDescription.Invoke(archetype, out (string, ScriptType)[] inputs, out (string, ScriptType)[] outputs); + archetype.GetInputOutputDescription.Invoke(archetype, out (string Name, ScriptType Type)[] inputs, out (string Name, ScriptType Type)[] outputs); if (inputs != null) { for (int i = 0; i < inputs.Length; i++) { - AddInputOutputElement(archetype, inputs[i].Item2, false, $"{inputs[i].Item1} ({inputs[i].Item2.Name})"); + AddInputOutputElement(archetype, inputs[i].Type, false, $"{inputs[i].Name} ({inputs[i].Type.Name})"); } } @@ -872,7 +868,7 @@ namespace FlaxEditor.Surface.ContextMenu { for (int i = 0; i < outputs.Length; i++) { - AddInputOutputElement(archetype, outputs[i].Item2, true, $"{outputs[i].Item1} ({outputs[i].Item2.Name})"); + AddInputOutputElement(archetype, outputs[i].Type, true, $"{outputs[i].Name} ({outputs[i].Type.Name})"); } } } @@ -880,22 +876,22 @@ namespace FlaxEditor.Surface.ContextMenu { foreach (var element in archetype.Elements) { - if (element.Type is NodeElementType.Input or NodeElementType.Output) - { - bool isOutput = element.Type == NodeElementType.Output; - if (element.ConnectionsType == null) - AddInputOutputElement(archetype, element.ConnectionsType, isOutput, $"{element.Text} ({archetype.ConnectionsHints.ToString()})"); - else - AddInputOutputElement(archetype, element.ConnectionsType, isOutput, $"{element.Text} ({element.ConnectionsType.Name})"); - } + if (element.Type is not (NodeElementType.Input or NodeElementType.Output)) + continue; + + bool isOutput = element.Type == NodeElementType.Output; + if (element.ConnectionsType == null) + AddInputOutputElement(archetype, element.ConnectionsType, isOutput, $"{element.Text} ({archetype.ConnectionsHints.ToString()})"); + else + AddInputOutputElement(archetype, element.ConnectionsType, isOutput, $"{element.Text} ({element.ConnectionsType.Name})"); } } } _surfaceStyle.GetConnectionColor(declaringType, archetype.ConnectionsHints, out var declaringTypeColor); - _descriptionClassImage.Color = declaringTypeColor; - _descriptionClassImage.MouseOverColor = declaringTypeColor; - + _descriptionDeclaringClassImage.Color = declaringTypeColor; + _descriptionDeclaringClassImage.MouseOverColor = declaringTypeColor; + float panelHeight = _descriptionSignatureLabel.Height; if (string.IsNullOrEmpty(archetype.Description)) @@ -911,21 +907,21 @@ namespace FlaxEditor.Surface.ContextMenu } _descriptionPanelSeparator.Y = _descriptionLabel.Bounds.Bottom + 8f; - + panelHeight += _descriptionLabel.Height + 32f; _descriptionInputPanel.Y = panelHeight; _descriptionOutputPanel.Y = panelHeight; panelHeight += Mathf.Max(_descriptionInputPanel.Height, _descriptionOutputPanel.Height); - + // Forcing the description panel to at least have a minimum height to not make the window size change too much in order to reduce jittering // TODO: Remove the Mathf.Max and just set the height to panelHeight once the window jitter issue is fixed - Nils _descriptionPanel.Height = Mathf.Max(135f, panelHeight); Height = 400 + _descriptionPanel.Height; UpdateWindowSize(); _descriptionPanelVisible = true; - + Profiler.EndEvent(); } @@ -962,7 +958,7 @@ namespace FlaxEditor.Surface.ContextMenu elementPanel.AddChild(elementText); elementPanel.Height = elementText.Height; } - + /// /// Hides the description panel and resets the context menu to its original size /// diff --git a/Source/Editor/Surface/NodeArchetype.cs b/Source/Editor/Surface/NodeArchetype.cs index 63d731b72..609b7b5f7 100644 --- a/Source/Editor/Surface/NodeArchetype.cs +++ b/Source/Editor/Surface/NodeArchetype.cs @@ -97,7 +97,7 @@ namespace FlaxEditor.Surface /// /// Gets description of inputs and outputs of the archetype. Used for special cases for the description panel. /// - public delegate void GetElementsDescriptionFunc(NodeArchetype nodeArch, out (string, ScriptType)[] inputs, out (string, ScriptType)[] outputs); + public delegate void GetElementsDescriptionFunc(NodeArchetype nodeArch, out (string Name, ScriptType Type)[] inputs, out (string Name, ScriptType Type)[] outputs); /// /// Unique node type ID within a single group. diff --git a/Source/Editor/Surface/SurfaceUtils.cs b/Source/Editor/Surface/SurfaceUtils.cs index 6bc834b0a..ad77aa510 100644 --- a/Source/Editor/Surface/SurfaceUtils.cs +++ b/Source/Editor/Surface/SurfaceUtils.cs @@ -468,7 +468,6 @@ namespace FlaxEditor.Surface sb.Append('.'); sb.Append(name); - // Is a method and not a property if (member.IsMethod) { sb.Append('('); @@ -512,7 +511,7 @@ namespace FlaxEditor.Surface return GetVisualScriptMemberShortDescription(property[0]); } } - + return Editor.Instance.CodeDocs.GetTooltip(member); } diff --git a/Source/Editor/Surface/VisjectSurfaceContext.Serialization.cs b/Source/Editor/Surface/VisjectSurfaceContext.Serialization.cs index 97122f872..7ddbc72db 100644 --- a/Source/Editor/Surface/VisjectSurfaceContext.Serialization.cs +++ b/Source/Editor/Surface/VisjectSurfaceContext.Serialization.cs @@ -51,7 +51,7 @@ namespace FlaxEditor.Surface { TypeID = originalNodeId, Title = "Missing Node :(", - Signature = ":(", + Signature = "Missing Node :(", Description = ":(", Flags = NodeFlags.AllGraphs, Size = new Float2(200, 70), From db17d8d0ced79d82aaa6108e62b6267d5693fa32 Mon Sep 17 00:00:00 2001 From: Nils Hausfeld Date: Fri, 21 Jun 2024 20:26:24 +0200 Subject: [PATCH 30/51] - Comments, cleanup and a bit of refactoring --- .../Editor/Surface/ContextMenu/VisjectCM.cs | 65 ++++++++++--------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/Source/Editor/Surface/ContextMenu/VisjectCM.cs b/Source/Editor/Surface/ContextMenu/VisjectCM.cs index d6dd852b4..2d22b2e3f 100644 --- a/Source/Editor/Surface/ContextMenu/VisjectCM.cs +++ b/Source/Editor/Surface/ContextMenu/VisjectCM.cs @@ -41,6 +41,9 @@ namespace FlaxEditor.Surface.ContextMenu /// TThe list of surface parameters or null if failed (readonly). public delegate List ParameterGetterDelegate(); + private const float DefaultWidth = 300; + private const float DefaultHeight = 400; + private readonly List _groups = new List(16); private CheckBox _contextSensitiveToggle; private bool _contextSensitiveSearchEnabled = true; @@ -164,7 +167,7 @@ namespace FlaxEditor.Surface.ContextMenu _surfaceStyle = info.Style; // Context menu dimensions - Size = new Float2(_useDescriptionPanel ? 350 : 300, 400); + Size = new Float2(_useDescriptionPanel ? DefaultWidth + 50f : DefaultWidth, DefaultHeight); var headerPanel = new Panel(ScrollBars.None) { @@ -236,7 +239,7 @@ namespace FlaxEditor.Surface.ContextMenu }; _groupsPanel = panel2; - // Create description panel if enabled + // Create description panel elements only when description panel is about to be used if (_useDescriptionPanel) { _descriptionPanel = new Panel(ScrollBars.None) @@ -246,21 +249,20 @@ namespace FlaxEditor.Surface.ContextMenu BackgroundColor = Style.Current.BackgroundNormal, }; - var spriteHandle = info.Style.Icons.BoxClose; _descriptionDeclaringClassImage = new Image(8, 12, 20, 20) { Parent = _descriptionPanel, - Brush = new SpriteBrush(spriteHandle), + Brush = new SpriteBrush(info.Style.Icons.BoxClose), }; - var signatureFontReference = new FontReference(Style.Current.FontMedium.Asset, 9f); + var descriptionFontReference = new FontReference(Style.Current.FontMedium.Asset, 9f); _descriptionSignatureLabel = new Label(32, 8, Width - 40, 0) { Parent = _descriptionPanel, HorizontalAlignment = TextAlignment.Near, VerticalAlignment = TextAlignment.Near, Wrapping = TextWrapping.WrapWords, - Font = signatureFontReference, + Font = descriptionFontReference, Bold = true, AutoHeight = true, }; @@ -272,7 +274,7 @@ namespace FlaxEditor.Surface.ContextMenu HorizontalAlignment = TextAlignment.Near, VerticalAlignment = TextAlignment.Near, Wrapping = TextWrapping.WrapWords, - Font = signatureFontReference, + Font = descriptionFontReference, AutoHeight = true, }; _descriptionLabel.SetAnchorPreset(AnchorPresets.TopLeft, true); @@ -818,6 +820,7 @@ namespace FlaxEditor.Surface.ContextMenu _descriptionInputPanel.RemoveChildren(); _descriptionOutputPanel.RemoveChildren(); + // Fetch description and information from the memberInfo - mainly from nodes that got fetched asynchronously by the visual scripting editor ScriptType declaringType; if (archetype.Tag is ScriptMemberInfo memberInfo) { @@ -830,11 +833,14 @@ namespace FlaxEditor.Surface.ContextMenu declaringType = memberInfo.DeclaringType; _descriptionSignatureLabel.Text = memberInfo.DeclaringType + "." + name; + // We have to add the Instance information manually for members that aren't static if (!memberInfo.IsStatic) AddInputOutputElement(archetype, declaringType, false, $"Instance ({memberInfo.DeclaringType.Name})"); + // We also have to manually add the Return information as well. if (memberInfo.ValueType != ScriptType.Null && memberInfo.ValueType != ScriptType.Void) { + // When a field has a setter we don't want it to show the input as a return output. if (memberInfo.IsField && archetype.Title.StartsWith("Set ")) AddInputOutputElement(archetype, memberInfo.ValueType, false, $"({memberInfo.ValueType.Name})"); else @@ -849,27 +855,24 @@ namespace FlaxEditor.Surface.ContextMenu } else { + // Try to fetch as many informations as possible from the predefined hardcoded nodes _descriptionSignatureLabel.Text = string.IsNullOrEmpty(archetype.Signature) ? archetype.Title : archetype.Signature; declaringType = archetype.DefaultType; + // Some nodes are more delicate. Like Arrays or Dictionaries. In this case we let them fetch the inputs/outputs for us. + // Otherwise, it is not possible to show a proper return type on some nodes. if (archetype.GetInputOutputDescription != null) { - archetype.GetInputOutputDescription.Invoke(archetype, out (string Name, ScriptType Type)[] inputs, out (string Name, ScriptType Type)[] outputs); + archetype.GetInputOutputDescription.Invoke(archetype, out var inputs, out var outputs); - if (inputs != null) + foreach (var input in inputs ?? []) { - for (int i = 0; i < inputs.Length; i++) - { - AddInputOutputElement(archetype, inputs[i].Type, false, $"{inputs[i].Name} ({inputs[i].Type.Name})"); - } + AddInputOutputElement(archetype, input.Type, false, $"{input.Name} ({input.Type.Name})"); } - if (outputs != null) + foreach (var output in outputs ?? []) { - for (int i = 0; i < outputs.Length; i++) - { - AddInputOutputElement(archetype, outputs[i].Type, true, $"{outputs[i].Name} ({outputs[i].Type.Name})"); - } + AddInputOutputElement(archetype, output.Type, true, $"{output.Name} ({output.Type.Name})"); } } else @@ -879,21 +882,21 @@ namespace FlaxEditor.Surface.ContextMenu if (element.Type is not (NodeElementType.Input or NodeElementType.Output)) continue; - bool isOutput = element.Type == NodeElementType.Output; - if (element.ConnectionsType == null) - AddInputOutputElement(archetype, element.ConnectionsType, isOutput, $"{element.Text} ({archetype.ConnectionsHints.ToString()})"); - else - AddInputOutputElement(archetype, element.ConnectionsType, isOutput, $"{element.Text} ({element.ConnectionsType.Name})"); + var typeText = element.ConnectionsType ? element.ConnectionsType.Name : archetype.ConnectionsHints.ToString(); + AddInputOutputElement(archetype, element.ConnectionsType, element.Type == NodeElementType.Output, $"{element.Text} ({typeText})"); } } } + // Set declaring type icon color _surfaceStyle.GetConnectionColor(declaringType, archetype.ConnectionsHints, out var declaringTypeColor); _descriptionDeclaringClassImage.Color = declaringTypeColor; _descriptionDeclaringClassImage.MouseOverColor = declaringTypeColor; + // Calculate the description panel height. (I am doing this manually since working with autoSize on horizontal/vertical panels didn't work, especially with nesting - Nils) float panelHeight = _descriptionSignatureLabel.Height; + // If thee is no description we move the signature label down a bit to align it with the icon. Just a cosmetic check if (string.IsNullOrEmpty(archetype.Description)) { _descriptionSignatureLabel.Y = 15; @@ -903,22 +906,21 @@ namespace FlaxEditor.Surface.ContextMenu { _descriptionSignatureLabel.Y = 8; _descriptionLabel.Y = _descriptionSignatureLabel.Bounds.Bottom + 6f; + // Replacing multiple whitespaces with a linebreak for better readability. (Mainly doing this because the ToolTip fetching system replaces linebreaks with whitespaces - Nils) _descriptionLabel.Text = Regex.Replace(archetype.Description, @"\s{2,}", "\n"); } + // Some padding and moving elements around _descriptionPanelSeparator.Y = _descriptionLabel.Bounds.Bottom + 8f; - panelHeight += _descriptionLabel.Height + 32f; - _descriptionInputPanel.Y = panelHeight; _descriptionOutputPanel.Y = panelHeight; - panelHeight += Mathf.Max(_descriptionInputPanel.Height, _descriptionOutputPanel.Height); // Forcing the description panel to at least have a minimum height to not make the window size change too much in order to reduce jittering // TODO: Remove the Mathf.Max and just set the height to panelHeight once the window jitter issue is fixed - Nils _descriptionPanel.Height = Mathf.Max(135f, panelHeight); - Height = 400 + _descriptionPanel.Height; + Height = DefaultHeight + _descriptionPanel.Height; UpdateWindowSize(); _descriptionPanelVisible = true; @@ -927,6 +929,7 @@ namespace FlaxEditor.Surface.ContextMenu private void AddInputOutputElement(NodeArchetype nodeArchetype, ScriptType type, bool isOutput, string text) { + // Using a panel instead of a vertical panel because auto sizing is unreliable - so we are doing this manually here as well var elementPanel = new Panel() { Parent = isOutput ? _descriptionOutputPanel : _descriptionInputPanel, @@ -934,17 +937,17 @@ namespace FlaxEditor.Surface.ContextMenu Height = 16, AnchorPreset = AnchorPresets.TopLeft }; - - var sprite = _surfaceStyle.Icons.BoxOpen; + _surfaceStyle.GetConnectionColor(type, nodeArchetype.ConnectionsHints, out var typeColor); elementPanel.AddChild(new Image(2, 0, 12, 12) { - Brush = new SpriteBrush(sprite), + Brush = new SpriteBrush(_surfaceStyle.Icons.BoxOpen), Color = typeColor, MouseOverColor = typeColor, AutoFocus = false, }).SetAnchorPreset(AnchorPresets.TopLeft, true); + // Forcing the first letter to be capital and removing the '&' char from pointer-references text = (char.ToUpper(text[0]) + text.Substring(1)).Replace("&", ""); var elementText = new Label(16, 0, Width * 0.5f - 32, 16) { @@ -969,7 +972,7 @@ namespace FlaxEditor.Surface.ContextMenu _descriptionInputPanel.RemoveChildren(); _descriptionOutputPanel.RemoveChildren(); - Height = 400; + Height = DefaultHeight; UpdateWindowSize(); _descriptionPanelVisible = false; } From a8bd59c07f662b3c4a73c9268a261fb7cc3b98dd Mon Sep 17 00:00:00 2001 From: Nils Hausfeld Date: Fri, 21 Jun 2024 20:40:39 +0200 Subject: [PATCH 31/51] - Fixed regression where pack/unpack nodes didn't return any inputs/outputs --- Source/Editor/Surface/Archetypes/Packing.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Source/Editor/Surface/Archetypes/Packing.cs b/Source/Editor/Surface/Archetypes/Packing.cs index 88ed6a64d..99899e033 100644 --- a/Source/Editor/Surface/Archetypes/Packing.cs +++ b/Source/Editor/Surface/Archetypes/Packing.cs @@ -262,6 +262,7 @@ namespace FlaxEditor.Surface.Archetypes } outputs = [(type.Name, type)]; + return; } inputs = null; @@ -322,7 +323,9 @@ namespace FlaxEditor.Surface.Archetypes var field = fields[i]; outputs[i] = (field.Name, field.ValueType); } + return; } + inputs = null; outputs = null; } From ef5d4013d3143ba1264474a4e3b1fe5f60c50c80 Mon Sep 17 00:00:00 2001 From: Nils Hausfeld Date: Fri, 21 Jun 2024 20:45:22 +0200 Subject: [PATCH 32/51] - Increased min description panel height a tiny bit to make 4 input/output elements fit without causing jittering / flickering --- Source/Editor/Surface/ContextMenu/VisjectCM.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Editor/Surface/ContextMenu/VisjectCM.cs b/Source/Editor/Surface/ContextMenu/VisjectCM.cs index 2d22b2e3f..691bef2dd 100644 --- a/Source/Editor/Surface/ContextMenu/VisjectCM.cs +++ b/Source/Editor/Surface/ContextMenu/VisjectCM.cs @@ -919,7 +919,7 @@ namespace FlaxEditor.Surface.ContextMenu // Forcing the description panel to at least have a minimum height to not make the window size change too much in order to reduce jittering // TODO: Remove the Mathf.Max and just set the height to panelHeight once the window jitter issue is fixed - Nils - _descriptionPanel.Height = Mathf.Max(135f, panelHeight); + _descriptionPanel.Height = Mathf.Max(140f, panelHeight); Height = DefaultHeight + _descriptionPanel.Height; UpdateWindowSize(); _descriptionPanelVisible = true; From 240ddbcde3411fccb4dc6f43d8a669b8c46c4bb8 Mon Sep 17 00:00:00 2001 From: Nils Hausfeld Date: Fri, 21 Jun 2024 20:52:14 +0200 Subject: [PATCH 33/51] - Minor cleanup --- Source/Editor/Surface/ContextMenu/VisjectCMItem.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs b/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs index 1d7b9fa8b..792579b67 100644 --- a/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs +++ b/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs @@ -359,8 +359,9 @@ namespace FlaxEditor.Surface.ContextMenu /// public override void OnMouseEnter(Float2 location) { - base.OnMouseEnter(location); Group.ContextMenu.SetDescriptionPanelArchetype(_archetype); + + base.OnMouseEnter(location); } /// From 4d0dda19b9653999702545add46fd9ddbea488e1 Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Wed, 17 Jul 2024 00:23:04 +0300 Subject: [PATCH 34/51] Improve engine responsiveness when not focused --- Source/Engine/Engine/Engine.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Source/Engine/Engine/Engine.cpp b/Source/Engine/Engine/Engine.cpp index 20063ca0f..af62e0b6e 100644 --- a/Source/Engine/Engine/Engine.cpp +++ b/Source/Engine/Engine/Engine.cpp @@ -195,6 +195,12 @@ int32 Engine::Main(const Char* cmdLine) // Use the same time for all ticks to improve synchronization const double time = Platform::GetTimeSeconds(); + // Update application (will gather data and other platform related events) + { + PROFILE_CPU_NAMED("Platform.Tick"); + Platform::Tick(); + } + // Update game logic if (Time::OnBeginUpdate(time)) { @@ -302,12 +308,6 @@ void Engine::OnUpdate() UpdateCount++; - // Update application (will gather data and other platform related events) - { - PROFILE_CPU_NAMED("Platform.Tick"); - Platform::Tick(); - } - const auto mainWindow = MainWindow; #if !USE_EDITOR From e05eedfc76d88a2b54ce2df944d19edb0f67d954 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Thu, 25 Jul 2024 17:28:55 -0500 Subject: [PATCH 35/51] Force rebuild on proxy changes if rebuild is true --- Source/Editor/Modules/ContentDatabaseModule.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Source/Editor/Modules/ContentDatabaseModule.cs b/Source/Editor/Modules/ContentDatabaseModule.cs index 0e4e96d30..8672c7e64 100644 --- a/Source/Editor/Modules/ContentDatabaseModule.cs +++ b/Source/Editor/Modules/ContentDatabaseModule.cs @@ -737,7 +737,7 @@ namespace FlaxEditor.Modules { Proxy.Insert(0, proxy); if (rebuild) - Rebuild(); + Rebuild(true); } /// @@ -749,7 +749,7 @@ namespace FlaxEditor.Modules { Proxy.Remove(proxy); if (rebuild) - Rebuild(); + Rebuild(true); } /// @@ -1275,10 +1275,6 @@ namespace FlaxEditor.Modules } _dirtyNodes.Clear(); } - - // Lazy-rebuilds - if (_rebuildFlag) - RebuildInternal(); } /// From 074751f91f41114d769adbb235cffeae51e7804a Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Thu, 25 Jul 2024 18:23:26 -0500 Subject: [PATCH 36/51] Re-add lazy rebuilds --- Source/Editor/Modules/ContentDatabaseModule.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Source/Editor/Modules/ContentDatabaseModule.cs b/Source/Editor/Modules/ContentDatabaseModule.cs index 8672c7e64..6d2821a28 100644 --- a/Source/Editor/Modules/ContentDatabaseModule.cs +++ b/Source/Editor/Modules/ContentDatabaseModule.cs @@ -1275,6 +1275,12 @@ namespace FlaxEditor.Modules } _dirtyNodes.Clear(); } + + // Lazy-rebuilds + if (_rebuildFlag) + { + RebuildInternal(); + } } /// From 1a9c3ba3ffc01c6759be72d7dfb2740732adc9f3 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Sat, 27 Jul 2024 09:28:56 -0500 Subject: [PATCH 37/51] Add options menu to json assets --- .../Editor/Windows/Assets/JsonAssetWindow.cs | 49 ++++++++++++++++++- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/Source/Editor/Windows/Assets/JsonAssetWindow.cs b/Source/Editor/Windows/Assets/JsonAssetWindow.cs index 86cf78ffc..c86846f7c 100644 --- a/Source/Editor/Windows/Assets/JsonAssetWindow.cs +++ b/Source/Editor/Windows/Assets/JsonAssetWindow.cs @@ -4,6 +4,7 @@ using System; using FlaxEditor.Content; using FlaxEditor.CustomEditors; using FlaxEditor.GUI; +using FlaxEditor.GUI.ContextMenu; using FlaxEngine; using FlaxEngine.GUI; @@ -24,6 +25,7 @@ namespace FlaxEditor.Windows.Assets private object _object; private bool _isRegisteredForScriptsReload; private Label _typeText; + private ToolStripButton _optionsButton; /// /// Gets the instance of the Json asset object that is being edited. @@ -139,6 +141,29 @@ namespace FlaxEditor.Windows.Assets if (_typeText != null) _typeText.Dispose(); + + // Get content item for options button + object buttonTag = null; + var allTypes = Editor.CodeEditing.All.Get(); + foreach (var type in allTypes) + { + if (type.TypeName.Equals(Asset.DataTypeName, StringComparison.Ordinal)) + { + buttonTag = type.ContentItem; + break; + } + } + + _optionsButton = new ToolStripButton(_toolstrip.ItemsHeight, ref Editor.Icons.Settings12) + { + AnchorPreset = AnchorPresets.TopRight, + Tag = buttonTag, + Parent = this, + }; + _optionsButton.LocalX -= (_optionsButton.Width + 4); + _optionsButton.LocalY += (_toolstrip.Height - _optionsButton.Height) * 0.5f; + _optionsButton.Clicked += OpenOptionsContextMenu; + var typeText = new ClickableLabel { Text = $"{Asset.DataTypeName}", @@ -147,9 +172,8 @@ namespace FlaxEditor.Windows.Assets AutoWidth = true, Parent = this, }; - typeText.LocalX += -(typeText.Width + 4); + typeText.LocalX += -(typeText.Width + _optionsButton.Width + 8); typeText.LocalY += (_toolstrip.Height - typeText.Height) * 0.5f; - typeText.RightClick = () => Clipboard.Text = Asset.DataTypeName; _typeText = typeText; _undo.Clear(); @@ -165,6 +189,27 @@ namespace FlaxEditor.Windows.Assets base.OnAssetLoaded(); } + private void OpenOptionsContextMenu() + { + var cm = new ContextMenu(); + cm.AddButton("Copy type name", () => Clipboard.Text = Asset.DataTypeName); + cm.AddButton("Copy Asset data", () => Clipboard.Text = Asset.Data); + cm.AddSeparator(); + if (_optionsButton.Tag is ContentItem item) + { + cm.AddButton("Edit Asset code", () => + { + Editor.Instance.ContentEditing.Open(item); + }); + cm.AddButton("Show Asset code item in content window", () => + { + Editor.Instance.Windows.ContentWin.Select(item); + }); + } + + cm.Show(_optionsButton, _optionsButton.PointFromScreen(Input.MouseScreenPosition)); + } + /// protected override void OnAssetLoadFailed() { From 728401b67c30daa2914cfa20fe84291500ef90c3 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Sat, 27 Jul 2024 10:30:05 -0500 Subject: [PATCH 38/51] Add pasting. --- .../Editor/Windows/Assets/JsonAssetWindow.cs | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/Source/Editor/Windows/Assets/JsonAssetWindow.cs b/Source/Editor/Windows/Assets/JsonAssetWindow.cs index c86846f7c..7ca5250e6 100644 --- a/Source/Editor/Windows/Assets/JsonAssetWindow.cs +++ b/Source/Editor/Windows/Assets/JsonAssetWindow.cs @@ -7,6 +7,8 @@ using FlaxEditor.GUI; using FlaxEditor.GUI.ContextMenu; using FlaxEngine; using FlaxEngine.GUI; +using FlaxEngine.Json; +using FlaxEngine.Utilities; namespace FlaxEditor.Windows.Assets { @@ -17,6 +19,53 @@ namespace FlaxEditor.Windows.Assets /// public sealed class JsonAssetWindow : AssetEditorWindowBase { + private class ObjectPasteUndo : IUndoAction + { + /// + public string ActionString => "Object Paste Undo"; + + private JsonAssetWindow _window; + private object _oldObject; + private object _newObject; + + public ObjectPasteUndo(object oldObject, object newObject, JsonAssetWindow window) + { + _oldObject = oldObject; + _newObject = newObject; + _window = window; + } + + /// + public void Dispose() + { + _oldObject = null; + _newObject = null; + _window = null; + } + + /// + public void Do() + { + if (_newObject != null) + { + _window._object = _newObject; + _window.MarkAsEdited(); + _window._presenter.Select(_window._object); + } + } + + /// + public void Undo() + { + if (_oldObject != null) + { + _window._object = _oldObject; + _window.MarkAsEdited(); + _window._presenter.Select(_window._object); + } + } + } + private readonly CustomEditorPresenter _presenter; private readonly ToolStripButton _saveButton; private readonly ToolStripButton _undoButton; @@ -194,6 +243,38 @@ namespace FlaxEditor.Windows.Assets var cm = new ContextMenu(); cm.AddButton("Copy type name", () => Clipboard.Text = Asset.DataTypeName); cm.AddButton("Copy Asset data", () => Clipboard.Text = Asset.Data); + cm.AddButton("Paste Asset data", () => + { + if (!string.IsNullOrEmpty(Clipboard.Text)) + { + var dataTypeName = Asset.DataTypeName; + var type = TypeUtils.GetType(dataTypeName); + if (type != null) + { + try + { + var obj = Activator.CreateInstance(type.Type); + var data = Clipboard.Text; + JsonSerializer.Deserialize(obj, data); + if (obj != null) + { + var undoAction = new ObjectPasteUndo(_object, obj, this); + undoAction.Do(); + _undo.AddAction(undoAction); + } + else + { + Editor.LogWarning("Pasted data is not the correct data type or has incomplete data"); + } + } + catch (Exception ex) + { + Editor.LogWarning("Pasted data is not the correct data type or has incomplete data"); + } + } + } + }); + cm.Enabled = !string.IsNullOrEmpty(Clipboard.Text); cm.AddSeparator(); if (_optionsButton.Tag is ContentItem item) { From 5f5b0485b5009515109aeded14d819848d1ac699 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Sat, 27 Jul 2024 10:42:51 -0500 Subject: [PATCH 39/51] Cache context menu and add check to prevent accidental duplication. --- .../Editor/Windows/Assets/JsonAssetWindow.cs | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/Source/Editor/Windows/Assets/JsonAssetWindow.cs b/Source/Editor/Windows/Assets/JsonAssetWindow.cs index 7ca5250e6..7fd2fc84c 100644 --- a/Source/Editor/Windows/Assets/JsonAssetWindow.cs +++ b/Source/Editor/Windows/Assets/JsonAssetWindow.cs @@ -75,6 +75,7 @@ namespace FlaxEditor.Windows.Assets private bool _isRegisteredForScriptsReload; private Label _typeText; private ToolStripButton _optionsButton; + private ContextMenu _optionsCM; /// /// Gets the instance of the Json asset object that is being edited. @@ -240,10 +241,13 @@ namespace FlaxEditor.Windows.Assets private void OpenOptionsContextMenu() { - var cm = new ContextMenu(); - cm.AddButton("Copy type name", () => Clipboard.Text = Asset.DataTypeName); - cm.AddButton("Copy Asset data", () => Clipboard.Text = Asset.Data); - cm.AddButton("Paste Asset data", () => + if (_optionsCM != null && _optionsCM.ContainsFocus) + return; + + _optionsCM = new ContextMenu(); + _optionsCM.AddButton("Copy type name", () => Clipboard.Text = Asset.DataTypeName); + _optionsCM.AddButton("Copy Asset data", () => Clipboard.Text = Asset.Data); + _optionsCM.AddButton("Paste Asset data", () => { if (!string.IsNullOrEmpty(Clipboard.Text)) { @@ -274,21 +278,21 @@ namespace FlaxEditor.Windows.Assets } } }); - cm.Enabled = !string.IsNullOrEmpty(Clipboard.Text); - cm.AddSeparator(); + _optionsCM.Enabled = !string.IsNullOrEmpty(Clipboard.Text); + _optionsCM.AddSeparator(); if (_optionsButton.Tag is ContentItem item) { - cm.AddButton("Edit Asset code", () => + _optionsCM.AddButton("Edit Asset code", () => { Editor.Instance.ContentEditing.Open(item); }); - cm.AddButton("Show Asset code item in content window", () => + _optionsCM.AddButton("Show Asset code item in content window", () => { Editor.Instance.Windows.ContentWin.Select(item); }); } - cm.Show(_optionsButton, _optionsButton.PointFromScreen(Input.MouseScreenPosition)); + _optionsCM.Show(_optionsButton, _optionsButton.PointFromScreen(Input.MouseScreenPosition)); } /// From 3db604c30cd038872e1c689b26936a6a46737cfb Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Sat, 27 Jul 2024 12:24:13 -0500 Subject: [PATCH 40/51] Add grid gizmo to prefab scene. --- Source/Editor/Viewport/PrefabWindowViewport.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Source/Editor/Viewport/PrefabWindowViewport.cs b/Source/Editor/Viewport/PrefabWindowViewport.cs index b1fdc1720..4151e9dfb 100644 --- a/Source/Editor/Viewport/PrefabWindowViewport.cs +++ b/Source/Editor/Viewport/PrefabWindowViewport.cs @@ -99,6 +99,16 @@ namespace FlaxEditor.Viewport ShowEditorPrimitives = true; Gizmos = new GizmosCollection(this); + _gridGizmo = new GridGizmo(this); + var showGridButton = ViewWidgetShowMenu.AddButton("Grid"); + showGridButton.Clicked += () => + { + _gridGizmo.Enabled = !_gridGizmo.Enabled; + showGridButton.Checked = _gridGizmo.Enabled; + }; + showGridButton.Checked = true; + showGridButton.CloseMenuOnClick = false; + // Prepare rendering task Task.ActorsSource = ActorsSources.CustomActors; Task.ViewFlags = ViewFlags.DefaultEditor; @@ -267,6 +277,8 @@ namespace FlaxEditor.Viewport /// public GizmosCollection Gizmos { get; } + private GridGizmo _gridGizmo; + /// public SceneRenderTask RenderTask => Task; From 649559a917e11f91ce3ecb1fc4698adb078b2002 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Sun, 28 Jul 2024 13:48:54 -0500 Subject: [PATCH 41/51] Fix missing debug draw from prefabs --- Source/Editor/Viewport/PrefabWindowViewport.cs | 8 ++++++++ Source/Engine/Debug/DebugDraw.cpp | 6 ++++++ Source/Engine/Debug/DebugDraw.h | 6 ++++++ 3 files changed, 20 insertions(+) diff --git a/Source/Editor/Viewport/PrefabWindowViewport.cs b/Source/Editor/Viewport/PrefabWindowViewport.cs index b1fdc1720..38c6107f8 100644 --- a/Source/Editor/Viewport/PrefabWindowViewport.cs +++ b/Source/Editor/Viewport/PrefabWindowViewport.cs @@ -611,6 +611,14 @@ namespace FlaxEditor.Viewport DebugDraw.DrawActors(new IntPtr(actors), _debugDrawData.ActorsCount, false); } } + + // Debug draw all actors in prefab + foreach (var child in SceneGraphRoot.ChildNodes) + { + if (child is not ActorNode actorNode) + continue; + DebugDraw.DrawActorsTree(actorNode.Actor); + } } } } diff --git a/Source/Engine/Debug/DebugDraw.cpp b/Source/Engine/Debug/DebugDraw.cpp index 1bb3a47f8..0bb97c0b2 100644 --- a/Source/Engine/Debug/DebugDraw.cpp +++ b/Source/Engine/Debug/DebugDraw.cpp @@ -944,6 +944,12 @@ void DebugDraw::DrawActors(Actor** selectedActors, int32 selectedActorsCount, bo } } +void DebugDraw::DrawActorsTree(Actor* actor) +{ + Function function = &DrawActorsTreeWalk; + actor->TreeExecute(function); +} + void DebugDraw::DrawAxisFromDirection(const Vector3& origin, const Vector3& direction, float size, float duration, bool depthTest) { ASSERT(direction.IsNormalized()); diff --git a/Source/Engine/Debug/DebugDraw.h b/Source/Engine/Debug/DebugDraw.h index 30e4c905f..ad5bd6fa1 100644 --- a/Source/Engine/Debug/DebugDraw.h +++ b/Source/Engine/Debug/DebugDraw.h @@ -67,6 +67,12 @@ API_CLASS(Static) class FLAXENGINE_API DebugDraw /// True if draw all debug shapes from scenes too or false if draw just from specified actor list. API_FUNCTION() static void DrawActors(Actor** selectedActors, int32 selectedActorsCount, bool drawScenes); + /// + /// Draws the debug shapes for the given actor and the actor's children + /// + /// /// The actor to start drawing at. + API_FUNCTION() static void DrawActorsTree(Actor* actor); + /// /// Draws the lines axis from direction. /// From 00960bad36fc1bff70cefe1704bea7b020ce4b44 Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Tue, 30 Jul 2024 20:50:34 +0300 Subject: [PATCH 42/51] Remove zero clamping from HingeJointDrive in Editor --- Source/Engine/Physics/Joints/HingeJoint.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Engine/Physics/Joints/HingeJoint.h b/Source/Engine/Physics/Joints/HingeJoint.h index 860a6544b..21f5026e4 100644 --- a/Source/Engine/Physics/Joints/HingeJoint.h +++ b/Source/Engine/Physics/Joints/HingeJoint.h @@ -38,7 +38,7 @@ API_STRUCT() struct HingeJointDrive /// /// Target velocity of the joint. /// - API_FIELD(Attributes="Limit(0)") float Velocity = 0.0f; + API_FIELD() float Velocity = 0.0f; /// /// Maximum torque the drive is allowed to apply. From 0d42b6d7eeeb9970ea2a7ae596ffa7587b4db5d2 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Tue, 30 Jul 2024 21:41:50 -0500 Subject: [PATCH 43/51] Add actor type and script type to search filters. --- Source/Editor/SceneGraph/GUI/ActorTreeNode.cs | 111 +++++++++++++++--- 1 file changed, 92 insertions(+), 19 deletions(-) diff --git a/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs b/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs index 44ec4a74b..f7ad55a42 100644 --- a/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs +++ b/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs @@ -184,30 +184,103 @@ namespace FlaxEditor.SceneGraph.GUI } else { - var text = Text; - if (QueryFilterHelper.Match(filterText, text, out QueryFilterHelper.Range[] ranges)) + var splitFilter = filterText.Split(','); + var hasAllFilters = true; + foreach (var filter in splitFilter) { - // Update highlights - if (_highlights == null) - _highlights = new List(ranges.Length); - else - _highlights.Clear(); - var font = Style.Current.FontSmall; - var textRect = TextRect; - for (int i = 0; i < ranges.Length; i++) + if (string.IsNullOrEmpty(filter)) + continue; + var trimmedFilter = filter.Trim(); + var hasFilter = false; + + // Check if script + if (trimmedFilter.Contains("s:", StringComparison.OrdinalIgnoreCase)) { - var start = font.GetCharPosition(text, ranges[i].StartIndex); - var end = font.GetCharPosition(text, ranges[i].EndIndex); - _highlights.Add(new Rectangle(start.X + textRect.X, textRect.Y, end.X - start.X, textRect.Height)); + // Check for any scripts + if (trimmedFilter.Equals("s:", StringComparison.OrdinalIgnoreCase)) + { + if (Actor != null) + { + if (Actor.ScriptsCount > 0) + { + hasFilter = true; + } + } + } + else + { + var scriptText = trimmedFilter.Replace("s:", "", StringComparison.OrdinalIgnoreCase).Trim(); + var scriptFound = false; + if (Actor != null) + { + foreach (var script in Actor.Scripts) + { + var name = TypeUtils.GetTypeDisplayName(script.GetType()); + var nameNoSpaces = name.Replace(" ", ""); + if (name.Contains(scriptText, StringComparison.OrdinalIgnoreCase) || nameNoSpaces.Contains(scriptText, StringComparison.OrdinalIgnoreCase)) + { + scriptFound = true; + break; + } + } + } + + hasFilter = scriptFound; + } + } + // Check for actor type + else if (trimmedFilter.Contains("a:", StringComparison.OrdinalIgnoreCase)) + { + if (trimmedFilter.Equals("a:", StringComparison.OrdinalIgnoreCase)) + { + if (Actor != null) + hasFilter = true; + } + else + { + if (Actor !=null) + { + var actorTypeText = trimmedFilter.Replace("a:", "", StringComparison.OrdinalIgnoreCase).Trim(); + var name = TypeUtils.GetTypeDisplayName(Actor.GetType()); + var nameNoSpaces = name.Replace(" ", ""); + if (name.Contains(actorTypeText, StringComparison.OrdinalIgnoreCase) || nameNoSpaces.Contains(actorTypeText, StringComparison.OrdinalIgnoreCase)) + hasFilter = true; + } + } + } + // Match text + else + { + var text = Text; + if (QueryFilterHelper.Match(trimmedFilter, text, out QueryFilterHelper.Range[] ranges)) + { + // Update highlights + if (_highlights == null) + _highlights = new List(ranges.Length); + else + _highlights.Clear(); + var font = Style.Current.FontSmall; + var textRect = TextRect; + for (int i = 0; i < ranges.Length; i++) + { + var start = font.GetCharPosition(text, ranges[i].StartIndex); + var end = font.GetCharPosition(text, ranges[i].EndIndex); + _highlights.Add(new Rectangle(start.X + textRect.X, textRect.Y, end.X - start.X, textRect.Height)); + } + hasFilter = true; + } + } + + if (!hasFilter) + { + hasAllFilters = false; + break; } - isThisVisible = true; } - else - { - // Hide + + isThisVisible = hasAllFilters; + if (!hasAllFilters) _highlights?.Clear(); - isThisVisible = false; - } } // Update children From 979ab9f6ee23242be1189633d46d2cc7ef17e0b1 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 5 Aug 2024 14:37:31 +0200 Subject: [PATCH 44/51] Fix `World Triplanar Texture` node to support displacement and float4 value --- Source/Editor/Surface/Archetypes/Textures.cs | 4 +-- .../MaterialGenerator.Textures.cpp | 30 ++++++------------- 2 files changed, 11 insertions(+), 23 deletions(-) diff --git a/Source/Editor/Surface/Archetypes/Textures.cs b/Source/Editor/Surface/Archetypes/Textures.cs index 53b2ccf04..967ea1682 100644 --- a/Source/Editor/Surface/Archetypes/Textures.cs +++ b/Source/Editor/Surface/Archetypes/Textures.cs @@ -404,9 +404,9 @@ namespace FlaxEditor.Surface.Archetypes Elements = new[] { NodeElementArchetype.Factory.Input(0, "Texture", true, typeof(FlaxEngine.Object), 0), - NodeElementArchetype.Factory.Input(1, "Scale", true, typeof(Float3), 1, 0), + NodeElementArchetype.Factory.Input(1, "Scale", true, typeof(Float4), 1, 0), NodeElementArchetype.Factory.Input(2, "Blend", true, typeof(float), 2, 1), - NodeElementArchetype.Factory.Output(0, "Color", typeof(Float3), 3) + NodeElementArchetype.Factory.Output(0, "Color", typeof(Float4), 3) } }, new NodeArchetype diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Textures.cpp b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Textures.cpp index 8083718dd..1ed776646 100644 --- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Textures.cpp +++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Textures.cpp @@ -687,51 +687,41 @@ void MaterialGenerator::ProcessGroupTextures(Box* box, Node* node, Value& value) // World Triplanar Texture case 16: { - // Get input boxes auto textureBox = node->GetBox(0); auto scaleBox = node->GetBox(1); auto blendBox = node->GetBox(2); - if (!textureBox->HasConnection()) { // No texture to sample value = Value::Zero; break; } - - if (!CanUseSample(_treeType)) - { - // Must sample texture in pixel shader - value = Value::Zero; - break; - } - + const bool canUseSample = CanUseSample(_treeType); const auto texture = eatBox(textureBox->GetParent(), textureBox->FirstConnection()); - const auto scale = tryGetValue(scaleBox, node->Values[0]).AsFloat3(); + const auto scale = tryGetValue(scaleBox, node->Values[0]).AsFloat4(); const auto blend = tryGetValue(blendBox, node->Values[1]).AsFloat(); - auto result = writeLocal(Value::InitForZero(ValueType::Float4), node); - const String triplanarTexture = String::Format(TEXT( " {{\n" " float3 worldPos = input.WorldPosition.xyz * ({1} * 0.001f);\n" " float3 normal = abs(input.TBN[2]);\n" " normal = pow(normal, {2});\n" " normal = normal / (normal.x + normal.y + normal.z);\n" - - " {3} += {0}.Sample(SamplerLinearWrap, worldPos.yz) * normal.x;\n" - " {3} += {0}.Sample(SamplerLinearWrap, worldPos.xz) * normal.y;\n" - " {3} += {0}.Sample(SamplerLinearWrap, worldPos.xy) * normal.z;\n" + " {3} += {0}.{4}(SamplerLinearWrap, worldPos.yz{5}) * normal.x;\n" + " {3} += {0}.{4}(SamplerLinearWrap, worldPos.xz{5}) * normal.y;\n" + " {3} += {0}.{4}(SamplerLinearWrap, worldPos.xy{5}) * normal.z;\n" " }}\n" ), texture.Value, // {0} scale.Value, // {1} blend.Value, // {2} - result.Value // {3} + result.Value, // {3} + canUseSample ? TEXT("Sample") : TEXT("SampleLevel"), // {4} + canUseSample ? TEXT("") : TEXT(", 0") // {5} ); - _writer.Write(*triplanarTexture); value = result; + break; } // Get Lightmap UV case 18: @@ -746,9 +736,7 @@ void MaterialGenerator::ProcessGroupTextures(Box* box, Node* node, Value& value) "#endif\n" "}}\n" ), output.Value); - _writer.Write(*lightmapUV); - value = output; break; } From 387e8d1dd9bd0eefbbfb820275a7c6aebe569329 Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Sun, 4 Aug 2024 20:15:12 +0300 Subject: [PATCH 45/51] Use larger epsilon in `Vector` `IsNormalized` checks --- Source/Engine/Core/Math/Double2.cs | 2 +- Source/Engine/Core/Math/Double3.cs | 2 +- Source/Engine/Core/Math/Double4.cs | 2 +- Source/Engine/Core/Math/Float2.cs | 2 +- Source/Engine/Core/Math/Float3.cs | 2 +- Source/Engine/Core/Math/Float4.cs | 2 +- Source/Engine/Core/Math/Quaternion.cs | 2 +- Source/Engine/Core/Math/Quaternion.h | 2 +- Source/Engine/Core/Math/Vector2.cs | 2 +- Source/Engine/Core/Math/Vector2.h | 2 +- Source/Engine/Core/Math/Vector3.cs | 2 +- Source/Engine/Core/Math/Vector3.h | 2 +- Source/Engine/Core/Math/Vector4.cs | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Source/Engine/Core/Math/Double2.cs b/Source/Engine/Core/Math/Double2.cs index 2b6c71282..d3df12898 100644 --- a/Source/Engine/Core/Math/Double2.cs +++ b/Source/Engine/Core/Math/Double2.cs @@ -179,7 +179,7 @@ namespace FlaxEngine /// /// Gets a value indicting whether this instance is normalized. /// - public bool IsNormalized => Mathd.IsOne(X * X + Y * Y); + public bool IsNormalized => Mathd.Abs((X * X + Y * Y) - 1.0f) < 1e-4f; /// /// Gets a value indicting whether this vector is zero diff --git a/Source/Engine/Core/Math/Double3.cs b/Source/Engine/Core/Math/Double3.cs index aba7345a0..c84c9a935 100644 --- a/Source/Engine/Core/Math/Double3.cs +++ b/Source/Engine/Core/Math/Double3.cs @@ -234,7 +234,7 @@ namespace FlaxEngine /// /// Gets a value indicting whether this instance is normalized. /// - public bool IsNormalized => Mathd.IsOne(X * X + Y * Y + Z * Z); + public bool IsNormalized => Mathd.Abs((X * X + Y * Y + Z * Z) - 1.0f) < 1e-4f; /// /// Gets the normalized vector. Returned vector has length equal 1. diff --git a/Source/Engine/Core/Math/Double4.cs b/Source/Engine/Core/Math/Double4.cs index 504c4fcce..1e115c3ae 100644 --- a/Source/Engine/Core/Math/Double4.cs +++ b/Source/Engine/Core/Math/Double4.cs @@ -220,7 +220,7 @@ namespace FlaxEngine /// /// Gets a value indicting whether this instance is normalized. /// - public bool IsNormalized => Mathd.IsOne(X * X + Y * Y + Z * Z + W * W); + public bool IsNormalized => Mathd.Abs((X * X + Y * Y + Z * Z + W * W) - 1.0f) < 1e-4f; /// /// Gets a value indicting whether this vector is zero diff --git a/Source/Engine/Core/Math/Float2.cs b/Source/Engine/Core/Math/Float2.cs index 9c3909214..adbe61508 100644 --- a/Source/Engine/Core/Math/Float2.cs +++ b/Source/Engine/Core/Math/Float2.cs @@ -184,7 +184,7 @@ namespace FlaxEngine /// /// Gets a value indicting whether this instance is normalized. /// - public bool IsNormalized => Mathf.IsOne(X * X + Y * Y); + public bool IsNormalized => Mathf.Abs((X * X + Y * Y) - 1.0f) < 1e-4f; /// /// Gets a value indicting whether this vector is zero diff --git a/Source/Engine/Core/Math/Float3.cs b/Source/Engine/Core/Math/Float3.cs index 46814c2e8..beb35d541 100644 --- a/Source/Engine/Core/Math/Float3.cs +++ b/Source/Engine/Core/Math/Float3.cs @@ -228,7 +228,7 @@ namespace FlaxEngine /// /// Gets a value indicting whether this instance is normalized. /// - public bool IsNormalized => Mathf.IsOne(X * X + Y * Y + Z * Z); + public bool IsNormalized => Mathf.Abs((X * X + Y * Y + Z * Z) - 1.0f) < 1e-4f; /// /// Gets the normalized vector. Returned vector has length equal 1. diff --git a/Source/Engine/Core/Math/Float4.cs b/Source/Engine/Core/Math/Float4.cs index 6742ca34d..7b9a81b84 100644 --- a/Source/Engine/Core/Math/Float4.cs +++ b/Source/Engine/Core/Math/Float4.cs @@ -202,7 +202,7 @@ namespace FlaxEngine /// /// Gets a value indicting whether this instance is normalized. /// - public bool IsNormalized => Mathf.IsOne(X * X + Y * Y + Z * Z + W * W); + public bool IsNormalized => Mathf.Abs((X * X + Y * Y + Z * Z + W * W) - 1.0f) < 1e-4f; /// /// Gets a value indicting whether this vector is zero diff --git a/Source/Engine/Core/Math/Quaternion.cs b/Source/Engine/Core/Math/Quaternion.cs index d4d0fe96c..e50795221 100644 --- a/Source/Engine/Core/Math/Quaternion.cs +++ b/Source/Engine/Core/Math/Quaternion.cs @@ -163,7 +163,7 @@ namespace FlaxEngine /// /// Gets a value indicting whether this instance is normalized. /// - public bool IsNormalized => Mathf.IsOne(X * X + Y * Y + Z * Z + W * W); + public bool IsNormalized => Mathf.Abs((X * X + Y * Y + Z * Z + W * W) - 1.0f) < 1e-4f; /// /// Gets the euler angle (pitch, yaw, roll) in degrees. diff --git a/Source/Engine/Core/Math/Quaternion.h b/Source/Engine/Core/Math/Quaternion.h index 0790dcbfb..45605a674 100644 --- a/Source/Engine/Core/Math/Quaternion.h +++ b/Source/Engine/Core/Math/Quaternion.h @@ -107,7 +107,7 @@ public: /// bool IsNormalized() const { - return Math::IsOne(X * X + Y * Y + Z * Z + W * W); + return Math::Abs((X * X + Y * Y + Z * Z + W * W) - 1.0f) < 1e-4f; } /// diff --git a/Source/Engine/Core/Math/Vector2.cs b/Source/Engine/Core/Math/Vector2.cs index 29628c1fb..4570ad2e9 100644 --- a/Source/Engine/Core/Math/Vector2.cs +++ b/Source/Engine/Core/Math/Vector2.cs @@ -207,7 +207,7 @@ namespace FlaxEngine /// /// Gets a value indicting whether this instance is normalized. /// - public bool IsNormalized => Mathr.IsOne(X * X + Y * Y); + public bool IsNormalized => Mathr.Abs((X * X + Y * Y) - 1.0f) < 1e-4f; /// /// Gets a value indicting whether this vector is zero diff --git a/Source/Engine/Core/Math/Vector2.h b/Source/Engine/Core/Math/Vector2.h index 9854b472e..f36249025 100644 --- a/Source/Engine/Core/Math/Vector2.h +++ b/Source/Engine/Core/Math/Vector2.h @@ -105,7 +105,7 @@ public: // Gets a value indicting whether this instance is normalized. bool IsNormalized() const { - return Math::IsOne(X * X + Y * Y); + return Math::Abs((X * X + Y * Y) - 1.0f) < 1e-4f; } // Gets a value indicting whether this vector is zero. diff --git a/Source/Engine/Core/Math/Vector3.cs b/Source/Engine/Core/Math/Vector3.cs index 848a3b532..738a9bad8 100644 --- a/Source/Engine/Core/Math/Vector3.cs +++ b/Source/Engine/Core/Math/Vector3.cs @@ -256,7 +256,7 @@ namespace FlaxEngine /// /// Gets a value indicting whether this instance is normalized. /// - public bool IsNormalized => Mathr.IsOne(X * X + Y * Y + Z * Z); + public bool IsNormalized => Mathr.Abs((X * X + Y * Y + Z * Z) - 1.0f) < 1e-4f; /// /// Gets the normalized vector. Returned vector has length equal 1. diff --git a/Source/Engine/Core/Math/Vector3.h b/Source/Engine/Core/Math/Vector3.h index 950d730c5..619fcfc12 100644 --- a/Source/Engine/Core/Math/Vector3.h +++ b/Source/Engine/Core/Math/Vector3.h @@ -136,7 +136,7 @@ public: // Gets a value indicting whether this instance is normalized. bool IsNormalized() const { - return Math::IsOne(X * X + Y * Y + Z * Z); + return Math::Abs((X * X + Y * Y + Z * Z) - 1.0f) < 1e-4f; } // Gets a value indicting whether this vector is zero. diff --git a/Source/Engine/Core/Math/Vector4.cs b/Source/Engine/Core/Math/Vector4.cs index 64487e3c7..e859938bf 100644 --- a/Source/Engine/Core/Math/Vector4.cs +++ b/Source/Engine/Core/Math/Vector4.cs @@ -258,7 +258,7 @@ namespace FlaxEngine /// /// Gets a value indicting whether this instance is normalized. /// - public bool IsNormalized => Mathr.IsOne(X * X + Y * Y + Z * Z + W * W); + public bool IsNormalized => Mathr.Abs((X * X + Y * Y + Z * Z + W * W) - 1.0f) < 1e-4f; /// /// Gets a value indicting whether this vector is zero From eb3a940a31728ee64ab2d905a24d267305c93838 Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Sun, 4 Aug 2024 20:16:22 +0300 Subject: [PATCH 46/51] Fix Linux platform `CreateProcess` not working with whitespace in path --- Source/Engine/Platform/Linux/LinuxPlatform.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Engine/Platform/Linux/LinuxPlatform.cpp b/Source/Engine/Platform/Linux/LinuxPlatform.cpp index 1d3ccbd8c..2c951effa 100644 --- a/Source/Engine/Platform/Linux/LinuxPlatform.cpp +++ b/Source/Engine/Platform/Linux/LinuxPlatform.cpp @@ -2923,7 +2923,7 @@ int32 LinuxPlatform::CreateProcess(CreateProcessSettings& settings) LOG(Info, "Working directory: {0}", settings.WorkingDirectory); } const bool captureStdOut = settings.LogOutput || settings.SaveOutput; - const String cmdLine = settings.FileName + TEXT(" ") + settings.Arguments; + const String cmdLine = String::Format(TEXT("\"{0}\" {1}"), settings.FileName, settings.Arguments); int fildes[2]; int32 returnCode = 0; From 117178f547dcda3ee67a13419c5d93b059b1152d Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 5 Aug 2024 18:18:02 +0200 Subject: [PATCH 47/51] Fix shader resource usage warning when drawing grid gizmo after selection outline #2808 --- Source/Engine/Renderer/RenderList.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/Engine/Renderer/RenderList.cpp b/Source/Engine/Renderer/RenderList.cpp index 679e2317b..a26f1158e 100644 --- a/Source/Engine/Renderer/RenderList.cpp +++ b/Source/Engine/Renderer/RenderList.cpp @@ -326,6 +326,7 @@ void RenderList::RunCustomPostFxPass(GPUContext* context, RenderContext& renderC Swap(input, output); } context->ResetRenderTarget(); + context->ResetSR(); } } } From 1a953c99bcbe11dcfac7d8eac821bf958202f9c1 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 5 Aug 2024 19:01:56 +0200 Subject: [PATCH 48/51] Format code --- Source/Editor/Surface/ContextMenu/VisjectCM.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Source/Editor/Surface/ContextMenu/VisjectCM.cs b/Source/Editor/Surface/ContextMenu/VisjectCM.cs index 691bef2dd..526c24fae 100644 --- a/Source/Editor/Surface/ContextMenu/VisjectCM.cs +++ b/Source/Editor/Surface/ContextMenu/VisjectCM.cs @@ -794,7 +794,7 @@ namespace FlaxEditor.Surface.ContextMenu { Focus(null); - if(_useDescriptionPanel) + if (_useDescriptionPanel) HideDescriptionPanel(); base.Hide(); @@ -806,7 +806,7 @@ namespace FlaxEditor.Surface.ContextMenu /// The node archetype public void SetDescriptionPanelArchetype(NodeArchetype archetype) { - if(!_useDescriptionPanel) + if (!_useDescriptionPanel) return; if (archetype == null || !Editor.Instance.Options.Options.Interface.VisualScriptingDescriptionPanel) @@ -847,7 +847,7 @@ namespace FlaxEditor.Surface.ContextMenu AddInputOutputElement(archetype, memberInfo.ValueType, true, $"Return ({memberInfo.ValueType.Name})"); } - for(int i = 0; i < memberInfo.ParametersCount; i++) + for (int i = 0; i < memberInfo.ParametersCount; i++) { var param = memberInfo.GetParameters()[i]; AddInputOutputElement(archetype, param.Type, param.IsOut, $"{param.Name} ({param.Type.Name})"); @@ -882,7 +882,7 @@ namespace FlaxEditor.Surface.ContextMenu if (element.Type is not (NodeElementType.Input or NodeElementType.Output)) continue; - var typeText = element.ConnectionsType ? element.ConnectionsType.Name : archetype.ConnectionsHints.ToString(); + var typeText = element.ConnectionsType ? element.ConnectionsType.Name : archetype.ConnectionsHints.ToString(); AddInputOutputElement(archetype, element.ConnectionsType, element.Type == NodeElementType.Output, $"{element.Text} ({typeText})"); } } @@ -967,7 +967,7 @@ namespace FlaxEditor.Surface.ContextMenu /// private void HideDescriptionPanel() { - if(!_descriptionPanelVisible) + if (!_descriptionPanelVisible) return; _descriptionInputPanel.RemoveChildren(); From 265e34bd04849aa222a40b0b20194a32e21cc8a1 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Mon, 5 Aug 2024 12:13:44 -0500 Subject: [PATCH 49/51] Serialize json asset copy and paste data and code style fixes. --- .../Editor/Windows/Assets/JsonAssetWindow.cs | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/Source/Editor/Windows/Assets/JsonAssetWindow.cs b/Source/Editor/Windows/Assets/JsonAssetWindow.cs index 7fd2fc84c..43b34a8c6 100644 --- a/Source/Editor/Windows/Assets/JsonAssetWindow.cs +++ b/Source/Editor/Windows/Assets/JsonAssetWindow.cs @@ -25,13 +25,13 @@ namespace FlaxEditor.Windows.Assets public string ActionString => "Object Paste Undo"; private JsonAssetWindow _window; - private object _oldObject; - private object _newObject; + private string _oldObject; + private string _newObject; public ObjectPasteUndo(object oldObject, object newObject, JsonAssetWindow window) { - _oldObject = oldObject; - _newObject = newObject; + _oldObject = JsonSerializer.Serialize(oldObject); + _newObject = JsonSerializer.Serialize(newObject); _window = window; } @@ -46,9 +46,9 @@ namespace FlaxEditor.Windows.Assets /// public void Do() { - if (_newObject != null) + if (!string.IsNullOrEmpty(_newObject)) { - _window._object = _newObject; + _window._object = JsonSerializer.Deserialize(_newObject, TypeUtils.GetType(_window.Asset.DataTypeName).Type); _window.MarkAsEdited(); _window._presenter.Select(_window._object); } @@ -57,9 +57,9 @@ namespace FlaxEditor.Windows.Assets /// public void Undo() { - if (_oldObject != null) + if (!string.IsNullOrEmpty(_oldObject)) { - _window._object = _oldObject; + _window._object = JsonSerializer.Deserialize(_oldObject, TypeUtils.GetType(_window.Asset.DataTypeName).Type); _window.MarkAsEdited(); _window._presenter.Select(_window._object); } @@ -203,11 +203,12 @@ namespace FlaxEditor.Windows.Assets break; } } - + _optionsButton = new ToolStripButton(_toolstrip.ItemsHeight, ref Editor.Icons.Settings12) { AnchorPreset = AnchorPresets.TopRight, Tag = buttonTag, + Size = new Float2(18), Parent = this, }; _optionsButton.LocalX -= (_optionsButton.Width + 4); @@ -246,8 +247,8 @@ namespace FlaxEditor.Windows.Assets _optionsCM = new ContextMenu(); _optionsCM.AddButton("Copy type name", () => Clipboard.Text = Asset.DataTypeName); - _optionsCM.AddButton("Copy Asset data", () => Clipboard.Text = Asset.Data); - _optionsCM.AddButton("Paste Asset data", () => + _optionsCM.AddButton("Copy asset data", () => Clipboard.Text = Asset.Data); + _optionsCM.AddButton("Paste asset data", () => { if (!string.IsNullOrEmpty(Clipboard.Text)) { @@ -273,7 +274,7 @@ namespace FlaxEditor.Windows.Assets } catch (Exception ex) { - Editor.LogWarning("Pasted data is not the correct data type or has incomplete data"); + Editor.LogWarning($"Pasted data is not the correct data type or has incomplete data. Exception: {ex}"); } } } @@ -282,11 +283,11 @@ namespace FlaxEditor.Windows.Assets _optionsCM.AddSeparator(); if (_optionsButton.Tag is ContentItem item) { - _optionsCM.AddButton("Edit Asset code", () => + _optionsCM.AddButton("Edit asset code", () => { Editor.Instance.ContentEditing.Open(item); }); - _optionsCM.AddButton("Show Asset code item in content window", () => + _optionsCM.AddButton("Show asset code item in content window", () => { Editor.Instance.Windows.ContentWin.Select(item); }); From 23fcfb4eb2496fd0e9fc04e3ba5dd56a6a0ebb70 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 5 Aug 2024 19:44:06 +0200 Subject: [PATCH 50/51] Code cleanup #2717 --- .../Features/ForwardShading.hlsl | 13 +++----- .../Features/SDFReflections.hlsl | 2 -- .../Materials/ForwardMaterialShader.cpp | 4 +-- .../Graphics/Materials/MaterialShader.h | 2 +- .../Materials/MaterialShaderFeatures.cpp | 13 +++----- .../MaterialGenerator/MaterialGenerator.cpp | 31 ++++++++++--------- Source/Shaders/GBufferCommon.hlsl | 1 - Source/Shaders/ReflectionsCommon.hlsl | 3 ++ Source/Shaders/SSR.shader | 7 ++--- 9 files changed, 33 insertions(+), 43 deletions(-) diff --git a/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl b/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl index dc866c1ea..bbc06f15d 100644 --- a/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl +++ b/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl @@ -67,7 +67,6 @@ void PS_Forward( gBuffer.Color = material.Color; gBuffer.Specular = material.Specular; gBuffer.AO = material.AO; - // gBuffer.ViewPos is the view space position of the pixel gBuffer.ViewPos = mul(float4(materialInput.WorldPosition, 1), ViewMatrix).xyz; #if MATERIAL_SHADING_MODEL == SHADING_MODEL_SUBSURFACE gBuffer.CustomData = float4(material.SubsurfaceColor, material.Opacity); @@ -126,23 +125,19 @@ void PS_Forward( float3 screenColor = sceneColorTexture.SampleLevel(SamplerPointClamp, hit.xy, 0).rgb; reflections = lerp(reflections, screenColor, hit.z); } - + // Fallback to software tracing if possible #if USE_GLOBAL_SURFACE_ATLAS && CAN_USE_GLOBAL_SURFACE_ATLAS - - // If hit.z >= 0.9f then skip sdf tracing - if (hit.z < 0.9f) + if (hit.z < REFLECTIONS_HIT_THRESHOLD) { - // Don't use temporal effect in forward pass float3 reflectWS = ScreenSpaceReflectionDirection(screenUV, gBuffer, ViewPos); float4 surfaceAtlas; - - if(TraceSDFSoftwareReflections(gBuffer, reflectWS, surfaceAtlas)){ + if (TraceSDFSoftwareReflections(gBuffer, reflectWS, surfaceAtlas)) + { float3 screenColor = sceneColorTexture.SampleLevel(SamplerPointClamp, hit.xy, 0).rgb; reflections = lerp(surfaceAtlas, float4(screenColor, 1), hit.z); } } - #endif #endif diff --git a/Content/Editor/MaterialTemplates/Features/SDFReflections.hlsl b/Content/Editor/MaterialTemplates/Features/SDFReflections.hlsl index a7177e686..34201f546 100644 --- a/Content/Editor/MaterialTemplates/Features/SDFReflections.hlsl +++ b/Content/Editor/MaterialTemplates/Features/SDFReflections.hlsl @@ -29,10 +29,8 @@ bool TraceSDFSoftwareReflections(GBufferSample gBuffer, float3 reflectWS, out fl float3 hitPosition = sdfHit.GetHitPosition(sdfTrace); float surfaceThreshold = GetGlobalSurfaceAtlasThreshold(GlobalSDF, sdfHit); surfaceAtlas = SampleGlobalSurfaceAtlas(GlobalSurfaceAtlas, GlobalSurfaceAtlasChunks, RWGlobalSurfaceAtlasCulledObjects, GlobalSurfaceAtlasObjects, GlobalSurfaceAtlasDepth, GlobalSurfaceAtlasTex, hitPosition, -reflectWS, surfaceThreshold); - return true; } - return false; } diff --git a/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp b/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp index fd9568bcf..7aa662d43 100644 --- a/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp +++ b/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp @@ -51,7 +51,8 @@ void ForwardMaterialShader::Bind(BindParameters& params) int32 srv = 2; // Setup features - if ((_info.FeaturesFlags & MaterialFeaturesFlags::GlobalIllumination) != MaterialFeaturesFlags::None) { + if ((_info.FeaturesFlags & MaterialFeaturesFlags::GlobalIllumination) != MaterialFeaturesFlags::None) + { GlobalIlluminationFeature::Bind(params, cb, srv); if ((_info.FeaturesFlags & MaterialFeaturesFlags::ScreenSpaceReflections) != MaterialFeaturesFlags::None) SDFReflectionsFeature::Bind(params, cb, srv); @@ -181,7 +182,6 @@ bool ForwardMaterialShader::Load() psDesc.VS = _shader->GetVS("VS"); if (psDesc.VS == nullptr) return true; - psDesc.PS = _shader->GetPS("PS_Forward"); psDesc.DepthWriteEnable = false; psDesc.BlendMode = BlendingMode::AlphaBlend; diff --git a/Source/Engine/Graphics/Materials/MaterialShader.h b/Source/Engine/Graphics/Materials/MaterialShader.h index 7a5b842e2..5a4cec20c 100644 --- a/Source/Engine/Graphics/Materials/MaterialShader.h +++ b/Source/Engine/Graphics/Materials/MaterialShader.h @@ -10,7 +10,7 @@ /// /// Current materials shader version. /// -#define MATERIAL_GRAPH_VERSION 162 +#define MATERIAL_GRAPH_VERSION 163 class Material; class GPUShader; diff --git a/Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp b/Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp index 94c963b74..697176763 100644 --- a/Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp +++ b/Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp @@ -132,13 +132,13 @@ bool LightmapFeature::Bind(MaterialShader::BindParameters& params, Span& c const bool useLightmap = EnumHasAnyFlags(params.RenderContext.View.Flags, ViewFlags::GI) #if USE_EDITOR - && EnableLightmapsUsage + && EnableLightmapsUsage #endif - && drawCall.Surface.Lightmap != nullptr; + && drawCall.Surface.Lightmap != nullptr; if (useLightmap) { // Bind lightmap textures - GPUTexture* lightmap0, * lightmap1, * lightmap2; + GPUTexture *lightmap0, *lightmap1, *lightmap2; drawCall.Features.Lightmap->GetTextures(&lightmap0, &lightmap1, &lightmap2); params.GPUContext->BindSR(srv + 0, lightmap0); params.GPUContext->BindSR(srv + 1, lightmap1); @@ -210,16 +210,14 @@ bool SDFReflectionsFeature::Bind(MaterialShader::BindParameters& params, SpanGet(params.RenderContext.Buffers, bindingDataSDF) && !GlobalSurfaceAtlasPass::Instance()->Get(params.RenderContext.Buffers, bindingDataSurfaceAtlas)) { useSDFReflections = true; - // Bind DDGI data + // Bind SDF and Surface Atlas data data.GlobalSDF = bindingDataSDF.Constants; data.GlobalSurfaceAtlas = bindingDataSurfaceAtlas.Constants; - params.GPUContext->BindSR(srv + 0, bindingDataSDF.Texture ? bindingDataSDF.Texture->ViewVolume() : nullptr); params.GPUContext->BindSR(srv + 1, bindingDataSDF.TextureMip ? bindingDataSDF.TextureMip->ViewVolume() : nullptr); params.GPUContext->BindSR(srv + 2, bindingDataSurfaceAtlas.Chunks ? bindingDataSurfaceAtlas.Chunks->View() : nullptr); @@ -232,11 +230,10 @@ bool SDFReflectionsFeature::Bind(MaterialShader::BindParameters& params, SpanUnBindSR(srv + 0); params.GPUContext->UnBindSR(srv + 1); params.GPUContext->UnBindSR(srv + 2); diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp index bff70e709..f9ca26705 100644 --- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp +++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp @@ -188,45 +188,46 @@ bool MaterialGenerator::Generate(WriteStream& source, MaterialInfo& materialInfo { case MaterialDomain::Surface: if (materialInfo.TessellationMode != TessellationMethod::None) - ADD_FEATURE(TessellationFeature); + ADD_FEATURE(TessellationFeature); if (materialInfo.BlendMode == MaterialBlendMode::Opaque) - ADD_FEATURE(MotionVectorsFeature); + ADD_FEATURE(MotionVectorsFeature); if (materialInfo.BlendMode == MaterialBlendMode::Opaque) - ADD_FEATURE(LightmapFeature); + ADD_FEATURE(LightmapFeature); if (materialInfo.BlendMode == MaterialBlendMode::Opaque) - ADD_FEATURE(DeferredShadingFeature); + ADD_FEATURE(DeferredShadingFeature); if (materialInfo.BlendMode != MaterialBlendMode::Opaque && (materialInfo.FeaturesFlags & MaterialFeaturesFlags::DisableDistortion) == MaterialFeaturesFlags::None) - ADD_FEATURE(DistortionFeature); - if (materialInfo.BlendMode != MaterialBlendMode::Opaque && EnumHasAnyFlags(materialInfo.FeaturesFlags, MaterialFeaturesFlags::GlobalIllumination)) { + ADD_FEATURE(DistortionFeature); + if (materialInfo.BlendMode != MaterialBlendMode::Opaque && EnumHasAnyFlags(materialInfo.FeaturesFlags, MaterialFeaturesFlags::GlobalIllumination)) + { ADD_FEATURE(GlobalIlluminationFeature); // SDF Reflections is only valid when both GI and SSR is enabled if (materialInfo.BlendMode != MaterialBlendMode::Opaque && EnumHasAnyFlags(materialInfo.FeaturesFlags, MaterialFeaturesFlags::ScreenSpaceReflections)) - ADD_FEATURE(SDFReflectionsFeature); + ADD_FEATURE(SDFReflectionsFeature); } if (materialInfo.BlendMode != MaterialBlendMode::Opaque) - ADD_FEATURE(ForwardShadingFeature); + ADD_FEATURE(ForwardShadingFeature); break; case MaterialDomain::Terrain: if (materialInfo.TessellationMode != TessellationMethod::None) - ADD_FEATURE(TessellationFeature); + ADD_FEATURE(TessellationFeature); ADD_FEATURE(LightmapFeature); ADD_FEATURE(DeferredShadingFeature); break; case MaterialDomain::Particle: if (materialInfo.BlendMode != MaterialBlendMode::Opaque && (materialInfo.FeaturesFlags & MaterialFeaturesFlags::DisableDistortion) == MaterialFeaturesFlags::None) - ADD_FEATURE(DistortionFeature); + ADD_FEATURE(DistortionFeature); if (materialInfo.BlendMode != MaterialBlendMode::Opaque && EnumHasAnyFlags(materialInfo.FeaturesFlags, MaterialFeaturesFlags::GlobalIllumination)) - ADD_FEATURE(GlobalIlluminationFeature); + ADD_FEATURE(GlobalIlluminationFeature); ADD_FEATURE(ForwardShadingFeature); break; case MaterialDomain::Deformable: if (materialInfo.TessellationMode != TessellationMethod::None) - ADD_FEATURE(TessellationFeature); + ADD_FEATURE(TessellationFeature); if (materialInfo.BlendMode == MaterialBlendMode::Opaque) - ADD_FEATURE(DeferredShadingFeature); + ADD_FEATURE(DeferredShadingFeature); if (materialInfo.BlendMode != MaterialBlendMode::Opaque) - ADD_FEATURE(ForwardShadingFeature); + ADD_FEATURE(ForwardShadingFeature); break; default: break; @@ -713,7 +714,7 @@ void MaterialGenerator::ProcessGroupMath(Box* box, Node* node, Value& value) { switch (node->TypeID) { - // Vector Transform + // Vector Transform case 30: { // Get input vector diff --git a/Source/Shaders/GBufferCommon.hlsl b/Source/Shaders/GBufferCommon.hlsl index 27095f000..88a6c3688 100644 --- a/Source/Shaders/GBufferCommon.hlsl +++ b/Source/Shaders/GBufferCommon.hlsl @@ -14,7 +14,6 @@ struct GBufferSample float Metalness; float3 Color; float Specular; - // View space position of pixel, DIFFERENT FROM GBufferData.ViewPos float3 ViewPos; float AO; int ShadingModel; diff --git a/Source/Shaders/ReflectionsCommon.hlsl b/Source/Shaders/ReflectionsCommon.hlsl index f571abc47..0af6e39c1 100644 --- a/Source/Shaders/ReflectionsCommon.hlsl +++ b/Source/Shaders/ReflectionsCommon.hlsl @@ -5,6 +5,9 @@ #include "./Flax/GBufferCommon.hlsl" +// Hit depth (view space) threshold to detect if sky was hit (value above it where 1.0f is default) +#define REFLECTIONS_HIT_THRESHOLD 0.9f + float GetSpecularOcclusion(float NoV, float roughnessSq, float ao) { return saturate(pow(NoV + ao, roughnessSq) - 1 + ao); diff --git a/Source/Shaders/SSR.shader b/Source/Shaders/SSR.shader index 3aa3cbc60..a9cdbe57d 100644 --- a/Source/Shaders/SSR.shader +++ b/Source/Shaders/SSR.shader @@ -129,13 +129,12 @@ float4 PS_RayTracePass(Quad_VS2PS input) : SV_Target0 float mip = clamp(log2(intersectionCircleRadius * TraceSizeMax), 0.0, MaxColorMiplevel); float3 sampleColor = Texture0.SampleLevel(SamplerLinearClamp, screenHit.xy, mip).rgb; result = float4(sampleColor, screenHit.z); - if (screenHit.z >= 0.9f) + if (screenHit.z >= REFLECTIONS_HIT_THRESHOLD) return result; } // Fallback to Global SDF and Global Surface Atlas tracing #if USE_GLOBAL_SURFACE_ATLAS && CAN_USE_GLOBAL_SURFACE_ATLAS - // Calculate reflection direction (the same TraceScreenSpaceReflection) float3 reflectWS = ScreenSpaceReflectionDirection(input.TexCoord, gBuffer, gBufferData.ViewPos, TemporalEffect, TemporalTime, BRDFBias); @@ -149,9 +148,7 @@ float4 PS_RayTracePass(Quad_VS2PS input) : SV_Target0 float3 hitPosition = sdfHit.GetHitPosition(sdfTrace); float surfaceThreshold = GetGlobalSurfaceAtlasThreshold(GlobalSDF, sdfHit); float4 surfaceAtlas = SampleGlobalSurfaceAtlas(GlobalSurfaceAtlas, GlobalSurfaceAtlasChunks, RWGlobalSurfaceAtlasCulledObjects, GlobalSurfaceAtlasObjects, GlobalSurfaceAtlasDepth, GlobalSurfaceAtlasTex, hitPosition, -reflectWS, surfaceThreshold); - // Now the sdf reflection part is significantly darker than the screen space part - // TODO: Maybe multiply surfaceAtlas by a constant to make it brighter, adding 2* looks fine - result = lerp(surfaceAtlas, float4(result.rgb, 1), result.a); + result = lerp(surfaceAtlas, float4(result.rgb, 1), result.a); } #endif From 2c8111801d34c3fae43ba44d6f9fa5657b74b8f5 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 5 Aug 2024 19:44:41 +0200 Subject: [PATCH 51/51] Update shaders and materials --- Content/Editor/Camera/M_Camera.flax | 2 +- Content/Editor/CubeTexturePreviewMaterial.flax | 2 +- Content/Editor/DebugMaterials/DDGIDebugProbes.flax | 2 +- Content/Editor/DebugMaterials/SingleColor/Decal.flax | 2 +- Content/Editor/DebugMaterials/SingleColor/Particle.flax | 4 ++-- Content/Editor/DebugMaterials/SingleColor/Surface.flax | 2 +- .../Editor/DebugMaterials/SingleColor/SurfaceAdditive.flax | 4 ++-- Content/Editor/DebugMaterials/SingleColor/Terrain.flax | 2 +- Content/Editor/DefaultFontMaterial.flax | 2 +- Content/Editor/Gizmo/FoliageBrushMaterial.flax | 4 ++-- Content/Editor/Gizmo/Material.flax | 4 ++-- Content/Editor/Gizmo/MaterialWire.flax | 4 ++-- Content/Editor/Gizmo/SelectionOutlineMaterial.flax | 2 +- Content/Editor/Gizmo/VertexColorsPreviewMaterial.flax | 2 +- Content/Editor/Highlight Material.flax | 4 ++-- Content/Editor/Icons/IconsMaterial.flax | 4 ++-- Content/Editor/IesProfilePreviewMaterial.flax | 2 +- Content/Editor/Particles/Particle Material Color.flax | 4 ++-- Content/Editor/Particles/Smoke Material.flax | 4 ++-- Content/Editor/SpriteMaterial.flax | 2 +- Content/Editor/Terrain/Circle Brush Material.flax | 2 +- Content/Editor/Terrain/Highlight Terrain Material.flax | 2 +- Content/Editor/TexturePreviewMaterial.flax | 2 +- Content/Editor/Wires Debug Material.flax | 4 ++-- Content/Engine/DefaultDeformableMaterial.flax | 2 +- Content/Engine/DefaultMaterial.flax | 2 +- Content/Engine/DefaultRadialMenu.flax | 2 +- Content/Engine/DefaultTerrainMaterial.flax | 2 +- Content/Engine/SingleColorMaterial.flax | 2 +- Content/Engine/SkyboxMaterial.flax | 2 +- Content/Shaders/SSR.flax | 4 ++-- 31 files changed, 42 insertions(+), 42 deletions(-) diff --git a/Content/Editor/Camera/M_Camera.flax b/Content/Editor/Camera/M_Camera.flax index 16bf873eb..3e93768ea 100644 --- a/Content/Editor/Camera/M_Camera.flax +++ b/Content/Editor/Camera/M_Camera.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c7a4c3bb2a339de16d9738b35538d33670a224d69f8eba00e5977d03cfa85f83 +oid sha256:91bd11d6a7304b2fbf90a20e187e0361ad8197232f71e16bc7ce3a7a74a44899 size 30456 diff --git a/Content/Editor/CubeTexturePreviewMaterial.flax b/Content/Editor/CubeTexturePreviewMaterial.flax index d1e545233..20f23a065 100644 --- a/Content/Editor/CubeTexturePreviewMaterial.flax +++ b/Content/Editor/CubeTexturePreviewMaterial.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:89a9ab2a0168f0f51fd34ee064a896a65d1a3f85214cf04e370b82d41329cb09 +oid sha256:088ee6360b5dfaa084b70345219e986d2d98460d85660720e79d14cf3be89c43 size 32171 diff --git a/Content/Editor/DebugMaterials/DDGIDebugProbes.flax b/Content/Editor/DebugMaterials/DDGIDebugProbes.flax index 6a70e5490..967ab6221 100644 --- a/Content/Editor/DebugMaterials/DDGIDebugProbes.flax +++ b/Content/Editor/DebugMaterials/DDGIDebugProbes.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:90cfc9c29e29f8b25ff3f68394cb5133a95a936e7e6c0d0fe7cc4890a2a1ed61 +oid sha256:9b2c042f719386568cb4585f07bad544ced23bffe6094c3f0c482fa4edb13053 size 41404 diff --git a/Content/Editor/DebugMaterials/SingleColor/Decal.flax b/Content/Editor/DebugMaterials/SingleColor/Decal.flax index e1b60860c..83fae0f76 100644 --- a/Content/Editor/DebugMaterials/SingleColor/Decal.flax +++ b/Content/Editor/DebugMaterials/SingleColor/Decal.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:188d0f0574a2b12e96945fdde66082d0a63bf33965260969d50decbbbbd32590 +oid sha256:728b60a67786f8c50c02e3f496c76ad029943f4bc74e5769c5ac21faeef06d6e size 7489 diff --git a/Content/Editor/DebugMaterials/SingleColor/Particle.flax b/Content/Editor/DebugMaterials/SingleColor/Particle.flax index 1a84ad997..c53067528 100644 --- a/Content/Editor/DebugMaterials/SingleColor/Particle.flax +++ b/Content/Editor/DebugMaterials/SingleColor/Particle.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a6bfa4696c210cfdc8a3f3b6c1c28217e717bf8abe2dfacb793b36410681b388 -size 31721 +oid sha256:153b557292cab18c67490852e9ee80fd0dbdbf7e9fde559669e2440a9ce538f5 +size 32225 diff --git a/Content/Editor/DebugMaterials/SingleColor/Surface.flax b/Content/Editor/DebugMaterials/SingleColor/Surface.flax index e824434ac..09b96e399 100644 --- a/Content/Editor/DebugMaterials/SingleColor/Surface.flax +++ b/Content/Editor/DebugMaterials/SingleColor/Surface.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b5428f5f963d38ba8de16a932fba4f722e9b6bb03d874020122df3396841ea0e +oid sha256:da13bad48f77ba01bef9207fe5fb90b6a53dcf2ad48d6527598795dd1820bf14 size 30352 diff --git a/Content/Editor/DebugMaterials/SingleColor/SurfaceAdditive.flax b/Content/Editor/DebugMaterials/SingleColor/SurfaceAdditive.flax index 602434c46..a5b2ad177 100644 --- a/Content/Editor/DebugMaterials/SingleColor/SurfaceAdditive.flax +++ b/Content/Editor/DebugMaterials/SingleColor/SurfaceAdditive.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c4aa5cf0289c1489829e400d8c244712df6214520d1bc67feabcfe7e71c3b0f9 -size 32243 +oid sha256:89af473537cc03e7f0d07b3dfb0c515c608b1c38d572fcae01456b73bfc805b2 +size 32747 diff --git a/Content/Editor/DebugMaterials/SingleColor/Terrain.flax b/Content/Editor/DebugMaterials/SingleColor/Terrain.flax index 55029e5fb..4e385147c 100644 --- a/Content/Editor/DebugMaterials/SingleColor/Terrain.flax +++ b/Content/Editor/DebugMaterials/SingleColor/Terrain.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:07066043d6c634162ade92ca33119be5798fd9c8183712b6569e027c41cc1bff +oid sha256:a2430a9200896c29f5cefca67099895f453c91adce655cbe19711cb66f0f0f68 size 20737 diff --git a/Content/Editor/DefaultFontMaterial.flax b/Content/Editor/DefaultFontMaterial.flax index fd8e96f88..5f62ee8ef 100644 --- a/Content/Editor/DefaultFontMaterial.flax +++ b/Content/Editor/DefaultFontMaterial.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:33bd3e45519a05d48a7035f0740b3f879d962d80f7c4bc546505583585545341 +oid sha256:97f09eb4517c0e837033174115998aa673a196232f1cbc95ca50a6387613234c size 30531 diff --git a/Content/Editor/Gizmo/FoliageBrushMaterial.flax b/Content/Editor/Gizmo/FoliageBrushMaterial.flax index 81da98526..cf102fbd7 100644 --- a/Content/Editor/Gizmo/FoliageBrushMaterial.flax +++ b/Content/Editor/Gizmo/FoliageBrushMaterial.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eafdd82ba4c82f82e70525b4530f7f332646ce1f7d19c4c435fae84a25c502bf -size 38270 +oid sha256:c6f86f2215694fb0dccd685b9301c50c2c0f58a2fc669256632f03ca5dc57a8e +size 38774 diff --git a/Content/Editor/Gizmo/Material.flax b/Content/Editor/Gizmo/Material.flax index e6dab36f5..3dd1cd529 100644 --- a/Content/Editor/Gizmo/Material.flax +++ b/Content/Editor/Gizmo/Material.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ae83a3e9e14ebdd5bde7e6b40f8bd2de8a530a4471b111470d14359536f22a00 -size 32847 +oid sha256:a9b8f22650bac56484258539bee1a15f70ec6cb732c39e530494f128b3e523bd +size 33373 diff --git a/Content/Editor/Gizmo/MaterialWire.flax b/Content/Editor/Gizmo/MaterialWire.flax index b185becd2..1d6a332d6 100644 --- a/Content/Editor/Gizmo/MaterialWire.flax +++ b/Content/Editor/Gizmo/MaterialWire.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cc57eb71f0cde517be6082957b85439e6e464795bca9ef1c23fb00c679ac183a -size 31985 +oid sha256:21a6b790ea940e1b906306edd902f8796d02911126bc630d7afb31a2d5346dbe +size 32489 diff --git a/Content/Editor/Gizmo/SelectionOutlineMaterial.flax b/Content/Editor/Gizmo/SelectionOutlineMaterial.flax index f2877f0ec..be629fad7 100644 --- a/Content/Editor/Gizmo/SelectionOutlineMaterial.flax +++ b/Content/Editor/Gizmo/SelectionOutlineMaterial.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7fbde1a8dd1bdc621f562f18b7056c50de9df801719989c304a5a3aecbb31a4e +oid sha256:a8248cb3493de63e033edd1c5c784c57478eac0dd299505e43b57a0e7803f485 size 16166 diff --git a/Content/Editor/Gizmo/VertexColorsPreviewMaterial.flax b/Content/Editor/Gizmo/VertexColorsPreviewMaterial.flax index d92847c20..b42c9b927 100644 --- a/Content/Editor/Gizmo/VertexColorsPreviewMaterial.flax +++ b/Content/Editor/Gizmo/VertexColorsPreviewMaterial.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5835c9950bf5948a2a1bff56ed731a7e1788e0a03fea10e11762f40143057ae9 +oid sha256:6228ed09a33574dd15b169489c14268a873932334d0612d220da45cc973232ba size 31465 diff --git a/Content/Editor/Highlight Material.flax b/Content/Editor/Highlight Material.flax index 87488d15b..5dfd93651 100644 --- a/Content/Editor/Highlight Material.flax +++ b/Content/Editor/Highlight Material.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ecf23fb09c1d049f3c42668c2dabc6ce53f168af1b7b4d3ead13309799011e17 -size 30632 +oid sha256:2b8c75334a5b1966742706bb7ae1a6ed74cf58a32e47814cc33084ed90cb93f1 +size 31158 diff --git a/Content/Editor/Icons/IconsMaterial.flax b/Content/Editor/Icons/IconsMaterial.flax index 241c15820..296782a7b 100644 --- a/Content/Editor/Icons/IconsMaterial.flax +++ b/Content/Editor/Icons/IconsMaterial.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:97b6c13093d5ca38b2d70da09fb7c7e9a289dd6a7812d8333c67a5558e410b8e -size 30560 +oid sha256:0b98bdd3156ebe53935a51da9fa5b04216e4f49f88b5f5304749c67afb4062a2 +size 31086 diff --git a/Content/Editor/IesProfilePreviewMaterial.flax b/Content/Editor/IesProfilePreviewMaterial.flax index 818bec914..9ed068e8f 100644 --- a/Content/Editor/IesProfilePreviewMaterial.flax +++ b/Content/Editor/IesProfilePreviewMaterial.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:933cf9e187f8a475ae571560b4fe20edddc5d3a869e4696b81021031d8f4981c +oid sha256:39bf0f9e7d03c3356149fb768ff0b8b081e325bdbf4f12bd5ee8b5249aa49a0a size 18205 diff --git a/Content/Editor/Particles/Particle Material Color.flax b/Content/Editor/Particles/Particle Material Color.flax index c7f46c810..f51633f2d 100644 --- a/Content/Editor/Particles/Particle Material Color.flax +++ b/Content/Editor/Particles/Particle Material Color.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0156c820df3b48f412b66c0bfdbc462896b36b30f59cab250c5a06e274bc193f -size 29952 +oid sha256:6fd8f139ce4d7eb4e59c32c050416c267b6cf1749e32d43b127c7dea81457e0c +size 30456 diff --git a/Content/Editor/Particles/Smoke Material.flax b/Content/Editor/Particles/Smoke Material.flax index dae8d0226..6d2ade5f5 100644 --- a/Content/Editor/Particles/Smoke Material.flax +++ b/Content/Editor/Particles/Smoke Material.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:20635d62896ef520330d4a63b357a2e2f991b0fa7cdcd8bb586bfe5e7669717a -size 37132 +oid sha256:f307b7ccfff2c95c0a2642fbb43135961c0928d65c08c4a8bf5fbadd46534555 +size 37636 diff --git a/Content/Editor/SpriteMaterial.flax b/Content/Editor/SpriteMaterial.flax index 562280feb..2748f3b8d 100644 --- a/Content/Editor/SpriteMaterial.flax +++ b/Content/Editor/SpriteMaterial.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9c2385c51030b3224bce8896d4c692b41316373c76341c51f15bbf0c4c3fc240 +oid sha256:4d9860694b46d00e299ac8c883069d6df834e1070075ca5ff47eb854683d7c26 size 31544 diff --git a/Content/Editor/Terrain/Circle Brush Material.flax b/Content/Editor/Terrain/Circle Brush Material.flax index 38e8ac906..77bccb411 100644 --- a/Content/Editor/Terrain/Circle Brush Material.flax +++ b/Content/Editor/Terrain/Circle Brush Material.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f9c9455b6f4935d35b0a63cd9aea417f010576a630d3be9e1a124ca1d531ae8a +oid sha256:783c85f8938703a0ee1539de21a21843ae0cf6ca0d26df67c2debfac9398c3a4 size 27409 diff --git a/Content/Editor/Terrain/Highlight Terrain Material.flax b/Content/Editor/Terrain/Highlight Terrain Material.flax index f1e03310f..04a5fb7e0 100644 --- a/Content/Editor/Terrain/Highlight Terrain Material.flax +++ b/Content/Editor/Terrain/Highlight Terrain Material.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7436293db3692279754eaf29aed820a86ff214efc05a336a266582e8e0d3393c +oid sha256:098a1002fb6c50a2823792e22334e6d13d82b12227d4815c8066dd2ad8b3484d size 20790 diff --git a/Content/Editor/TexturePreviewMaterial.flax b/Content/Editor/TexturePreviewMaterial.flax index 80be4d726..85bf101ac 100644 --- a/Content/Editor/TexturePreviewMaterial.flax +++ b/Content/Editor/TexturePreviewMaterial.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3c8380071cf96428989cd6fd92d70c7b7ea694fe8a939608cd4367f957e75491 +oid sha256:15f87cf87b590acbf664847067557859809279b39de2a5dfeb5b7dd71ecb9013 size 10570 diff --git a/Content/Editor/Wires Debug Material.flax b/Content/Editor/Wires Debug Material.flax index 0834d47a6..e382c02f6 100644 --- a/Content/Editor/Wires Debug Material.flax +++ b/Content/Editor/Wires Debug Material.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a9dffca5051434a4731c16db377598d424dbeab57211331a8e7d16c05e18a7d9 -size 30632 +oid sha256:a575ee5265009b22fd675bd19284fe71a69410a5968c03c6e9e33bb2928665f3 +size 31136 diff --git a/Content/Engine/DefaultDeformableMaterial.flax b/Content/Engine/DefaultDeformableMaterial.flax index 097e5353c..0150b3279 100644 --- a/Content/Engine/DefaultDeformableMaterial.flax +++ b/Content/Engine/DefaultDeformableMaterial.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0fe507d8719930b86b9acfe2a6984f0d6e13523ba32c4c5df2c823bcb42281d9 +oid sha256:32200dbf1c0c5fb5f3f999b0f8b74c852a05bf7138d34ff9618cdd34e2831e7f size 18524 diff --git a/Content/Engine/DefaultMaterial.flax b/Content/Engine/DefaultMaterial.flax index 590833abc..3f31b7610 100644 --- a/Content/Engine/DefaultMaterial.flax +++ b/Content/Engine/DefaultMaterial.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:404951f3ab7a8f05b7bec519f441e27225411c327508f795ac007a401d8d1453 +oid sha256:1f8469e5fc068a62ee72b55553e0aef41251665a97c1e3db977c27ce8731fa3f size 32377 diff --git a/Content/Engine/DefaultRadialMenu.flax b/Content/Engine/DefaultRadialMenu.flax index 1159e4719..41af69613 100644 --- a/Content/Engine/DefaultRadialMenu.flax +++ b/Content/Engine/DefaultRadialMenu.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d7c517175501d1b41143a9d2d81950bf0d91d0556cfebca5784e7ef2c4ba94cf +oid sha256:4fe1e884c6ca9d3b0a9c6d0ebac3cad58216f539245cd642e74e7bb217a948f2 size 20340 diff --git a/Content/Engine/DefaultTerrainMaterial.flax b/Content/Engine/DefaultTerrainMaterial.flax index f21cdc1df..35bb0833e 100644 --- a/Content/Engine/DefaultTerrainMaterial.flax +++ b/Content/Engine/DefaultTerrainMaterial.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:210ca70aeac7856c59bfcfb0c3370bc60a6724a4f2346cf4fbee1715878ca672 +oid sha256:8659571dd94657ebfb6b13c8129e61e8d7aa5e32473f772c99d5b998b5f5ab6d size 22874 diff --git a/Content/Engine/SingleColorMaterial.flax b/Content/Engine/SingleColorMaterial.flax index 7edfefde9..4fbf7717d 100644 --- a/Content/Engine/SingleColorMaterial.flax +++ b/Content/Engine/SingleColorMaterial.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6c03577e1dda81ef42be30e3f7fb1dd92821baf52a30cec05aae6fa687ede451 +oid sha256:d4f1ac78ac1943cd276fdfebd265f1451ed37fc1d2a7aa144ed5164a2b2b6802 size 30553 diff --git a/Content/Engine/SkyboxMaterial.flax b/Content/Engine/SkyboxMaterial.flax index ac9e5fa57..6a26aa180 100644 --- a/Content/Engine/SkyboxMaterial.flax +++ b/Content/Engine/SkyboxMaterial.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4ddc74bc1aa47fe9b63e0a053b9dc56751ba2a9bcfa64987eddb230e382ef10a +oid sha256:83b4f1d136aaedd99d3d443d2867fbc0c22914c6a612e2cf34d4dda41a504011 size 31751 diff --git a/Content/Shaders/SSR.flax b/Content/Shaders/SSR.flax index b3c34e95e..b3fad3d88 100644 --- a/Content/Shaders/SSR.flax +++ b/Content/Shaders/SSR.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1c42203227cf1070143a4cd1a414cc3ae3625577c7d0dfd7d204f99bf8bc4542 -size 11142 +oid sha256:9f331e8d5300e0241520b063a6ceb9a5c7bdf42da78274ff9331788e7e239126 +size 11175