From 8b3f1ca01935387d5957ac4b403598b5503aa049 Mon Sep 17 00:00:00 2001 From: xxSeys1 Date: Wed, 9 Oct 2024 18:25:04 +0200 Subject: [PATCH 01/69] make "Edit Prefab" not change content panel file path If someone still wants to change the Content panel to the file path of the prefab, they can use the "Select Prefab" button --- Source/Editor/CustomEditors/Dedicated/ActorEditor.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Source/Editor/CustomEditors/Dedicated/ActorEditor.cs b/Source/Editor/CustomEditors/Dedicated/ActorEditor.cs index 27e2849bd..bc40c77ff 100644 --- a/Source/Editor/CustomEditors/Dedicated/ActorEditor.cs +++ b/Source/Editor/CustomEditors/Dedicated/ActorEditor.cs @@ -9,6 +9,7 @@ using FlaxEditor.CustomEditors.Elements; using FlaxEditor.GUI; using FlaxEditor.GUI.ContextMenu; using FlaxEditor.GUI.Tree; +using FlaxEditor.Modules; using FlaxEditor.Scripting; using FlaxEditor.Windows; using FlaxEditor.Windows.Assets; @@ -87,9 +88,7 @@ namespace FlaxEditor.CustomEditors.Dedicated var editPrefab = panel.Button("Edit Prefab"); editPrefab.Button.Clicked += () => { - Editor.Instance.Windows.ContentWin.ClearItemsSearch(); - Editor.Instance.Windows.ContentWin.Select(prefab); - Editor.Instance.Windows.ContentWin.Open(Editor.Instance.Windows.ContentWin.View.Selection[0]); + Editor.Instance.Windows.ContentWin.Open(Editor.Instance.ContentDatabase.FindAsset(prefab.ID)); }; // Viewing changes applied to this actor From 1fca41b31a4d84302f6a2ca3b662f084f5788616 Mon Sep 17 00:00:00 2001 From: xxSeys1 Date: Wed, 9 Oct 2024 18:29:48 +0200 Subject: [PATCH 02/69] code style fix --- Source/Editor/CustomEditors/Dedicated/ActorEditor.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Source/Editor/CustomEditors/Dedicated/ActorEditor.cs b/Source/Editor/CustomEditors/Dedicated/ActorEditor.cs index bc40c77ff..3e6785491 100644 --- a/Source/Editor/CustomEditors/Dedicated/ActorEditor.cs +++ b/Source/Editor/CustomEditors/Dedicated/ActorEditor.cs @@ -86,10 +86,7 @@ namespace FlaxEditor.CustomEditors.Dedicated // Edit selected prefab asset var editPrefab = panel.Button("Edit Prefab"); - editPrefab.Button.Clicked += () => - { - Editor.Instance.Windows.ContentWin.Open(Editor.Instance.ContentDatabase.FindAsset(prefab.ID)); - }; + editPrefab.Button.Clicked += () => Editor.Instance.Windows.ContentWin.Open(Editor.Instance.ContentDatabase.FindAsset(prefab.ID)); // Viewing changes applied to this actor var viewChanges = panel.Button("View Changes"); From 0335086df8b1a845ac2139a2a675bfd55c5b378e Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Fri, 22 Nov 2024 17:07:10 -0600 Subject: [PATCH 03/69] Add more scripting templates. --- Content/Editor/Scripting/ActorTemplate.cpp | 19 +++++ Content/Editor/Scripting/ActorTemplate.cs | 39 ++++++++++ Content/Editor/Scripting/ActorTemplate.h | 13 ++++ .../Editor/Scripting/EmptyClassTemplate.cs | 13 ++++ .../Scripting/EmptyInterfaceTemplate.cs | 13 ++++ .../Editor/Scripting/EmptyStructTemplate.cs | 13 ++++ Source/Editor/Content/Proxy/CSharpProxy.cs | 74 ++++++++++++++++++- Source/Editor/Content/Proxy/CppProxy.cs | 18 +++++ .../Editor/Modules/ContentDatabaseModule.cs | 5 ++ 9 files changed, 204 insertions(+), 3 deletions(-) create mode 100644 Content/Editor/Scripting/ActorTemplate.cpp create mode 100644 Content/Editor/Scripting/ActorTemplate.cs create mode 100644 Content/Editor/Scripting/ActorTemplate.h create mode 100644 Content/Editor/Scripting/EmptyClassTemplate.cs create mode 100644 Content/Editor/Scripting/EmptyInterfaceTemplate.cs create mode 100644 Content/Editor/Scripting/EmptyStructTemplate.cs diff --git a/Content/Editor/Scripting/ActorTemplate.cpp b/Content/Editor/Scripting/ActorTemplate.cpp new file mode 100644 index 000000000..826c361cc --- /dev/null +++ b/Content/Editor/Scripting/ActorTemplate.cpp @@ -0,0 +1,19 @@ +%copyright%#include "%filename%.h" + +%class%::%class%(const SpawnParams& params) + : Actor(params) +{ + +} + +void %class%::OnEnable() +{ + Actor::OnEnable(); + // Here you can add code that needs to be called when script is enabled (eg. register for events) +} + +void %class%::OnDisable() +{ + Actor::OnDisable(); + // Here you can add code that needs to be called when script is disabled (eg. unregister from events) +} diff --git a/Content/Editor/Scripting/ActorTemplate.cs b/Content/Editor/Scripting/ActorTemplate.cs new file mode 100644 index 000000000..20714b22b --- /dev/null +++ b/Content/Editor/Scripting/ActorTemplate.cs @@ -0,0 +1,39 @@ +%copyright%using System; +using System.Collections.Generic; +using FlaxEngine; + +namespace %namespace%; + +/// +/// %class% Actor. +/// +public class %class% : Actor +{ + /// + public override void OnBeginPlay() + { + base.OnBeginPlay(); + // Here you can add code that needs to be called when Actor added to the game. This is called during edit time as well. + } + + /// + public override void OnEndPlay() + { + base.OnEndPlay(); + // Here you can add code that needs to be called when Actor removed to the game. This is called during edit time as well. + } + + /// + public override void OnEnable() + { + base.OnEnable(); + // Here you can add code that needs to be called when Actor is enabled (eg. register for events). This is called during edit time as well. + } + + /// + public override void OnDisable() + { + base.OnDisable(); + // Here you can add code that needs to be called when Actor is disabled (eg. unregister from events). This is called during edit time as well. + } +} diff --git a/Content/Editor/Scripting/ActorTemplate.h b/Content/Editor/Scripting/ActorTemplate.h new file mode 100644 index 000000000..e97651a51 --- /dev/null +++ b/Content/Editor/Scripting/ActorTemplate.h @@ -0,0 +1,13 @@ +%copyright%#pragma once + +#include "Engine/Level/Actor.h" + +API_CLASS() class %module%%class% : public Actor +{ +API_AUTO_SERIALIZATION(); +DECLARE_SCENE_OBJECT(%class%); + + // [Actor] + void OnEnable() override; + void OnDisable() override; +}; diff --git a/Content/Editor/Scripting/EmptyClassTemplate.cs b/Content/Editor/Scripting/EmptyClassTemplate.cs new file mode 100644 index 000000000..613f80cfa --- /dev/null +++ b/Content/Editor/Scripting/EmptyClassTemplate.cs @@ -0,0 +1,13 @@ +%copyright%using System; +using System.Collections.Generic; +using FlaxEngine; + +namespace %namespace%; + +/// +/// %class% class. +/// +public class %class% +{ + +} diff --git a/Content/Editor/Scripting/EmptyInterfaceTemplate.cs b/Content/Editor/Scripting/EmptyInterfaceTemplate.cs new file mode 100644 index 000000000..9738379bd --- /dev/null +++ b/Content/Editor/Scripting/EmptyInterfaceTemplate.cs @@ -0,0 +1,13 @@ +%copyright%using System; +using System.Collections.Generic; +using FlaxEngine; + +namespace %namespace%; + +/// +/// %class% interface. +/// +public interface %class% +{ + +} diff --git a/Content/Editor/Scripting/EmptyStructTemplate.cs b/Content/Editor/Scripting/EmptyStructTemplate.cs new file mode 100644 index 000000000..3cca5aed4 --- /dev/null +++ b/Content/Editor/Scripting/EmptyStructTemplate.cs @@ -0,0 +1,13 @@ +%copyright%using System; +using System.Collections.Generic; +using FlaxEngine; + +namespace %namespace%; + +/// +/// %class% struct. +/// +public struct %class% +{ + +} diff --git a/Source/Editor/Content/Proxy/CSharpProxy.cs b/Source/Editor/Content/Proxy/CSharpProxy.cs index 099ad6109..0476d6aa8 100644 --- a/Source/Editor/Content/Proxy/CSharpProxy.cs +++ b/Source/Editor/Content/Proxy/CSharpProxy.cs @@ -73,10 +73,10 @@ namespace FlaxEditor.Content } /// - /// Context proxy object for C# script files. + /// Context proxy object for C# Script files. /// /// - [ContentContextMenu("New/C#/C# Script")] + [ContentContextMenu("New/C#/Scripting/C# Script")] public class CSharpScriptProxy : CSharpProxy { /// @@ -89,11 +89,28 @@ namespace FlaxEditor.Content } } + /// + /// Context proxy object for C# Actor files. + /// + /// + [ContentContextMenu("New/C#/Scripting/C# Actor")] + public class CSharpActorProxy : CSharpProxy + { + /// + public override string Name => "C# Actor"; + + /// + protected override void GetTemplatePath(out string path) + { + path = StringUtils.CombinePaths(Globals.EngineContentFolder, "Editor/Scripting/ActorTemplate.cs"); + } + } + /// /// Context proxy object for empty C# files. /// /// - [ContentContextMenu("New/C#/C# Empty File")] + [ContentContextMenu("New/C#/Generic/C# Empty File")] public class CSharpEmptyProxy : CSharpProxy { /// @@ -105,4 +122,55 @@ namespace FlaxEditor.Content path = StringUtils.CombinePaths(Globals.EngineContentFolder, "Editor/Scripting/CSharpEmptyTemplate.cs"); } } + + /// + /// Context proxy object for empty C# class files. + /// + /// + [ContentContextMenu("New/C#/Generic/C# Class")] + public class CSharpEmptyClassProxy : CSharpProxy + { + /// + public override string Name => "C# Class"; + + /// + protected override void GetTemplatePath(out string path) + { + path = StringUtils.CombinePaths(Globals.EngineContentFolder, "Editor/Scripting/EmptyClassTemplate.cs"); + } + } + + /// + /// Context proxy object for empty C# struct files. + /// + /// + [ContentContextMenu("New/C#/Generic/C# Struct")] + public class CSharpEmptyStructProxy : CSharpProxy + { + /// + public override string Name => "C# Struct"; + + /// + protected override void GetTemplatePath(out string path) + { + path = StringUtils.CombinePaths(Globals.EngineContentFolder, "Editor/Scripting/EmptyStructTemplate.cs"); + } + } + + /// + /// Context proxy object for empty C# interface files. + /// + /// + [ContentContextMenu("New/C#/Generic/C# Interface")] + public class CSharpEmptyInterfaceProxy : CSharpProxy + { + /// + public override string Name => "C# Interface"; + + /// + protected override void GetTemplatePath(out string path) + { + path = StringUtils.CombinePaths(Globals.EngineContentFolder, "Editor/Scripting/EmptyInterfaceTemplate.cs"); + } + } } diff --git a/Source/Editor/Content/Proxy/CppProxy.cs b/Source/Editor/Content/Proxy/CppProxy.cs index af5f93421..3d3b6588f 100644 --- a/Source/Editor/Content/Proxy/CppProxy.cs +++ b/Source/Editor/Content/Proxy/CppProxy.cs @@ -100,6 +100,24 @@ namespace FlaxEditor.Content sourceTemplate = StringUtils.CombinePaths(Globals.EngineContentFolder, "Editor/Scripting/ScriptTemplate.cpp"); } } + + /// + /// Context proxy object for C++ Actor files. + /// + /// + [ContentContextMenu("New/C++/C++ Actor")] + public class CppActorProxy : CppProxy + { + /// + public override string Name => "C++ Actor"; + + /// + protected override void GetTemplatePaths(out string headerTemplate, out string sourceTemplate) + { + headerTemplate = StringUtils.CombinePaths(Globals.EngineContentFolder, "Editor/Scripting/ActorTemplate.h"); + sourceTemplate = StringUtils.CombinePaths(Globals.EngineContentFolder, "Editor/Scripting/ActorTemplate.cpp"); + } + } /// /// Context proxy object for C++ Json Asset files. diff --git a/Source/Editor/Modules/ContentDatabaseModule.cs b/Source/Editor/Modules/ContentDatabaseModule.cs index c42bd9d86..7a85107d9 100644 --- a/Source/Editor/Modules/ContentDatabaseModule.cs +++ b/Source/Editor/Modules/ContentDatabaseModule.cs @@ -1136,9 +1136,14 @@ namespace FlaxEditor.Modules Proxy.Add(new SceneAnimationProxy()); Proxy.Add(new CSharpScriptProxy()); Proxy.Add(new CSharpEmptyProxy()); + Proxy.Add(new CSharpEmptyClassProxy()); + Proxy.Add(new CSharpEmptyStructProxy()); + Proxy.Add(new CSharpEmptyInterfaceProxy()); + Proxy.Add(new CSharpActorProxy()); Proxy.Add(new CppAssetProxy()); Proxy.Add(new CppStaticClassProxy()); Proxy.Add(new CppScriptProxy()); + Proxy.Add(new CppActorProxy()); Proxy.Add(new SceneProxy()); Proxy.Add(new PrefabProxy()); Proxy.Add(new IESProfileProxy()); From c7fd1999dbc7e3513565f5bcb3a34a48941c1363 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Tue, 26 Nov 2024 20:22:36 -0600 Subject: [PATCH 04/69] Remove c# template menus. --- Source/Editor/Content/Proxy/CSharpProxy.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Source/Editor/Content/Proxy/CSharpProxy.cs b/Source/Editor/Content/Proxy/CSharpProxy.cs index 0476d6aa8..8abdf8b30 100644 --- a/Source/Editor/Content/Proxy/CSharpProxy.cs +++ b/Source/Editor/Content/Proxy/CSharpProxy.cs @@ -76,7 +76,7 @@ namespace FlaxEditor.Content /// Context proxy object for C# Script files. /// /// - [ContentContextMenu("New/C#/Scripting/C# Script")] + [ContentContextMenu("New/C#/C# Script")] public class CSharpScriptProxy : CSharpProxy { /// @@ -93,7 +93,7 @@ namespace FlaxEditor.Content /// Context proxy object for C# Actor files. /// /// - [ContentContextMenu("New/C#/Scripting/C# Actor")] + [ContentContextMenu("New/C#/C# Actor")] public class CSharpActorProxy : CSharpProxy { /// @@ -110,7 +110,7 @@ namespace FlaxEditor.Content /// Context proxy object for empty C# files. /// /// - [ContentContextMenu("New/C#/Generic/C# Empty File")] + [ContentContextMenu("New/C#/C# Empty File")] public class CSharpEmptyProxy : CSharpProxy { /// @@ -127,7 +127,7 @@ namespace FlaxEditor.Content /// Context proxy object for empty C# class files. /// /// - [ContentContextMenu("New/C#/Generic/C# Class")] + [ContentContextMenu("New/C#/C# Class")] public class CSharpEmptyClassProxy : CSharpProxy { /// @@ -144,7 +144,7 @@ namespace FlaxEditor.Content /// Context proxy object for empty C# struct files. /// /// - [ContentContextMenu("New/C#/Generic/C# Struct")] + [ContentContextMenu("New/C#/C# Struct")] public class CSharpEmptyStructProxy : CSharpProxy { /// @@ -161,7 +161,7 @@ namespace FlaxEditor.Content /// Context proxy object for empty C# interface files. /// /// - [ContentContextMenu("New/C#/Generic/C# Interface")] + [ContentContextMenu("New/C#/C# Interface")] public class CSharpEmptyInterfaceProxy : CSharpProxy { /// From f9e125f795793de63aa04d3cb7854b36840034f3 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Tue, 3 Dec 2024 17:59:30 -0600 Subject: [PATCH 05/69] Select dropped actors that are reparented. --- Source/Editor/SceneGraph/GUI/ActorTreeNode.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs b/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs index f7ad55a42..b6b69950d 100644 --- a/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs +++ b/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs @@ -596,11 +596,17 @@ namespace FlaxEditor.SceneGraph.GUI { bool worldPositionsStays = Root.GetKey(KeyboardKeys.Control) == false; var objects = new SceneObject[_dragActors.Objects.Count]; + var treeNodes = new TreeNode[_dragActors.Objects.Count]; for (int i = 0; i < objects.Length; i++) + { objects[i] = _dragActors.Objects[i].Actor; + treeNodes[i] = _dragActors.Objects[i].TreeNode; + } var action = new ParentActorsAction(objects, newParent, newOrder, worldPositionsStays); ActorNode.Root.Undo?.AddAction(action); action.Do(); + ParentTree.Focus(); + ParentTree.Select(treeNodes.ToList()); result = DragDropEffect.Move; } // Drag scripts From 66cc3196e1222f031c27f3b4d277c82dfdf52025 Mon Sep 17 00:00:00 2001 From: xxSeys1 Date: Thu, 5 Dec 2024 20:50:32 +0100 Subject: [PATCH 06/69] improve "Editor Options -> Visual" categories --- Source/Editor/Options/VisualOptions.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Source/Editor/Options/VisualOptions.cs b/Source/Editor/Options/VisualOptions.cs index 4e94538e2..8a55ded91 100644 --- a/Source/Editor/Options/VisualOptions.cs +++ b/Source/Editor/Options/VisualOptions.cs @@ -22,35 +22,35 @@ namespace FlaxEditor.Options /// Gets or sets the first outline color. /// [DefaultValue(typeof(Color), "0.039,0.827,0.156")] - [EditorDisplay("Gizmo"), EditorOrder(100), Tooltip("The first color of the selection outline gradient.")] + [EditorDisplay("Transform Gizmo"), EditorOrder(100), Tooltip("The first color of the selection outline gradient.")] public Color SelectionOutlineColor0 { get; set; } = new Color(0.039f, 0.827f, 0.156f); /// /// Gets or sets the second outline color. /// [DefaultValue(typeof(Color), "0.019,0.615,0.101")] - [EditorDisplay("Gizmo"), EditorOrder(101), Tooltip("The second color of the selection outline gradient.")] + [EditorDisplay("Transform Gizmo"), EditorOrder(101), Tooltip("The second color of the selection outline gradient.")] public Color SelectionOutlineColor1 { get; set; } = new Color(0.019f, 0.615f, 0.101f); /// /// Gets or sets the selection outline size for UI controls. /// [DefaultValue(2.0f)] - [EditorDisplay("Gizmo", "UI Control Outline Size"), EditorOrder(100), Tooltip("The size of the selection outline for UI controls.")] + [EditorDisplay("UI Gizmo", "UI Control Outline Size"), EditorOrder(103), Tooltip("The size of the selection outline for UI controls.")] public float UISelectionOutlineSize { get; set; } = 2.0f; /// /// Gets or sets the transform gizmo size. /// [DefaultValue(1.0f), Limit(0.01f, 100.0f, 0.01f)] - [EditorDisplay("Gizmo"), EditorOrder(110), Tooltip("The transform gizmo size.")] + [EditorDisplay("Transform Gizmo"), EditorOrder(110), Tooltip("The transform gizmo size.")] public float GizmoSize { get; set; } = 1.0f; /// /// Gets or sets the color used to highlight selected meshes and CSG surfaces. /// [DefaultValue(typeof(Color), "0.0,0.533,1.0,1.0")] - [EditorDisplay("Gizmo"), EditorOrder(200), Tooltip("The color used to highlight selected meshes and CSG surfaces.")] + [EditorDisplay("Transform Gizmo"), EditorOrder(200), Tooltip("The color used to highlight selected meshes and CSG surfaces.")] public Color HighlightColor { get; set; } = new Color(0.0f, 0.533f, 1.0f, 1.0f); /// From cee0b24b9fefc77ebeddb8e586e655a0b6df5d8d Mon Sep 17 00:00:00 2001 From: xxSeys1 Date: Thu, 5 Dec 2024 21:10:26 +0100 Subject: [PATCH 07/69] add options for gizmo brightness and opacity --- .../Editor/Gizmo/TransformGizmoBase.Draw.cs | 86 +++++++++++++++---- Source/Editor/Options/VisualOptions.cs | 14 +++ 2 files changed, 85 insertions(+), 15 deletions(-) diff --git a/Source/Editor/Gizmo/TransformGizmoBase.Draw.cs b/Source/Editor/Gizmo/TransformGizmoBase.Draw.cs index fe2e7b9e3..4166b463d 100644 --- a/Source/Editor/Gizmo/TransformGizmoBase.Draw.cs +++ b/Source/Editor/Gizmo/TransformGizmoBase.Draw.cs @@ -1,6 +1,9 @@ // Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. +using FlaxEditor.Options; +using FlaxEditor.SceneGraph; using FlaxEngine; +using System; namespace FlaxEditor.Gizmo { @@ -18,8 +21,13 @@ namespace FlaxEditor.Gizmo private MaterialInstance _materialAxisY; private MaterialInstance _materialAxisZ; private MaterialInstance _materialAxisFocus; + private MaterialInstance _materialAxisLocked; private MaterialBase _materialSphere; + // Material Parameter Names + const String _brightnessParamName = "Brightness"; + const String _opacityParamName = "Opacity"; + private void InitDrawing() { // Axis Models @@ -34,6 +42,7 @@ namespace FlaxEditor.Gizmo _materialAxisY = FlaxEngine.Content.LoadAsyncInternal("Editor/Gizmo/MaterialAxisY"); _materialAxisZ = FlaxEngine.Content.LoadAsyncInternal("Editor/Gizmo/MaterialAxisZ"); _materialAxisFocus = FlaxEngine.Content.LoadAsyncInternal("Editor/Gizmo/MaterialAxisFocus"); + _materialAxisLocked = FlaxEngine.Content.LoadAsyncInternal("Editor/Gizmo/MaterialAxisLocked"); _materialSphere = FlaxEngine.Content.LoadAsyncInternal("Editor/Gizmo/MaterialSphere"); // Ensure that every asset was loaded @@ -50,6 +59,23 @@ namespace FlaxEditor.Gizmo { Platform.Fatal("Failed to load transform gizmo resources."); } + + ApplyGizmoOptionsToMaterials(Editor.Instance.Options.Options); + + Editor.Instance.Options.OptionsChanged += ApplyGizmoOptionsToMaterials; + } + + private void ApplyGizmoOptionsToMaterials(EditorOptions o) + { + _materialAxisX.SetParameterValue(_brightnessParamName, o.Visual.transformGizmoBrightness); + _materialAxisY.SetParameterValue(_brightnessParamName, o.Visual.transformGizmoBrightness); + _materialAxisZ.SetParameterValue(_brightnessParamName, o.Visual.transformGizmoBrightness); + _materialAxisLocked.SetParameterValue(_brightnessParamName, o.Visual.transformGizmoBrightness); + + _materialAxisX.SetParameterValue(_opacityParamName, o.Visual.transformGizmoOpacity); + _materialAxisY.SetParameterValue(_opacityParamName, o.Visual.transformGizmoOpacity); + _materialAxisZ.SetParameterValue(_opacityParamName, o.Visual.transformGizmoOpacity); + _materialAxisLocked.SetParameterValue(_opacityParamName, o.Visual.transformGizmoOpacity); } /// @@ -60,6 +86,21 @@ namespace FlaxEditor.Gizmo if (!_modelCube || !_modelCube.IsLoaded) return; + bool gizmoLocked = false; + + // Find out if any of the selected objects can not be moved. + if (Editor.Instance.StateMachine.IsPlayMode) + { + foreach (SceneGraphNode obj in Editor.Instance.SceneEditing.Selection) + { + if (obj.CanTransform == false) + { + gizmoLocked = true; + break; + } + } + } + // As all axisMesh have the same pivot, add a little offset to the x axisMesh, this way SortDrawCalls is able to sort the draw order // https://github.com/FlaxEngine/FlaxEngine/issues/680 @@ -92,32 +133,38 @@ namespace FlaxEditor.Gizmo // X axis Matrix.RotationY(-Mathf.PiOverTwo, out m2); Matrix.Multiply(ref m2, ref m1, out m3); - transAxisMesh.Draw(ref renderContext, isXAxis ? _materialAxisFocus : _materialAxisX, ref m3); + MaterialInstance xAxisMaterialTransform = gizmoLocked ? _materialAxisLocked : (isXAxis ? _materialAxisFocus : _materialAxisX); + transAxisMesh.Draw(ref renderContext, xAxisMaterialTransform, ref m3); // Y axis Matrix.RotationX(Mathf.PiOverTwo, out m2); Matrix.Multiply(ref m2, ref m1, out m3); - transAxisMesh.Draw(ref renderContext, isYAxis ? _materialAxisFocus : _materialAxisY, ref m3); + MaterialInstance yAxisMaterialTransform = gizmoLocked ? _materialAxisLocked : (isYAxis ? _materialAxisFocus : _materialAxisY); + transAxisMesh.Draw(ref renderContext, yAxisMaterialTransform, ref m3); // Z axis Matrix.RotationX(Mathf.Pi, out m2); Matrix.Multiply(ref m2, ref m1, out m3); - transAxisMesh.Draw(ref renderContext, isZAxis ? _materialAxisFocus : _materialAxisZ, ref m3); + MaterialInstance zAxisMaterialTransform = gizmoLocked ? _materialAxisLocked : (isZAxis ? _materialAxisFocus : _materialAxisZ); + transAxisMesh.Draw(ref renderContext, zAxisMaterialTransform, ref m3); // XY plane m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationX(Mathf.PiOverTwo), new Vector3(boxSize * boxScale, boxSize * boxScale, 0.0f)); Matrix.Multiply(ref m2, ref m1, out m3); - cubeMesh.Draw(ref renderContext, _activeAxis == Axis.XY ? _materialAxisFocus : _materialAxisX, ref m3); + MaterialInstance xyPlaneMaterialTransform = gizmoLocked ? _materialAxisLocked : (_activeAxis == Axis.XY ? _materialAxisFocus : _materialAxisX); + cubeMesh.Draw(ref renderContext, xyPlaneMaterialTransform, ref m3); // ZX plane m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.Identity, new Vector3(boxSize * boxScale, 0.0f, boxSize * boxScale)); Matrix.Multiply(ref m2, ref m1, out m3); - cubeMesh.Draw(ref renderContext, _activeAxis == Axis.ZX ? _materialAxisFocus : _materialAxisZ, ref m3); + MaterialInstance zxPlaneMaterialTransform = gizmoLocked ? _materialAxisLocked : (_activeAxis == Axis.ZX ? _materialAxisFocus : _materialAxisY); + cubeMesh.Draw(ref renderContext, zxPlaneMaterialTransform, ref m3); // YZ plane m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationZ(Mathf.PiOverTwo), new Vector3(0.0f, boxSize * boxScale, boxSize * boxScale)); Matrix.Multiply(ref m2, ref m1, out m3); - cubeMesh.Draw(ref renderContext, _activeAxis == Axis.YZ ? _materialAxisFocus : _materialAxisY, ref m3); + MaterialInstance yzPlaneMaterialTransform = gizmoLocked ? _materialAxisLocked : (_activeAxis == Axis.YZ ? _materialAxisFocus : _materialAxisZ); + cubeMesh.Draw(ref renderContext, yzPlaneMaterialTransform, ref m3); // Center sphere Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2); @@ -136,15 +183,18 @@ namespace FlaxEditor.Gizmo // X axis Matrix.RotationZ(Mathf.PiOverTwo, out m2); Matrix.Multiply(ref m2, ref m1, out m3); - rotationAxisMesh.Draw(ref renderContext, isXAxis ? _materialAxisFocus : _materialAxisX, ref m3); + MaterialInstance xAxisMaterialRotate = gizmoLocked ? _materialAxisLocked : (isXAxis ? _materialAxisFocus : _materialAxisX); + rotationAxisMesh.Draw(ref renderContext, xAxisMaterialRotate, ref m3); // Y axis - rotationAxisMesh.Draw(ref renderContext, isYAxis ? _materialAxisFocus : _materialAxisY, ref m1); + MaterialInstance yAxisMaterialRotate = gizmoLocked ? _materialAxisLocked : (isYAxis ? _materialAxisFocus : _materialAxisY); + rotationAxisMesh.Draw(ref renderContext, yAxisMaterialRotate, ref m1); // Z axis Matrix.RotationX(-Mathf.PiOverTwo, out m2); Matrix.Multiply(ref m2, ref m1, out m3); - rotationAxisMesh.Draw(ref renderContext, isZAxis ? _materialAxisFocus : _materialAxisZ, ref m3); + MaterialInstance zAxisMaterialRotate = gizmoLocked ? _materialAxisLocked : (isZAxis ? _materialAxisFocus : _materialAxisZ); + rotationAxisMesh.Draw(ref renderContext, zAxisMaterialRotate, ref m3); // Center box Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2); @@ -163,32 +213,38 @@ namespace FlaxEditor.Gizmo // X axis Matrix.RotationY(-Mathf.PiOverTwo, out m2); Matrix.Multiply(ref m2, ref mx1, out m3); - scaleAxisMesh.Draw(ref renderContext, isXAxis ? _materialAxisFocus : _materialAxisX, ref m3); + MaterialInstance xAxisMaterialRotate = gizmoLocked ? _materialAxisLocked : (isXAxis ? _materialAxisFocus : _materialAxisX); + scaleAxisMesh.Draw(ref renderContext, xAxisMaterialRotate, ref m3); // Y axis Matrix.RotationX(Mathf.PiOverTwo, out m2); Matrix.Multiply(ref m2, ref m1, out m3); - scaleAxisMesh.Draw(ref renderContext, isYAxis ? _materialAxisFocus : _materialAxisY, ref m3); + MaterialInstance yAxisMaterialRotate = gizmoLocked ? _materialAxisLocked : (isYAxis ? _materialAxisFocus : _materialAxisY); + scaleAxisMesh.Draw(ref renderContext, yAxisMaterialRotate, ref m3); // Z axis Matrix.RotationX(Mathf.Pi, out m2); Matrix.Multiply(ref m2, ref m1, out m3); - scaleAxisMesh.Draw(ref renderContext, isZAxis ? _materialAxisFocus : _materialAxisZ, ref m3); + MaterialInstance zAxisMaterialRotate = gizmoLocked ? _materialAxisLocked : (isZAxis ? _materialAxisFocus : _materialAxisZ); + scaleAxisMesh.Draw(ref renderContext, zAxisMaterialRotate, ref m3); // XY plane m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationX(Mathf.PiOverTwo), new Vector3(boxSize * boxScale, boxSize * boxScale, 0.0f)); Matrix.Multiply(ref m2, ref m1, out m3); - cubeMesh.Draw(ref renderContext, _activeAxis == Axis.XY ? _materialAxisFocus : _materialAxisX, ref m3); + MaterialInstance xyPlaneMaterialScale = gizmoLocked ? _materialAxisLocked : (_activeAxis == Axis.XY ? _materialAxisFocus : _materialAxisX); + cubeMesh.Draw(ref renderContext, xyPlaneMaterialScale, ref m3); // ZX plane m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.Identity, new Vector3(boxSize * boxScale, 0.0f, boxSize * boxScale)); Matrix.Multiply(ref m2, ref m1, out m3); - cubeMesh.Draw(ref renderContext, _activeAxis == Axis.ZX ? _materialAxisFocus : _materialAxisZ, ref m3); + MaterialInstance zxPlaneMaterialScale = gizmoLocked ? _materialAxisLocked : (_activeAxis == Axis.ZX ? _materialAxisFocus : _materialAxisZ); + cubeMesh.Draw(ref renderContext, zxPlaneMaterialScale, ref m3); // YZ plane m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationZ(Mathf.PiOverTwo), new Vector3(0.0f, boxSize * boxScale, boxSize * boxScale)); Matrix.Multiply(ref m2, ref m1, out m3); - cubeMesh.Draw(ref renderContext, _activeAxis == Axis.YZ ? _materialAxisFocus : _materialAxisY, ref m3); + MaterialInstance yzPlaneMaterialScale = gizmoLocked ? _materialAxisLocked : (_activeAxis == Axis.YZ ? _materialAxisFocus : _materialAxisY); + cubeMesh.Draw(ref renderContext, yzPlaneMaterialScale, ref m3); // Center box Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2); diff --git a/Source/Editor/Options/VisualOptions.cs b/Source/Editor/Options/VisualOptions.cs index 8a55ded91..5314cd8c1 100644 --- a/Source/Editor/Options/VisualOptions.cs +++ b/Source/Editor/Options/VisualOptions.cs @@ -53,6 +53,20 @@ namespace FlaxEditor.Options [EditorDisplay("Transform Gizmo"), EditorOrder(200), Tooltip("The color used to highlight selected meshes and CSG surfaces.")] public Color HighlightColor { get; set; } = new Color(0.0f, 0.533f, 1.0f, 1.0f); + /// + /// Gets or set a value indicating how bright the transform gizmo is. Value over 1 will result in the gizmo emitting light. + /// + [DefaultValue(1f), Range(0f, 5f)] + [EditorDisplay("Transform Gizmo", "Gizmo Brightness"), EditorOrder(210)] + public float transformGizmoBrightness { get; set; } = 1f; + + /// + /// Gets or set a value indicating the opactiy of the transform gizmo. + /// + [DefaultValue(1f), Range(0f, 1f)] + [EditorDisplay("Transform Gizmo", "Gizmo Opacity"), EditorOrder(211)] + public float transformGizmoOpacity { get; set; } = 1f; + /// /// Gets or sets a value indicating whether enable MSAA for DebugDraw primitives rendering. Helps with pixel aliasing but reduces performance. /// From 82453acf53a80c0dd224747b846cff3b3c02589b Mon Sep 17 00:00:00 2001 From: Nils Hausfeld Date: Sat, 7 Dec 2024 18:42:00 +0100 Subject: [PATCH 08/69] - Added the ability to rename selected visject comments by pressing F2 - Added rename option to context menu for visject comments --- Source/Editor/Surface/SurfaceComment.cs | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/Source/Editor/Surface/SurfaceComment.cs b/Source/Editor/Surface/SurfaceComment.cs index d072ee28e..ef32b160a 100644 --- a/Source/Editor/Surface/SurfaceComment.cs +++ b/Source/Editor/Surface/SurfaceComment.cs @@ -172,10 +172,21 @@ namespace FlaxEditor.Surface /// public override void Update(float deltaTime) { - if (_isRenaming && (!_renameTextBox.IsFocused || !RootWindow.IsFocused)) + if (_isRenaming) { - Rename(_renameTextBox.Text); - StopRenaming(); + // Stop renaming when clicking anywhere else + if (!_renameTextBox.IsFocused || !RootWindow.IsFocused) + { + Rename(_renameTextBox.Text); + StopRenaming(); + } + } + else + { + if (IsSelected && Input.GetKeyDown(KeyboardKeys.F2)) + { + StartRenaming(); + } } base.Update(deltaTime); @@ -417,6 +428,12 @@ namespace FlaxEditor.Surface base.OnShowSecondaryContextMenu(menu, location); menu.AddSeparator(); + menu.AddButton("Rename", () => + { + if(!_isRenaming) + StartRenaming(); + }); + ContextMenuChildMenu cmOrder = menu.AddChildMenu("Order"); { cmOrder.ContextMenu.AddButton("Bring Forward", () => From e9243d03580caa3e35076e8e061cb9a0ca9de654 Mon Sep 17 00:00:00 2001 From: Nils Hausfeld Date: Sat, 7 Dec 2024 19:15:14 +0100 Subject: [PATCH 09/69] - Fixed regression of commit ec7840f36b9bbdd31ca76e27502d639e8d5ca5f6 that caused surface comments created with "// " to throw an error --- Source/Editor/Surface/Archetypes/Tools.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Source/Editor/Surface/Archetypes/Tools.cs b/Source/Editor/Surface/Archetypes/Tools.cs index e2b330616..c4ff4a03c 100644 --- a/Source/Editor/Surface/Archetypes/Tools.cs +++ b/Source/Editor/Surface/Archetypes/Tools.cs @@ -1502,9 +1502,10 @@ namespace FlaxEditor.Surface.Archetypes { data = new object[] { - filterText.Substring(2), - new Color(1.0f, 1.0f, 1.0f, 0.2f), - new Float2(400.0f, 400.0f), + filterText.Substring(2), // Title + new Color(1.0f, 1.0f, 1.0f, 0.2f), // Color + new Float2(400.0f, 400.0f), // Size + -1, // Order }; return true; } From 23015009b3c8519da83614de399c8599f7e20083 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Tue, 10 Dec 2024 12:50:28 +0100 Subject: [PATCH 10/69] Update Vulkan SDK to `1.3.296.0` for Github Actions --- .github/actions/vulkan/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/vulkan/action.yml b/.github/actions/vulkan/action.yml index e0db012f7..ba92b7f01 100644 --- a/.github/actions/vulkan/action.yml +++ b/.github/actions/vulkan/action.yml @@ -3,7 +3,7 @@ description: Downloads and installs Vulkan SDK. inputs: vulkan-version: description: 'Vulkan SDK release version (e.g. 1.2.198.1).' - default: '1.2.198.1' + default: '1.3.296.0' required: false runs: using: "composite" From 5ffc06d6eedeb74dbca55159609761b808c0486f Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Tue, 10 Dec 2024 13:00:19 +0100 Subject: [PATCH 11/69] Fix Vulkan SDK install on Mac to use explicit image file name --- .github/actions/vulkan/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/vulkan/action.yml b/.github/actions/vulkan/action.yml index ba92b7f01..de271675a 100644 --- a/.github/actions/vulkan/action.yml +++ b/.github/actions/vulkan/action.yml @@ -24,7 +24,7 @@ runs: ;; Darwin) export VULKAN_SDK_ROOT=`pwd`/../VulkanSDK - curl -LO "https://sdk.lunarg.com/sdk/download/$VULKAN_SDK_VER/mac/vulkan-sdk.dmg" + curl -L -o vulkan-sdk.dmg "https://sdk.lunarg.com/sdk/download/$VULKAN_SDK_VER/mac/vulkan-sdk.dmg" hdiutil attach vulkan-sdk.dmg -mountpoint /Volumes/vulkan-sdk sudo "/Volumes/vulkan-sdk/InstallVulkan.app/Contents/MacOS/InstallVulkan" --root $VULKAN_SDK_ROOT --accept-licenses --default-answer --confirm-command install export VULKAN_SDK=$VULKAN_SDK_ROOT/macOS From 84c65b92d000d1ec77950180854380c35e9705f1 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Tue, 10 Dec 2024 15:18:48 +0100 Subject: [PATCH 12/69] Revert macos change and use older Vulkan SDK that uses proper `dmg` image for mac --- .github/actions/vulkan/action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/vulkan/action.yml b/.github/actions/vulkan/action.yml index de271675a..4ab4adb59 100644 --- a/.github/actions/vulkan/action.yml +++ b/.github/actions/vulkan/action.yml @@ -3,7 +3,7 @@ description: Downloads and installs Vulkan SDK. inputs: vulkan-version: description: 'Vulkan SDK release version (e.g. 1.2.198.1).' - default: '1.3.296.0' + default: '1.3.290.0' required: false runs: using: "composite" @@ -24,7 +24,7 @@ runs: ;; Darwin) export VULKAN_SDK_ROOT=`pwd`/../VulkanSDK - curl -L -o vulkan-sdk.dmg "https://sdk.lunarg.com/sdk/download/$VULKAN_SDK_VER/mac/vulkan-sdk.dmg" + curl -LO "https://sdk.lunarg.com/sdk/download/$VULKAN_SDK_VER/mac/vulkan-sdk.dmg" hdiutil attach vulkan-sdk.dmg -mountpoint /Volumes/vulkan-sdk sudo "/Volumes/vulkan-sdk/InstallVulkan.app/Contents/MacOS/InstallVulkan" --root $VULKAN_SDK_ROOT --accept-licenses --default-answer --confirm-command install export VULKAN_SDK=$VULKAN_SDK_ROOT/macOS From 04a3435200b9c6c52cbd48953a1de607d3bda042 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Tue, 10 Dec 2024 16:45:59 +0100 Subject: [PATCH 13/69] Fix shaders parsing to skip comments in between special macros --- .../Parser/ShaderProcessing.cpp | 36 ++----------------- Source/Engine/Utilities/TextProcessing.cpp | 35 ++++++++++++++++++ Source/Engine/Utilities/TextProcessing.h | 20 +++++------ 3 files changed, 47 insertions(+), 44 deletions(-) diff --git a/Source/Engine/ShadersCompilation/Parser/ShaderProcessing.cpp b/Source/Engine/ShadersCompilation/Parser/ShaderProcessing.cpp index fea60c8e7..e65961038 100644 --- a/Source/Engine/ShadersCompilation/Parser/ShaderProcessing.cpp +++ b/Source/Engine/ShadersCompilation/Parser/ShaderProcessing.cpp @@ -66,10 +66,6 @@ void ShaderProcessing::Parser::init() bool ShaderProcessing::Parser::process() { const Token defineToken("#define"); - const Separator singleLineCommentSeparator('/', '/'); - const Separator multiLineCommentSeparator('/', '*'); - - // TODO: split parsing into two phrases: comments preprocessing and parsing // Read whole source code Token token; @@ -77,36 +73,8 @@ bool ShaderProcessing::Parser::process() { text.ReadToken(&token); - // Single line comment - if (token.Separator == singleLineCommentSeparator) - { - // Read whole line - text.ReadLine(); - } - // Multi line comment - else if (token.Separator == multiLineCommentSeparator) - { - // Read tokens until end sequence - char prev = ' '; - char c; - while (text.CanRead()) - { - c = text.ReadChar(); - if (prev == '*' && c == '/') - { - break; - } - prev = c; - } - - // Check if comment is valid (has end before file end) - if (!text.CanRead()) - { - OnWarning(TEXT("Missing multiline comment ending")); - } - } - // Preprocessor definition - else if (token == defineToken) + // Preprocessor definition + if (token == defineToken) { // Skip text.ReadLine(); diff --git a/Source/Engine/Utilities/TextProcessing.cpp b/Source/Engine/Utilities/TextProcessing.cpp index fb971559d..50faeb262 100644 --- a/Source/Engine/Utilities/TextProcessing.cpp +++ b/Source/Engine/Utilities/TextProcessing.cpp @@ -1,6 +1,7 @@ // Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. #include "TextProcessing.h" +#include "Engine/Core/Log.h" TextProcessing::TextProcessing(const char* input, int32 length) : _buffer(input) @@ -54,6 +55,8 @@ void TextProcessing::Setup_HLSL() 32, }; Whitespaces.Set(whitespaces, ARRAY_COUNT(whitespaces)); + SingleLineComment = SeparatorData('/', '/'); + MultiLineCommentSeparator = SeparatorData('/', '*'); } char TextProcessing::ReadChar() @@ -123,6 +126,38 @@ void TextProcessing::ReadToken(Token* token) token->Separator = Separators[s]; ReadChar(); + + // Check for comments + if (token->Separator == SingleLineComment) + { + // Read whole line + ReadLine(); + + // Read another token + ReadToken(token); + } + else if (token->Separator == MultiLineCommentSeparator) + { + // Read tokens until end sequence + char prev = ' '; + while (CanRead()) + { + c = ReadChar(); + if (prev == '*' && c == '/') + break; + prev = c; + } + + // Check if comment is valid (has end before file end) + if (!CanRead()) + { + LOG(Warning, "Missing multiline comment ending"); + } + + // Read another token + ReadToken(token); + } + return; } } diff --git a/Source/Engine/Utilities/TextProcessing.h b/Source/Engine/Utilities/TextProcessing.h index d26f52814..fa804a132 100644 --- a/Source/Engine/Utilities/TextProcessing.h +++ b/Source/Engine/Utilities/TextProcessing.h @@ -9,13 +9,13 @@ #include "Engine/Platform/StringUtils.h" /// -/// Helper class to fast ANSI text processing (tokenization, reading, streaming etc.) +/// Helper class to fast ANSI text processing (tokenization, reading, streaming etc.). /// class FLAXENGINE_API TextProcessing : public NonCopyable { public: /// - /// Separator structure + /// Separator structure. /// struct SeparatorData { @@ -200,18 +200,21 @@ public: public: /// - /// Array with all token separators + /// Array with all token separators. /// Array Separators; /// /// - /// Array with all white characters + /// Array with all white characters. /// Array Whitespaces; + SeparatorData SingleLineComment; + SeparatorData MultiLineCommentSeparator; + public: /// - /// Set separators and white chars for HLSL language + /// Sets up separators and white chars for HLSL language. /// void Setup_HLSL(); @@ -219,25 +222,22 @@ public: /// /// Returns true if there are still characters in the buffer and can read data from it /// - /// True if can read data, otherwise false FORCE_INLINE bool CanRead() const { return _position < _length; } /// - /// Peeks single character without moving forward in the buffer + /// Peeks a single character without moving forward in the buffer. /// - /// First character FORCE_INLINE char PeekChar() const { return *_cursor; } /// - /// Gets current line number + /// Gets the current line number. /// - /// Current line number FORCE_INLINE int32 GetLine() const { return _line; From 139a43161404c4bf6b2f5e636ea8265ba8ed8170 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Tue, 10 Dec 2024 17:01:41 +0100 Subject: [PATCH 14/69] Fix crash due to alive reference to old asset validator #3081 --- Source/Editor/Content/AssetPickerValidator.cs | 1 - .../Editor/CustomEditors/Editors/AssetRefEditor.cs | 12 ++++++++++++ .../Editor/CustomEditors/Editors/CollectionEditor.cs | 4 ++++ Source/Editor/GUI/AssetPicker.cs | 2 +- 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/Source/Editor/Content/AssetPickerValidator.cs b/Source/Editor/Content/AssetPickerValidator.cs index 109ea2f79..349d43cf4 100644 --- a/Source/Editor/Content/AssetPickerValidator.cs +++ b/Source/Editor/Content/AssetPickerValidator.cs @@ -1,7 +1,6 @@ // Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. using System; -using System.IO; using FlaxEditor.Scripting; using FlaxEngine; using FlaxEngine.Utilities; diff --git a/Source/Editor/CustomEditors/Editors/AssetRefEditor.cs b/Source/Editor/CustomEditors/Editors/AssetRefEditor.cs index 76f0e12cd..83fa1f129 100644 --- a/Source/Editor/CustomEditors/Editors/AssetRefEditor.cs +++ b/Source/Editor/CustomEditors/Editors/AssetRefEditor.cs @@ -292,5 +292,17 @@ namespace FlaxEditor.CustomEditors.Editors _isRefreshing = false; } } + + /// + protected override void Deinitialize() + { + if (_validator != null) + { + _validator.OnDestroy(); + _validator = null; + } + + base.Deinitialize(); + } } } diff --git a/Source/Editor/CustomEditors/Editors/CollectionEditor.cs b/Source/Editor/CustomEditors/Editors/CollectionEditor.cs index 1f06b2704..5497d085f 100644 --- a/Source/Editor/CustomEditors/Editors/CollectionEditor.cs +++ b/Source/Editor/CustomEditors/Editors/CollectionEditor.cs @@ -898,9 +898,13 @@ namespace FlaxEditor.CustomEditors.Editors base.Draw(); } + /// public override void OnDestroy() { _pickerValidator.OnDestroy(); + _pickerValidator = null; + + base.OnDestroy(); } private bool ValidateActors(ActorNode node) diff --git a/Source/Editor/GUI/AssetPicker.cs b/Source/Editor/GUI/AssetPicker.cs index c1ef7c362..7aca96c4e 100644 --- a/Source/Editor/GUI/AssetPicker.cs +++ b/Source/Editor/GUI/AssetPicker.cs @@ -59,7 +59,7 @@ namespace FlaxEditor.GUI /// /// Initializes a new instance of the class. /// - /// The assets types that this picker accepts. + /// The asset types that this picker accepts. /// The control location. public AssetPicker(ScriptType assetType, Float2 location) : base(location, new Float2(DefaultIconSize + ButtonsOffset + ButtonsSize, DefaultIconSize)) From 24266b64da611e8c6f429a628d1d3f42fbe82656 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Wed, 11 Dec 2024 14:24:06 +0100 Subject: [PATCH 15/69] Fix Continuous Deployment --- Source/ThirdParty/rapidjson/reader.h | 2 +- Source/Tools/Flax.Build/Deploy/Deployer.cs | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Source/ThirdParty/rapidjson/reader.h b/Source/ThirdParty/rapidjson/reader.h index a61a94ec5..84dcf5b5c 100644 --- a/Source/ThirdParty/rapidjson/reader.h +++ b/Source/ThirdParty/rapidjson/reader.h @@ -1189,7 +1189,7 @@ private: d = NAN; } else if (RAPIDJSON_LIKELY(Consume(s, 'I') && Consume(s, 'n') && Consume(s, 'f'))) { - d = (minus ? -INFINITY : INFINITY); + d = (double)(minus ? -INFINITY : INFINITY); if (RAPIDJSON_UNLIKELY(s.Peek() == 'i' && !(Consume(s, 'i') && Consume(s, 'n') && Consume(s, 'i') && Consume(s, 't') && Consume(s, 'y')))) RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell()); diff --git a/Source/Tools/Flax.Build/Deploy/Deployer.cs b/Source/Tools/Flax.Build/Deploy/Deployer.cs index c9809a97d..6b68a41c4 100644 --- a/Source/Tools/Flax.Build/Deploy/Deployer.cs +++ b/Source/Tools/Flax.Build/Deploy/Deployer.cs @@ -1,5 +1,7 @@ // Copyright (c) 2012-2024 Flax Engine. All rights reserved. +#define USE_STD + using System; using System.IO; using System.Text; @@ -99,6 +101,9 @@ namespace Flax.Deploy Log.Info("Compressing game debug symbols files..."); var gamePackageZipPath = Path.Combine(Deployer.PackageOutputPath, "GameDebugSymbols.zip"); Utilities.FileDelete(gamePackageZipPath); +#if USE_STD + System.IO.Compression.ZipFile.CreateFromDirectory(Path.Combine(Deployer.PackageOutputPath, "GameDebugSymbols"), gamePackageZipPath, System.IO.Compression.CompressionLevel.Optimal, false); +#else using (var zip = new Ionic.Zip.ZipFile()) { zip.AddDirectory(Path.Combine(Deployer.PackageOutputPath, "GameDebugSymbols")); @@ -106,6 +111,7 @@ namespace Flax.Deploy zip.Comment = string.Format("Flax Game {0}.{1}.{2}\nDate: {3}", Deployer.VersionMajor, Deployer.VersionMinor, Deployer.VersionBuild, DateTime.UtcNow); zip.Save(gamePackageZipPath); } +#endif Log.Info("Compressed game debug symbols package size: " + Utilities.GetFileSize(gamePackageZipPath)); } Utilities.DirectoryDelete(Path.Combine(Deployer.PackageOutputPath, "GameDebugSymbols")); From 4a2f4a98ec5605562a82f5a3f2cbb75c1f242ac8 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Wed, 11 Dec 2024 14:42:13 +0100 Subject: [PATCH 16/69] Revert unwanted change from 24266b64da611e8c6f429a628d1d3f42fbe82656 --- Source/ThirdParty/rapidjson/reader.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/ThirdParty/rapidjson/reader.h b/Source/ThirdParty/rapidjson/reader.h index 84dcf5b5c..a61a94ec5 100644 --- a/Source/ThirdParty/rapidjson/reader.h +++ b/Source/ThirdParty/rapidjson/reader.h @@ -1189,7 +1189,7 @@ private: d = NAN; } else if (RAPIDJSON_LIKELY(Consume(s, 'I') && Consume(s, 'n') && Consume(s, 'f'))) { - d = (double)(minus ? -INFINITY : INFINITY); + d = (minus ? -INFINITY : INFINITY); if (RAPIDJSON_UNLIKELY(s.Peek() == 'i' && !(Consume(s, 'i') && Consume(s, 'n') && Consume(s, 'i') && Consume(s, 't') && Consume(s, 'y')))) RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell()); From 1e61abdfefff2154be63e0ffc2e1b2f36603ff64 Mon Sep 17 00:00:00 2001 From: xxSeys1 Date: Wed, 11 Dec 2024 17:11:00 +0100 Subject: [PATCH 17/69] add highlight when actor reference is single clicked --- .../Editors/FlaxObjectRefEditor.cs | 24 ++++++++ Source/Editor/GUI/Tree/TreeNode.cs | 60 +++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/Source/Editor/CustomEditors/Editors/FlaxObjectRefEditor.cs b/Source/Editor/CustomEditors/Editors/FlaxObjectRefEditor.cs index fd367d21f..18953e88f 100644 --- a/Source/Editor/CustomEditors/Editors/FlaxObjectRefEditor.cs +++ b/Source/Editor/CustomEditors/Editors/FlaxObjectRefEditor.cs @@ -7,6 +7,7 @@ using FlaxEditor.CustomEditors.Elements; using FlaxEditor.GUI; using FlaxEditor.GUI.Drag; using FlaxEditor.SceneGraph; +using FlaxEditor.SceneGraph.GUI; using FlaxEditor.Scripting; using FlaxEngine; using FlaxEngine.GUI; @@ -300,7 +301,30 @@ namespace FlaxEditor.CustomEditors.Editors // Picker dropdown menu if (_supportsPickDropDown && (isSelected ? button2Rect : button1Rect).Contains(ref location)) + { ShowDropDownMenu(); + return true; + } + + if (button == MouseButton.Left) + { + + _isMouseDown = false; + + if (Value is Actor a && !_hasValidDragOver) + { + ActorTreeNode treeNode = Editor.Instance.Scene.GetActorNode(a).TreeNode; + treeNode.ExpandAllParents(); + Editor.Instance.Windows.SceneWin.SceneTreePanel.ScrollViewTo(treeNode, true); + treeNode.StartHighlight(); + return true; + } + + if (Value is Script s && !IsDragOver && !_hasValidDragOver) + { + // TODO: Highlight scripts when Value is a script + } + } return base.OnMouseUp(location, button); } diff --git a/Source/Editor/GUI/Tree/TreeNode.cs b/Source/Editor/GUI/Tree/TreeNode.cs index 9bb9d2038..7059266c4 100644 --- a/Source/Editor/GUI/Tree/TreeNode.cs +++ b/Source/Editor/GUI/Tree/TreeNode.cs @@ -23,10 +23,17 @@ namespace FlaxEditor.GUI.Tree /// public const float DefaultNodeOffsetY = 0; + private const float _targetHighlightScale = 1.25f; + private const float _highlightScaleAnimDuration = 0.85f; + private Tree _tree; private bool _opened, _canChangeOrder; private float _animationProgress, _cachedHeight; + private bool _isHightlighted; + private float _targetHighlightTimeSec; + private float _currentHighlightTimeSec; + private float _highlightScale; private bool _mouseOverArrow, _mouseOverHeader; private float _xOffset, _textWidth; private float _headerHeight = 16.0f; @@ -605,9 +612,44 @@ namespace FlaxEditor.GUI.Tree } } + /// + /// Adds a box around the text to highlight the node. + /// + /// The duration of the highlight in seconds. + public void StartHighlight(float durationSec = 3) + { + _isHightlighted = true; + _targetHighlightTimeSec = durationSec; + _currentHighlightTimeSec = 0; + _highlightScale = 2f; + } + + /// + /// Stops any current highlight. + /// + public void StopHighlight() + { + _isHightlighted = false; + _targetHighlightTimeSec = 0; + _currentHighlightTimeSec = 0; + } + /// public override void Update(float deltaTime) { + // Highlight animations + if (_isHightlighted) + { + _currentHighlightTimeSec += deltaTime; + + // In the first second, animate the highlight to shrink into it's resting position + if (_currentHighlightTimeSec < _highlightScaleAnimDuration) + _highlightScale = Mathf.Lerp(_highlightScale, _targetHighlightScale, _currentHighlightTimeSec); + + if (_currentHighlightTimeSec >= _targetHighlightTimeSec) + _isHightlighted = false; + } + // Drop/down animation if (_animationProgress < 1.0f) { @@ -676,6 +718,18 @@ namespace FlaxEditor.GUI.Tree textRect.Width -= 18.0f; } + float textWidth = TextFont.GetFont().MeasureText(_text).X; + Rectangle trueTextRect = textRect; + trueTextRect.Width = textWidth; + trueTextRect.Scale(_highlightScale); + + if (_isHightlighted) + { + Color highlightBackgroundColor = Editor.Instance.Options.Options.Visual.HighlightColor; + highlightBackgroundColor = highlightBackgroundColor.AlphaMultiplied(0.3f); + Render2D.FillRectangle(trueTextRect, highlightBackgroundColor); + } + // Draw text Color textColor = CacheTextColor(); Render2D.DrawText(TextFont.GetFont(), _text, textRect, textColor, TextAlignment.Near, TextAlignment.Center); @@ -730,6 +784,12 @@ namespace FlaxEditor.GUI.Tree } } + if (_isHightlighted) + { + // Draw highlights + Render2D.DrawRectangle(trueTextRect, Editor.Instance.Options.Options.Visual.HighlightColor, 3); + } + // Base if (_opened) { From 99e836b1fb6a2349c4e4f568d77baa9a9e305af5 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Wed, 11 Dec 2024 20:43:52 -0600 Subject: [PATCH 18/69] Fix valid drop not resetting, add debounce timer to highlighting for showing on double click prevention --- .../Editors/FlaxObjectRefEditor.cs | 46 ++++++++++++++++--- Source/Editor/GUI/Tree/TreeNode.cs | 9 +++- 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/Source/Editor/CustomEditors/Editors/FlaxObjectRefEditor.cs b/Source/Editor/CustomEditors/Editors/FlaxObjectRefEditor.cs index 18953e88f..908aba278 100644 --- a/Source/Editor/CustomEditors/Editors/FlaxObjectRefEditor.cs +++ b/Source/Editor/CustomEditors/Editors/FlaxObjectRefEditor.cs @@ -24,6 +24,7 @@ namespace FlaxEditor.CustomEditors.Editors public class FlaxObjectRefPickerControl : Control { private ScriptType _type; + private ActorTreeNode _linkedTreeNode; private Object _value; private string _valueName; private bool _supportsPickDropDown; @@ -308,22 +309,50 @@ namespace FlaxEditor.CustomEditors.Editors if (button == MouseButton.Left) { - _isMouseDown = false; - + // Highlight actor reference. if (Value is Actor a && !_hasValidDragOver) { - ActorTreeNode treeNode = Editor.Instance.Scene.GetActorNode(a).TreeNode; - treeNode.ExpandAllParents(); - Editor.Instance.Windows.SceneWin.SceneTreePanel.ScrollViewTo(treeNode, true); - treeNode.StartHighlight(); + if (_linkedTreeNode != null && _linkedTreeNode.Actor == a) + { + _linkedTreeNode.ExpandAllParents(); + _linkedTreeNode.StartHighlight(); + } + else + { + _linkedTreeNode = Editor.Instance.Scene.GetActorNode(a).TreeNode; + _linkedTreeNode.ExpandAllParents(); + Editor.Instance.Windows.SceneWin.SceneTreePanel.ScrollViewTo(_linkedTreeNode, true); + _linkedTreeNode.StartHighlight(); + } return true; } + // Highlight actor with script reference. if (Value is Script s && !IsDragOver && !_hasValidDragOver) { - // TODO: Highlight scripts when Value is a script + var scriptActor = s.Actor; + if (scriptActor != null) + { + if (_linkedTreeNode != null && _linkedTreeNode.Actor == scriptActor) + { + _linkedTreeNode.ExpandAllParents(); + _linkedTreeNode.StartHighlight(); + } + else + { + _linkedTreeNode = Editor.Instance.Scene.GetActorNode(scriptActor).TreeNode; + _linkedTreeNode.ExpandAllParents(); + Editor.Instance.Windows.SceneWin.SceneTreePanel.ScrollViewTo(_linkedTreeNode, true); + _linkedTreeNode.StartHighlight(); + } + return true; + } } + + // Reset valid drag over if still true at this point. + if (_hasValidDragOver) + _hasValidDragOver = false; } return base.OnMouseUp(location, button); @@ -350,6 +379,8 @@ namespace FlaxEditor.CustomEditors.Editors // Check if has object selected if (_value != null) { + if (_linkedTreeNode != null) + _linkedTreeNode.StopHighlight(); // Select object if (_value is Actor actor) Editor.Instance.SceneEditing.Select(actor); @@ -493,6 +524,7 @@ namespace FlaxEditor.CustomEditors.Editors _value = null; _type = ScriptType.Null; _valueName = null; + _linkedTreeNode = null; base.OnDestroy(); } diff --git a/Source/Editor/GUI/Tree/TreeNode.cs b/Source/Editor/GUI/Tree/TreeNode.cs index 7059266c4..90639cebc 100644 --- a/Source/Editor/GUI/Tree/TreeNode.cs +++ b/Source/Editor/GUI/Tree/TreeNode.cs @@ -33,6 +33,8 @@ namespace FlaxEditor.GUI.Tree private bool _isHightlighted; private float _targetHighlightTimeSec; private float _currentHighlightTimeSec; + // Used to prevent showing highlight on double mouse click + private float _debounceHighlightTime; private float _highlightScale; private bool _mouseOverArrow, _mouseOverHeader; private float _xOffset, _textWidth; @@ -621,6 +623,7 @@ namespace FlaxEditor.GUI.Tree _isHightlighted = true; _targetHighlightTimeSec = durationSec; _currentHighlightTimeSec = 0; + _debounceHighlightTime = 0; _highlightScale = 2f; } @@ -632,6 +635,7 @@ namespace FlaxEditor.GUI.Tree _isHightlighted = false; _targetHighlightTimeSec = 0; _currentHighlightTimeSec = 0; + _debounceHighlightTime = 0; } /// @@ -640,6 +644,7 @@ namespace FlaxEditor.GUI.Tree // Highlight animations if (_isHightlighted) { + _debounceHighlightTime += deltaTime; _currentHighlightTimeSec += deltaTime; // In the first second, animate the highlight to shrink into it's resting position @@ -723,7 +728,7 @@ namespace FlaxEditor.GUI.Tree trueTextRect.Width = textWidth; trueTextRect.Scale(_highlightScale); - if (_isHightlighted) + if (_isHightlighted && _debounceHighlightTime > 0.1f) { Color highlightBackgroundColor = Editor.Instance.Options.Options.Visual.HighlightColor; highlightBackgroundColor = highlightBackgroundColor.AlphaMultiplied(0.3f); @@ -784,7 +789,7 @@ namespace FlaxEditor.GUI.Tree } } - if (_isHightlighted) + if (_isHightlighted && _debounceHighlightTime > 0.1f) { // Draw highlights Render2D.DrawRectangle(trueTextRect, Editor.Instance.Options.Options.Visual.HighlightColor, 3); From 0906a561c408655666b60a001caf5b7880eec96c Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Wed, 11 Dec 2024 20:55:49 -0600 Subject: [PATCH 19/69] Show game window if hidden when start play. --- Source/Editor/Modules/SimulationModule.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Source/Editor/Modules/SimulationModule.cs b/Source/Editor/Modules/SimulationModule.cs index bb9df0950..3906fe424 100644 --- a/Source/Editor/Modules/SimulationModule.cs +++ b/Source/Editor/Modules/SimulationModule.cs @@ -99,6 +99,10 @@ namespace FlaxEditor.Modules { if (Editor.StateMachine.IsEditMode) { + // Show Game window if hidden + if (Editor.Windows.GameWin.IsHidden) + Editor.Windows.GameWin.Show(); + Editor.Log("[PlayMode] Start"); if (Editor.Options.Options.General.AutoReloadScriptsOnMainWindowFocus) @@ -131,6 +135,10 @@ namespace FlaxEditor.Modules if (!Editor.StateMachine.IsEditMode) return; + // Show Game window if hidden + if (Editor.Windows.GameWin.IsHidden) + Editor.Windows.GameWin.Show(); + var firstScene = Content.Settings.GameSettings.Load().FirstScene; if (firstScene == Guid.Empty) { From 76b84cca4e2b972c3594c2582a47e8f9c0f9853b Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Thu, 12 Dec 2024 10:40:08 -0600 Subject: [PATCH 20/69] Scroll to script on add. --- Source/Editor/CustomEditors/Dedicated/ScriptsEditor.cs | 7 +++++++ Source/Editor/Options/InterfaceOptions.cs | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/Source/Editor/CustomEditors/Dedicated/ScriptsEditor.cs b/Source/Editor/CustomEditors/Dedicated/ScriptsEditor.cs index e71f9a8bc..583241915 100644 --- a/Source/Editor/CustomEditors/Dedicated/ScriptsEditor.cs +++ b/Source/Editor/CustomEditors/Dedicated/ScriptsEditor.cs @@ -424,6 +424,13 @@ namespace FlaxEditor.CustomEditors.Dedicated { presenter.Undo.AddAction(multiAction); presenter.Control.Focus(); + + // Scroll to bottom of script control where a new script is added. + if (presenter.Panel.Parent is Panel p && Editor.Instance.Options.Options.Interface.ScrollToScriptOnAdd) + { + var loc = ScriptsEditor.Layout.Control.BottomLeft; + p.ScrollViewTo(loc); + } } } } diff --git a/Source/Editor/Options/InterfaceOptions.cs b/Source/Editor/Options/InterfaceOptions.cs index 1654df920..4cd76adc6 100644 --- a/Source/Editor/Options/InterfaceOptions.cs +++ b/Source/Editor/Options/InterfaceOptions.cs @@ -258,6 +258,13 @@ namespace FlaxEditor.Options private TextAlignment _tooltipTextAlignment = TextAlignment.Center; + /// + /// Whether to scroll to the script when a script is added to an actor. + /// + [DefaultValue(true)] + [EditorDisplay("Interface"), EditorOrder(322)] + public bool ScrollToScriptOnAdd { get; set; } = true; + /// /// Gets or sets the timestamps prefix mode for output log messages. /// From a0216746b9909fd3ec14b48e0e18e6e940989fbd Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Thu, 12 Dec 2024 11:04:28 -0600 Subject: [PATCH 21/69] Add value null check in `UiControlEditor` to fix exception --- Source/Editor/CustomEditors/Dedicated/UIControlEditor.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Source/Editor/CustomEditors/Dedicated/UIControlEditor.cs b/Source/Editor/CustomEditors/Dedicated/UIControlEditor.cs index c3330330d..8be473bcb 100644 --- a/Source/Editor/CustomEditors/Dedicated/UIControlEditor.cs +++ b/Source/Editor/CustomEditors/Dedicated/UIControlEditor.cs @@ -723,10 +723,13 @@ namespace FlaxEditor.CustomEditors.Dedicated } // Refresh anchors - GetAnchorEquality(out bool xEq, out bool yEq, ValuesTypes); - if (xEq != _cachedXEq || yEq != _cachedYEq) + if (Values != null && Values[0] != null) { - RebuildLayout(); + GetAnchorEquality(out bool xEq, out bool yEq, ValuesTypes); + if (xEq != _cachedXEq || yEq != _cachedYEq) + { + RebuildLayout(); + } } base.Refresh(); From 7e0c0559ddf241660d4601f4a6ef117dbcf65522 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Thu, 12 Dec 2024 11:53:12 -0600 Subject: [PATCH 22/69] Add the ability to ignore specific warnings during build. --- .../Flax.Build/Build/DotNet/Builder.DotNet.cs | 7 +++++++ .../Flax.Build/Build/NativeCpp/BuildOptions.cs | 7 +++++++ .../Projects/VisualStudio/CSProjectGenerator.cs | 14 ++++++++++++++ .../Projects/VisualStudio/CSSDKProjectGenerator.cs | 7 +++++++ 4 files changed, 35 insertions(+) diff --git a/Source/Tools/Flax.Build/Build/DotNet/Builder.DotNet.cs b/Source/Tools/Flax.Build/Build/DotNet/Builder.DotNet.cs index fb1f84323..f4ae09a1a 100644 --- a/Source/Tools/Flax.Build/Build/DotNet/Builder.DotNet.cs +++ b/Source/Tools/Flax.Build/Build/DotNet/Builder.DotNet.cs @@ -256,6 +256,13 @@ namespace Flax.Build #endif if (buildOptions.ScriptingAPI.IgnoreMissingDocumentationWarnings) args.Add("-nowarn:1591"); + if (buildOptions.ScriptingAPI.IgnoreSpecificWarnings.Any()) + { + foreach (var warningString in buildOptions.ScriptingAPI.IgnoreSpecificWarnings) + { + args.Add($"-nowarn:{warningString}"); + } + } // Optimizations prevent debugging, only enable in release builds by default var optimize = optimizeAssembly.HasValue ? optimizeAssembly.Value : buildData.Configuration == TargetConfiguration.Release; diff --git a/Source/Tools/Flax.Build/Build/NativeCpp/BuildOptions.cs b/Source/Tools/Flax.Build/Build/NativeCpp/BuildOptions.cs index fb94131a1..6f693a03b 100644 --- a/Source/Tools/Flax.Build/Build/NativeCpp/BuildOptions.cs +++ b/Source/Tools/Flax.Build/Build/NativeCpp/BuildOptions.cs @@ -235,6 +235,11 @@ namespace Flax.Build.NativeCpp /// public HashSet Analyzers; + /// + /// The specific .NET warning to ignore. + /// + public HashSet IgnoreSpecificWarnings; + /// /// True if ignore compilation warnings due to missing code documentation comments. /// @@ -265,6 +270,7 @@ namespace Flax.Build.NativeCpp FileReferences.AddRange(other.FileReferences); Analyzers.AddRange(other.Analyzers); IgnoreMissingDocumentationWarnings |= other.IgnoreMissingDocumentationWarnings; + IgnoreSpecificWarnings.AddRange(other.IgnoreSpecificWarnings); } } @@ -338,6 +344,7 @@ namespace Flax.Build.NativeCpp }, FileReferences = new HashSet(), Analyzers = new HashSet(), + IgnoreSpecificWarnings = new HashSet(), }; /// diff --git a/Source/Tools/Flax.Build/Projects/VisualStudio/CSProjectGenerator.cs b/Source/Tools/Flax.Build/Projects/VisualStudio/CSProjectGenerator.cs index a83a5a7f6..c5359f66e 100644 --- a/Source/Tools/Flax.Build/Projects/VisualStudio/CSProjectGenerator.cs +++ b/Source/Tools/Flax.Build/Projects/VisualStudio/CSProjectGenerator.cs @@ -125,6 +125,13 @@ namespace Flax.Build.Projects.VisualStudio csProjectFileContent.AppendLine(" true"); if (configuration.TargetBuildOptions.ScriptingAPI.IgnoreMissingDocumentationWarnings) csProjectFileContent.AppendLine(" 1591"); + if (configuration.TargetBuildOptions.ScriptingAPI.IgnoreSpecificWarnings.Any()) + { + foreach (var warningString in configuration.TargetBuildOptions.ScriptingAPI.IgnoreSpecificWarnings) + { + csProjectFileContent.AppendLine($" {warningString}"); + } + } csProjectFileContent.AppendLine(string.Format(" {0}\\{1}.CSharp.xml", outputPath, project.BaseName)); csProjectFileContent.AppendLine(" true"); csProjectFileContent.AppendLine(" "); @@ -156,6 +163,13 @@ namespace Flax.Build.Projects.VisualStudio csProjectFileContent.AppendLine(" true"); if (configuration.TargetBuildOptions.ScriptingAPI.IgnoreMissingDocumentationWarnings) csProjectFileContent.AppendLine(" 1591"); + if (configuration.TargetBuildOptions.ScriptingAPI.IgnoreSpecificWarnings.Any()) + { + foreach (var warningString in configuration.TargetBuildOptions.ScriptingAPI.IgnoreSpecificWarnings) + { + csProjectFileContent.AppendLine($" {warningString}"); + } + } csProjectFileContent.AppendLine(string.Format(" {0}\\{1}.CSharp.xml", outputPath, project.BaseName)); csProjectFileContent.AppendLine(" true"); csProjectFileContent.AppendLine(" "); diff --git a/Source/Tools/Flax.Build/Projects/VisualStudio/CSSDKProjectGenerator.cs b/Source/Tools/Flax.Build/Projects/VisualStudio/CSSDKProjectGenerator.cs index 64c333499..9059cda94 100644 --- a/Source/Tools/Flax.Build/Projects/VisualStudio/CSSDKProjectGenerator.cs +++ b/Source/Tools/Flax.Build/Projects/VisualStudio/CSSDKProjectGenerator.cs @@ -284,6 +284,13 @@ namespace Flax.Build.Projects.VisualStudio csProjectFileContent.AppendLine(" true"); if (configuration.TargetBuildOptions.ScriptingAPI.IgnoreMissingDocumentationWarnings) csProjectFileContent.AppendLine(" 1591"); + if (configuration.TargetBuildOptions.ScriptingAPI.IgnoreSpecificWarnings.Any()) + { + foreach (var warningString in configuration.TargetBuildOptions.ScriptingAPI.IgnoreSpecificWarnings) + { + csProjectFileContent.AppendLine($" {warningString}"); + } + } csProjectFileContent.AppendLine(string.Format(" {0}\\{1}.CSharp.xml", outputPath, project.BaseName)); csProjectFileContent.AppendLine(" true"); From 696b1c0d0c13e580da81f9ad4c11877bdf6817c3 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Thu, 12 Dec 2024 11:57:29 -0600 Subject: [PATCH 23/69] Fix comment. --- Source/Tools/Flax.Build/Build/NativeCpp/BuildOptions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Tools/Flax.Build/Build/NativeCpp/BuildOptions.cs b/Source/Tools/Flax.Build/Build/NativeCpp/BuildOptions.cs index 6f693a03b..19e04236e 100644 --- a/Source/Tools/Flax.Build/Build/NativeCpp/BuildOptions.cs +++ b/Source/Tools/Flax.Build/Build/NativeCpp/BuildOptions.cs @@ -236,7 +236,7 @@ namespace Flax.Build.NativeCpp public HashSet Analyzers; /// - /// The specific .NET warning to ignore. + /// The specific warnings to ignore. /// public HashSet IgnoreSpecificWarnings; From 21d1419e7444457a11932c52c90f8b7c9ad9c19d Mon Sep 17 00:00:00 2001 From: Gary M Date: Thu, 12 Dec 2024 22:19:55 -0800 Subject: [PATCH 24/69] Added import option to reverse winding order --- .../Tools/ModelTool/ModelTool.Assimp.cpp | 4 ++++ .../ModelTool/ModelTool.AutodeskFbxSdk.cpp | 13 +++++++++++++ .../Tools/ModelTool/ModelTool.OpenFBX.cpp | 18 ++++++++++++++++++ Source/Engine/Tools/ModelTool/ModelTool.cpp | 2 ++ Source/Engine/Tools/ModelTool/ModelTool.h | 3 +++ 5 files changed, 40 insertions(+) diff --git a/Source/Engine/Tools/ModelTool/ModelTool.Assimp.cpp b/Source/Engine/Tools/ModelTool/ModelTool.Assimp.cpp index ff8dc31fe..550793d12 100644 --- a/Source/Engine/Tools/ModelTool/ModelTool.Assimp.cpp +++ b/Source/Engine/Tools/ModelTool/ModelTool.Assimp.cpp @@ -765,6 +765,10 @@ bool ModelTool::ImportDataAssimp(const String& path, ModelData& data, Options& o flags |= aiProcess_FixInfacingNormals | aiProcess_GenSmoothNormals; if (options.CalculateTangents) flags |= aiProcess_CalcTangentSpace; + if (options.ReverseWindingOrder) + // actually we need to remove this flag + // flags |= aiProcess_FlipWindingOrder; + flags &= ~aiProcess_FlipWindingOrder; if (options.OptimizeMeshes) flags |= aiProcess_OptimizeMeshes | aiProcess_SplitLargeMeshes | aiProcess_ImproveCacheLocality; if (options.MergeMeshes) diff --git a/Source/Engine/Tools/ModelTool/ModelTool.AutodeskFbxSdk.cpp b/Source/Engine/Tools/ModelTool/ModelTool.AutodeskFbxSdk.cpp index 1ea6a22ad..7f3dfb355 100644 --- a/Source/Engine/Tools/ModelTool/ModelTool.AutodeskFbxSdk.cpp +++ b/Source/Engine/Tools/ModelTool/ModelTool.AutodeskFbxSdk.cpp @@ -385,6 +385,19 @@ bool ProcessMesh(ImporterData& data, FbxMesh* fbxMesh, MeshData& mesh, String& e mesh.Indices[i] = fbxIndices[i]; } + if (data.Options.ReverseWindingOrder) + { + for (int32 i = 0; i < vertexCount; i += 3) + { + Swap(meshIndices[i + 1], meshIndices[i + 2]); + Swap(meshPositions[i + 1], meshPositions[i + 2]); + if (meshNormals) + Swap(meshNormals[i + 1], meshNormals[i + 2]); + if (meshTangents) + Swap(meshTangents[i + 1], meshTangents[i + 2]); + } + } + // Texture coordinates FbxGeometryElementUV* texcoords = fbxMesh->GetElementUV(0); if (texcoords) diff --git a/Source/Engine/Tools/ModelTool/ModelTool.OpenFBX.cpp b/Source/Engine/Tools/ModelTool/ModelTool.OpenFBX.cpp index dcb0b6c5f..98747086a 100644 --- a/Source/Engine/Tools/ModelTool/ModelTool.OpenFBX.cpp +++ b/Source/Engine/Tools/ModelTool/ModelTool.OpenFBX.cpp @@ -775,6 +775,24 @@ bool ProcessMesh(ModelData& result, OpenFbxImporterData& data, const ofbx::Mesh* } } + // Reverse winding order + if (data.Options.ReverseWindingOrder) + { + uint32* meshIndices = mesh.Indices.Get(); + Float3* meshPositions = mesh.Positions.Get(); + Float3* meshNormals = mesh.Normals.HasItems() ? mesh.Normals.Get() : nullptr; + Float3* meshTangents = mesh.Tangents.HasItems() ? mesh.Tangents.Get() : nullptr; + + for (int i = 0; i < vertexCount; i += 3) { + Swap(meshIndices[i + 1], meshIndices[i + 2]); + Swap(meshPositions[i + 1], meshPositions[i + 2]); + if (meshNormals) + Swap(meshNormals[i + 1], meshNormals[i + 2]); + if (meshTangents) + Swap(meshTangents[i + 1], meshTangents[i + 2]); + } + } + // Lightmap UVs if (data.Options.LightmapUVsSource == ModelLightmapUVsSource::Disable) { diff --git a/Source/Engine/Tools/ModelTool/ModelTool.cpp b/Source/Engine/Tools/ModelTool/ModelTool.cpp index 91c2edc06..fec4ba8f5 100644 --- a/Source/Engine/Tools/ModelTool/ModelTool.cpp +++ b/Source/Engine/Tools/ModelTool/ModelTool.cpp @@ -667,6 +667,7 @@ void ModelTool::Options::Serialize(SerializeStream& stream, const void* otherObj SERIALIZE(FlipNormals); SERIALIZE(CalculateTangents); SERIALIZE(SmoothingTangentsAngle); + SERIALIZE(ReverseWindingOrder); SERIALIZE(OptimizeMeshes); SERIALIZE(MergeMeshes); SERIALIZE(ImportLODs); @@ -717,6 +718,7 @@ void ModelTool::Options::Deserialize(DeserializeStream& stream, ISerializeModifi DESERIALIZE(FlipNormals); DESERIALIZE(CalculateTangents); DESERIALIZE(SmoothingTangentsAngle); + DESERIALIZE(ReverseWindingOrder); DESERIALIZE(OptimizeMeshes); DESERIALIZE(MergeMeshes); DESERIALIZE(ImportLODs); diff --git a/Source/Engine/Tools/ModelTool/ModelTool.h b/Source/Engine/Tools/ModelTool/ModelTool.h index 708b94342..bfd8092e7 100644 --- a/Source/Engine/Tools/ModelTool/ModelTool.h +++ b/Source/Engine/Tools/ModelTool/ModelTool.h @@ -170,6 +170,9 @@ public: // Specifies the maximum angle (in degrees) that may be between two vertex tangents before their tangents and bi-tangents are smoothed. The default value is 45. API_FIELD(Attributes="EditorOrder(45), EditorDisplay(\"Geometry\"), VisibleIf(nameof(ShowSmoothingTangentsAngle)), Limit(0, 45, 0.1f)") float SmoothingTangentsAngle = 45.0f; + // If checked, the winding order of the vertices will be reversed. + API_FIELD(Attributes="EditorOrder(47), EditorDisplay(\"Geometry\"), VisibleIf(nameof(ShowGeometry))") + bool ReverseWindingOrder = false; // Enable/disable meshes geometry optimization. API_FIELD(Attributes="EditorOrder(50), EditorDisplay(\"Geometry\"), VisibleIf(nameof(ShowGeometry))") bool OptimizeMeshes = true; From c6b7077c2d4f29c15872c5044e93d96e06d9f80c Mon Sep 17 00:00:00 2001 From: Gary M Date: Thu, 12 Dec 2024 22:23:21 -0800 Subject: [PATCH 25/69] Remove unnecessary comments --- Source/Engine/Tools/ModelTool/ModelTool.Assimp.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/Source/Engine/Tools/ModelTool/ModelTool.Assimp.cpp b/Source/Engine/Tools/ModelTool/ModelTool.Assimp.cpp index 550793d12..c4f27abf5 100644 --- a/Source/Engine/Tools/ModelTool/ModelTool.Assimp.cpp +++ b/Source/Engine/Tools/ModelTool/ModelTool.Assimp.cpp @@ -766,8 +766,6 @@ bool ModelTool::ImportDataAssimp(const String& path, ModelData& data, Options& o if (options.CalculateTangents) flags |= aiProcess_CalcTangentSpace; if (options.ReverseWindingOrder) - // actually we need to remove this flag - // flags |= aiProcess_FlipWindingOrder; flags &= ~aiProcess_FlipWindingOrder; if (options.OptimizeMeshes) flags |= aiProcess_OptimizeMeshes | aiProcess_SplitLargeMeshes | aiProcess_ImproveCacheLocality; From f57f57423c0aad97e639f7e46b50507242312183 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Fri, 13 Dec 2024 14:31:44 -0600 Subject: [PATCH 26/69] Fix Collection value containers to use correct value assignment. --- Source/Editor/CustomEditors/CustomEditor.cs | 2 +- Source/Editor/CustomEditors/Values/ValueContainer.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Editor/CustomEditors/CustomEditor.cs b/Source/Editor/CustomEditors/CustomEditor.cs index 6b7bd4601..8c3810c3c 100644 --- a/Source/Editor/CustomEditors/CustomEditor.cs +++ b/Source/Editor/CustomEditors/CustomEditor.cs @@ -301,7 +301,7 @@ namespace FlaxEditor.CustomEditors _valueToSet = null; // Assign value - if (val is IList l && l.Count == _values.Count) + if (val is IList l && l.Count == _values.Count && _values.Count > 1) { for (int i = 0; i < _values.Count; i++) _values[i] = l[i]; diff --git a/Source/Editor/CustomEditors/Values/ValueContainer.cs b/Source/Editor/CustomEditors/Values/ValueContainer.cs index 601d20bb9..904d5bc09 100644 --- a/Source/Editor/CustomEditors/Values/ValueContainer.cs +++ b/Source/Editor/CustomEditors/Values/ValueContainer.cs @@ -386,7 +386,7 @@ namespace FlaxEditor.CustomEditors if (instanceValues.Count != Count) throw new ArgumentException(); - if (value is IList l && l.Count == Count) + if (value is IList l && l.Count == Count && Count > 1) { for (int i = 0; i < Count; i++) { From fa8f50ead13f1653c699f230c3aa935b389fa41a Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 16 Dec 2024 22:52:05 +0100 Subject: [PATCH 27/69] Fix crash on incorrect light shadow state after shadowmap resizing failure #3106 --- Source/Engine/Renderer/ShadowsPass.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Source/Engine/Renderer/ShadowsPass.cpp b/Source/Engine/Renderer/ShadowsPass.cpp index 0487d7ce2..f182b9848 100644 --- a/Source/Engine/Renderer/ShadowsPass.cpp +++ b/Source/Engine/Renderer/ShadowsPass.cpp @@ -623,10 +623,6 @@ void ShadowsPass::SetupRenderContext(RenderContext& renderContext, RenderContext void ShadowsPass::SetupLight(ShadowsCustomBuffer& shadows, RenderContext& renderContext, RenderContextBatch& renderContextBatch, RenderLightData& light, ShadowAtlasLight& atlasLight) { - // Initialize frame-data - atlasLight.ContextIndex = 0; - atlasLight.ContextCount = 0; - // Copy light properties atlasLight.Sharpness = light.ShadowsSharpness; atlasLight.Fade = light.ShadowsStrength; @@ -1298,6 +1294,11 @@ RETRY_ATLAS_SETUP: for (RenderLightData* light : shadowedLights) { auto& atlasLight = shadows.Lights[light->ID]; + + // Reset frame-data + atlasLight.ContextIndex = 0; + atlasLight.ContextCount = 0; + if (atlasLight.Tiles[0].RectTile && atlasLight.Tiles[0].RectTile->Width == atlasLight.Resolution) { // Invalidate cache when whole atlas will be cleared From 222a614a2b3f02cb2507f6093fffffa47f64655f Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 16 Dec 2024 23:14:50 +0100 Subject: [PATCH 28/69] Simplify and cleanup code #3096 --- .../Editors/FlaxObjectRefEditor.cs | 37 +++++++------------ 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/Source/Editor/CustomEditors/Editors/FlaxObjectRefEditor.cs b/Source/Editor/CustomEditors/Editors/FlaxObjectRefEditor.cs index 908aba278..386d8d518 100644 --- a/Source/Editor/CustomEditors/Editors/FlaxObjectRefEditor.cs +++ b/Source/Editor/CustomEditors/Editors/FlaxObjectRefEditor.cs @@ -310,38 +310,23 @@ namespace FlaxEditor.CustomEditors.Editors if (button == MouseButton.Left) { _isMouseDown = false; - // Highlight actor reference. - if (Value is Actor a && !_hasValidDragOver) - { - if (_linkedTreeNode != null && _linkedTreeNode.Actor == a) - { - _linkedTreeNode.ExpandAllParents(); - _linkedTreeNode.StartHighlight(); - } - else - { - _linkedTreeNode = Editor.Instance.Scene.GetActorNode(a).TreeNode; - _linkedTreeNode.ExpandAllParents(); - Editor.Instance.Windows.SceneWin.SceneTreePanel.ScrollViewTo(_linkedTreeNode, true); - _linkedTreeNode.StartHighlight(); - } - return true; - } - // Highlight actor with script reference. - if (Value is Script s && !IsDragOver && !_hasValidDragOver) + // Highlight actor or script reference + if (!_hasValidDragOver && !IsDragOver) { - var scriptActor = s.Actor; - if (scriptActor != null) + Actor actor = _value as Actor; + if (actor == null && _value is Script script) + actor = script.Actor; + if (actor != null) { - if (_linkedTreeNode != null && _linkedTreeNode.Actor == scriptActor) + if (_linkedTreeNode != null && _linkedTreeNode.Actor == actor) { _linkedTreeNode.ExpandAllParents(); _linkedTreeNode.StartHighlight(); } else { - _linkedTreeNode = Editor.Instance.Scene.GetActorNode(scriptActor).TreeNode; + _linkedTreeNode = Editor.Instance.Scene.GetActorNode(actor).TreeNode; _linkedTreeNode.ExpandAllParents(); Editor.Instance.Windows.SceneWin.SceneTreePanel.ScrollViewTo(_linkedTreeNode, true); _linkedTreeNode.StartHighlight(); @@ -350,7 +335,7 @@ namespace FlaxEditor.CustomEditors.Editors } } - // Reset valid drag over if still true at this point. + // Reset valid drag over if still true at this point if (_hasValidDragOver) _hasValidDragOver = false; } @@ -380,7 +365,11 @@ namespace FlaxEditor.CustomEditors.Editors if (_value != null) { if (_linkedTreeNode != null) + { _linkedTreeNode.StopHighlight(); + _linkedTreeNode = null; + } + // Select object if (_value is Actor actor) Editor.Instance.SceneEditing.Select(actor); From cedacdba3e2d7a601ce6900db28f00f68941936d Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 16 Dec 2024 23:21:45 +0100 Subject: [PATCH 29/69] Simplify `Rename` context option activity and use input option for F2 remapping in Editor #3093 --- Source/Editor/Surface/SurfaceComment.cs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/Source/Editor/Surface/SurfaceComment.cs b/Source/Editor/Surface/SurfaceComment.cs index ef32b160a..4786252a0 100644 --- a/Source/Editor/Surface/SurfaceComment.cs +++ b/Source/Editor/Surface/SurfaceComment.cs @@ -183,8 +183,9 @@ namespace FlaxEditor.Surface } else { - if (IsSelected && Input.GetKeyDown(KeyboardKeys.F2)) - { + // Rename on F2 + if (IsSelected && Editor.Instance.Options.Options.Input.Rename.Process(this)) + { StartRenaming(); } } @@ -428,12 +429,7 @@ namespace FlaxEditor.Surface base.OnShowSecondaryContextMenu(menu, location); menu.AddSeparator(); - menu.AddButton("Rename", () => - { - if(!_isRenaming) - StartRenaming(); - }); - + menu.AddButton("Rename", StartRenaming); ContextMenuChildMenu cmOrder = menu.AddChildMenu("Order"); { cmOrder.ContextMenu.AddButton("Bring Forward", () => From 622de6ebcbe4450c9c382ca26881ba2baf8bc5b8 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 16 Dec 2024 23:41:55 +0100 Subject: [PATCH 30/69] Minor improvements to new gizmo changes and add new assets #3088 --- Content/Editor/Gizmo/Material.flax | 4 +-- Content/Editor/Gizmo/MaterialAxisFocus.flax | 4 +-- Content/Editor/Gizmo/MaterialAxisLocked.flax | 3 ++ Content/Editor/Gizmo/MaterialAxisX.flax | 4 +-- Content/Editor/Gizmo/MaterialAxisY.flax | 4 +-- Content/Editor/Gizmo/MaterialAxisZ.flax | 4 +-- Content/Editor/Gizmo/MaterialSphere.flax | 4 +-- .../Editor/Gizmo/TransformGizmoBase.Draw.cs | 34 ++++++++++--------- Source/Editor/Options/VisualOptions.cs | 6 ++-- 9 files changed, 36 insertions(+), 31 deletions(-) create mode 100644 Content/Editor/Gizmo/MaterialAxisLocked.flax diff --git a/Content/Editor/Gizmo/Material.flax b/Content/Editor/Gizmo/Material.flax index 87e7c078d..872b529e3 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:ace1f3a9b078208da9a8742e2a7de74b10509abb3dcf12ddc70e4da918bbb756 -size 30756 +oid sha256:af4271107789ee629c6b5f2f0d4d2324a0a8b124043f6dd14f977514c408014b +size 31306 diff --git a/Content/Editor/Gizmo/MaterialAxisFocus.flax b/Content/Editor/Gizmo/MaterialAxisFocus.flax index 56c3f6560..a9de5e7e6 100644 --- a/Content/Editor/Gizmo/MaterialAxisFocus.flax +++ b/Content/Editor/Gizmo/MaterialAxisFocus.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b051fe079aa227c67f861220e35fab93c321d310f737ff663d9b77ef3fe98c3e -size 466 +oid sha256:db7018144f8a2774e1188b6f0ef7edfde3f8cb9c7f11f576163512c02f4c5a54 +size 661 diff --git a/Content/Editor/Gizmo/MaterialAxisLocked.flax b/Content/Editor/Gizmo/MaterialAxisLocked.flax new file mode 100644 index 000000000..be44ece86 --- /dev/null +++ b/Content/Editor/Gizmo/MaterialAxisLocked.flax @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7518765847301a4b13625fb05d542fab4fc924190a7414d39227db817a0e29cb +size 661 diff --git a/Content/Editor/Gizmo/MaterialAxisX.flax b/Content/Editor/Gizmo/MaterialAxisX.flax index 2bdb44208..9c7141673 100644 --- a/Content/Editor/Gizmo/MaterialAxisX.flax +++ b/Content/Editor/Gizmo/MaterialAxisX.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cdffe8d74604845d50004b3f481e28c996a5b7945ae4e3e9e69975d23b2ef176 -size 302 +oid sha256:261382d0e9d30168f325eea14e96ae7abdd2c1fd8bad166f1b134df507e5fda9 +size 661 diff --git a/Content/Editor/Gizmo/MaterialAxisY.flax b/Content/Editor/Gizmo/MaterialAxisY.flax index b07d7b64a..6a16d14da 100644 --- a/Content/Editor/Gizmo/MaterialAxisY.flax +++ b/Content/Editor/Gizmo/MaterialAxisY.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1407e7ad2dbd54e0833488fd96ef4c3ede3b78fd970b3ff7e804d51dd04fdb2e -size 302 +oid sha256:f9160ba4200d01d7dfe6c529bb2f8893ee5106fa644921de51757947a0cb7bea +size 661 diff --git a/Content/Editor/Gizmo/MaterialAxisZ.flax b/Content/Editor/Gizmo/MaterialAxisZ.flax index e2bf44327..29c9a49d4 100644 --- a/Content/Editor/Gizmo/MaterialAxisZ.flax +++ b/Content/Editor/Gizmo/MaterialAxisZ.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9f4a98b0028a9a9750f8dad737e5baf2bd061970f2f35fd10deacf47162cd992 -size 302 +oid sha256:5d129825361a89fca14f1dbad60a983cfac60d69284be66ca5e84041713e07a6 +size 661 diff --git a/Content/Editor/Gizmo/MaterialSphere.flax b/Content/Editor/Gizmo/MaterialSphere.flax index bf110acfb..1da1a3413 100644 --- a/Content/Editor/Gizmo/MaterialSphere.flax +++ b/Content/Editor/Gizmo/MaterialSphere.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bf88f48c5de6b8fb8c7effbbdded9e6f115b1a3ac262d60785987c8f24107dfb -size 567 +oid sha256:55fe4f30e87ddda26928901beeef710bc5eaaf7712224bf633c674465cf3b4ac +size 661 diff --git a/Source/Editor/Gizmo/TransformGizmoBase.Draw.cs b/Source/Editor/Gizmo/TransformGizmoBase.Draw.cs index 4166b463d..77bfff4b4 100644 --- a/Source/Editor/Gizmo/TransformGizmoBase.Draw.cs +++ b/Source/Editor/Gizmo/TransformGizmoBase.Draw.cs @@ -60,22 +60,24 @@ namespace FlaxEditor.Gizmo Platform.Fatal("Failed to load transform gizmo resources."); } - ApplyGizmoOptionsToMaterials(Editor.Instance.Options.Options); - - Editor.Instance.Options.OptionsChanged += ApplyGizmoOptionsToMaterials; + // Setup editor options + OnEditorOptionsChanged(Editor.Instance.Options.Options); + Editor.Instance.Options.OptionsChanged += OnEditorOptionsChanged; } - private void ApplyGizmoOptionsToMaterials(EditorOptions o) + private void OnEditorOptionsChanged(EditorOptions options) { - _materialAxisX.SetParameterValue(_brightnessParamName, o.Visual.transformGizmoBrightness); - _materialAxisY.SetParameterValue(_brightnessParamName, o.Visual.transformGizmoBrightness); - _materialAxisZ.SetParameterValue(_brightnessParamName, o.Visual.transformGizmoBrightness); - _materialAxisLocked.SetParameterValue(_brightnessParamName, o.Visual.transformGizmoBrightness); - - _materialAxisX.SetParameterValue(_opacityParamName, o.Visual.transformGizmoOpacity); - _materialAxisY.SetParameterValue(_opacityParamName, o.Visual.transformGizmoOpacity); - _materialAxisZ.SetParameterValue(_opacityParamName, o.Visual.transformGizmoOpacity); - _materialAxisLocked.SetParameterValue(_opacityParamName, o.Visual.transformGizmoOpacity); + float brightness = options.Visual.TransformGizmoBrightness; + _materialAxisX.SetParameterValue(_brightnessParamName, brightness); + _materialAxisY.SetParameterValue(_brightnessParamName, brightness); + _materialAxisZ.SetParameterValue(_brightnessParamName, brightness); + _materialAxisLocked.SetParameterValue(_brightnessParamName, brightness); + + float opacity = options.Visual.TransformGizmoOpacity; + _materialAxisX.SetParameterValue(_opacityParamName, opacity); + _materialAxisY.SetParameterValue(_opacityParamName, opacity); + _materialAxisZ.SetParameterValue(_opacityParamName, opacity); + _materialAxisLocked.SetParameterValue(_opacityParamName, opacity); } /// @@ -86,13 +88,13 @@ namespace FlaxEditor.Gizmo if (!_modelCube || !_modelCube.IsLoaded) return; + // Find out if any of the selected objects can not be moved bool gizmoLocked = false; - - // Find out if any of the selected objects can not be moved. if (Editor.Instance.StateMachine.IsPlayMode) { - foreach (SceneGraphNode obj in Editor.Instance.SceneEditing.Selection) + for (int i = 0; i < SelectionCount; i++) { + var obj = GetSelectedObject(i); if (obj.CanTransform == false) { gizmoLocked = true; diff --git a/Source/Editor/Options/VisualOptions.cs b/Source/Editor/Options/VisualOptions.cs index 5314cd8c1..cb5a0a89d 100644 --- a/Source/Editor/Options/VisualOptions.cs +++ b/Source/Editor/Options/VisualOptions.cs @@ -58,14 +58,14 @@ namespace FlaxEditor.Options /// [DefaultValue(1f), Range(0f, 5f)] [EditorDisplay("Transform Gizmo", "Gizmo Brightness"), EditorOrder(210)] - public float transformGizmoBrightness { get; set; } = 1f; + public float TransformGizmoBrightness { get; set; } = 1f; /// - /// Gets or set a value indicating the opactiy of the transform gizmo. + /// Gets or set a value indicating the opacity of the transform gizmo. /// [DefaultValue(1f), Range(0f, 1f)] [EditorDisplay("Transform Gizmo", "Gizmo Opacity"), EditorOrder(211)] - public float transformGizmoOpacity { get; set; } = 1f; + public float TransformGizmoOpacity { get; set; } = 1f; /// /// Gets or sets a value indicating whether enable MSAA for DebugDraw primitives rendering. Helps with pixel aliasing but reduces performance. From 2175837f3355db189e8f1f93d3abede8a36911f8 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 19 Dec 2024 13:07:59 +0100 Subject: [PATCH 31/69] Add XCode version parsing --- .../Tools/Flax.Build/Platforms/Apple/XCode.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/Source/Tools/Flax.Build/Platforms/Apple/XCode.cs b/Source/Tools/Flax.Build/Platforms/Apple/XCode.cs index ef1070191..2a7bd7560 100644 --- a/Source/Tools/Flax.Build/Platforms/Apple/XCode.cs +++ b/Source/Tools/Flax.Build/Platforms/Apple/XCode.cs @@ -32,16 +32,32 @@ namespace Flax.Build.Platforms return; try { + // Get path RootPath = Utilities.ReadProcessOutput("xcode-select", "--print-path"); if (string.IsNullOrEmpty(RootPath) || !Directory.Exists(RootPath)) return; IsValid = true; Version = new Version(1, 0); - Log.Verbose(string.Format("Found XCode at {0}", RootPath)); + + // Get version (optional) + var versionText = Utilities.ReadProcessOutput("xcodebuild", "-version"); + var versionLines = versionText?.Split('\n') ?? null; + if (versionLines != null && versionLines.Length != 0) + { + versionText = versionLines[0].Trim(); + var versionParts = versionText.Split(' '); + if (versionParts != null && versionParts.Length > 1) + { + versionText = versionParts[1].Trim(); + if (Version.TryParse(versionText, out var v)) + Version = v; + } + } } catch { } + Log.Verbose(string.Format("Found XCode {1} at {0}", RootPath, Version)); } } } From 12f3f00f9f6414c49e5d96a15af93cceafa19168 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 19 Dec 2024 13:21:47 +0100 Subject: [PATCH 32/69] Fix log file spam and limit size to 1GB #2980 --- Source/Engine/Core/Log.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Source/Engine/Core/Log.cpp b/Source/Engine/Core/Log.cpp index 2b6d0f300..b93d96ccd 100644 --- a/Source/Engine/Core/Log.cpp +++ b/Source/Engine/Core/Log.cpp @@ -25,6 +25,7 @@ namespace bool IsWindowsSingleNewLineChar = false; #endif int LogTotalErrorsCnt = 0; + int32 LogTotalWriteSize = 0; FileWriteStream* LogFile = nullptr; CriticalSection LogLocker; DateTime LogStartTime; @@ -149,10 +150,17 @@ void Log::Logger::Write(const StringView& msg) Platform::Log(msg); // Write message to log file - if (LogAfterInit) + constexpr uint LogMaxWriteSize = 1 * 1024 * 1024; // 1GB + if (LogAfterInit && LogTotalWriteSize < LogMaxWriteSize) { + LogTotalWriteSize += length; LogFile->WriteBytes(ptr, length * sizeof(Char)); LogFile->WriteBytes(TEXT(PLATFORM_LINE_TERMINATOR), (ARRAY_COUNT(PLATFORM_LINE_TERMINATOR) - 1) * sizeof(Char)); + if (LogTotalWriteSize >= LogMaxWriteSize) + { + StringView endMessage(TEXT("Trimming log file.\n\n")); + LogFile->WriteBytes(endMessage.Get(), endMessage.Length() * sizeof(Char)); + } #if LOG_ENABLE_AUTO_FLUSH LogFile->Flush(); #endif From 0f847335c33039e09b43623396a4e725c05f2750 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 19 Dec 2024 14:56:22 +0100 Subject: [PATCH 33/69] Fix typo on mac --- Source/Engine/Core/Log.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Engine/Core/Log.cpp b/Source/Engine/Core/Log.cpp index b93d96ccd..8b5427bd6 100644 --- a/Source/Engine/Core/Log.cpp +++ b/Source/Engine/Core/Log.cpp @@ -150,7 +150,7 @@ void Log::Logger::Write(const StringView& msg) Platform::Log(msg); // Write message to log file - constexpr uint LogMaxWriteSize = 1 * 1024 * 1024; // 1GB + constexpr int32 LogMaxWriteSize = 1 * 1024 * 1024; // 1GB if (LogAfterInit && LogTotalWriteSize < LogMaxWriteSize) { LogTotalWriteSize += length; From 36d4417905892bec73489b7ecd500886dd53b5c2 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Fri, 20 Dec 2024 09:29:36 -0600 Subject: [PATCH 34/69] Add game plugin template. --- .../Editor/Scripting/GamePluginTemplate.cs | 25 +++++++++++++++++++ Source/Editor/Content/Proxy/CSharpProxy.cs | 17 +++++++++++++ .../Editor/Modules/ContentDatabaseModule.cs | 1 + 3 files changed, 43 insertions(+) create mode 100644 Content/Editor/Scripting/GamePluginTemplate.cs diff --git a/Content/Editor/Scripting/GamePluginTemplate.cs b/Content/Editor/Scripting/GamePluginTemplate.cs new file mode 100644 index 000000000..d110fa68d --- /dev/null +++ b/Content/Editor/Scripting/GamePluginTemplate.cs @@ -0,0 +1,25 @@ +%copyright%using System; +using System.Collections.Generic; +using FlaxEngine; + +namespace %namespace%; + +/// +/// %class% GamePlugin. +/// +public class %class% : GamePlugin +{ + /// + public override void Initialize() + { + base.Initialize(); + + } + + /// + public override void Deinitialize() + { + base.Deinitialize(); + + } +} \ No newline at end of file diff --git a/Source/Editor/Content/Proxy/CSharpProxy.cs b/Source/Editor/Content/Proxy/CSharpProxy.cs index 8abdf8b30..f0a7997c7 100644 --- a/Source/Editor/Content/Proxy/CSharpProxy.cs +++ b/Source/Editor/Content/Proxy/CSharpProxy.cs @@ -106,6 +106,23 @@ namespace FlaxEditor.Content } } + /// + /// Context proxy object for C# GamePlugin files. + /// + /// + [ContentContextMenu("New/C#/C# GamePlugin")] + public class CSharpGamePluginProxy : CSharpProxy + { + /// + public override string Name => "C# GamePlugin"; + + /// + protected override void GetTemplatePath(out string path) + { + path = StringUtils.CombinePaths(Globals.EngineContentFolder, "Editor/Scripting/GamePluginTemplate.cs"); + } + } + /// /// Context proxy object for empty C# files. /// diff --git a/Source/Editor/Modules/ContentDatabaseModule.cs b/Source/Editor/Modules/ContentDatabaseModule.cs index 7a85107d9..4de7b593b 100644 --- a/Source/Editor/Modules/ContentDatabaseModule.cs +++ b/Source/Editor/Modules/ContentDatabaseModule.cs @@ -1140,6 +1140,7 @@ namespace FlaxEditor.Modules Proxy.Add(new CSharpEmptyStructProxy()); Proxy.Add(new CSharpEmptyInterfaceProxy()); Proxy.Add(new CSharpActorProxy()); + Proxy.Add(new CSharpGamePluginProxy()); Proxy.Add(new CppAssetProxy()); Proxy.Add(new CppStaticClassProxy()); Proxy.Add(new CppScriptProxy()); From 88703d721bfdf02a2c395ecf80b03e4de5a79f0e Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Mon, 23 Dec 2024 16:51:37 -0600 Subject: [PATCH 35/69] Warn if wrong type while setting material parameter. --- Source/Engine/Content/Assets/MaterialBase.cpp | 13 ++++++++++--- Source/Engine/Content/Assets/MaterialBase.h | 5 +++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/Source/Engine/Content/Assets/MaterialBase.cpp b/Source/Engine/Content/Assets/MaterialBase.cpp index d537a5746..6f111da68 100644 --- a/Source/Engine/Content/Assets/MaterialBase.cpp +++ b/Source/Engine/Content/Assets/MaterialBase.cpp @@ -25,13 +25,20 @@ Variant MaterialBase::GetParameterValue(const StringView& name) return Variant::Null; } -void MaterialBase::SetParameterValue(const StringView& name, const Variant& value, bool warnIfMissing) +void MaterialBase::SetParameterValue(const StringView& name, const Variant& value, bool warnIfMissing, bool warnIfWrongType) { const auto param = Params.Get(name); if (param) { - param->SetValue(value); - param->SetIsOverride(true); + if (param->GetValue().Type == value.Type) + { + param->SetValue(value); + param->SetIsOverride(true); + } + else if (warnIfWrongType) + { + LOG(Warning, "Material parameter '{0}' in material {1} is type '{2}' and not type '{3}'.", String(name), ToString(), param->GetValue().Type, value.Type); + } } else if (warnIfMissing) { diff --git a/Source/Engine/Content/Assets/MaterialBase.h b/Source/Engine/Content/Assets/MaterialBase.h index 81316b106..3d6487772 100644 --- a/Source/Engine/Content/Assets/MaterialBase.h +++ b/Source/Engine/Content/Assets/MaterialBase.h @@ -65,8 +65,9 @@ public: /// /// The parameter name. /// The value to set. - /// True if warn if parameter is missing, otherwise will do nothing. - API_FUNCTION() void SetParameterValue(const StringView& name, const Variant& value, bool warnIfMissing = true); + /// True to warn if parameter is missing, otherwise will do nothing. + /// True to warn if value is wrong type, otherwise will do nothing. + API_FUNCTION() void SetParameterValue(const StringView& name, const Variant& value, bool warnIfMissing = true, bool warnIfWrongType = true); /// /// Creates the virtual material instance of this material which allows to override any material parameters. From 6a8814c99a682176b984ac630bccc6266c1b0471 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Sun, 29 Dec 2024 17:08:10 -0600 Subject: [PATCH 36/69] Fix .exe being deleted when using the "Run cooked build" option. --- Source/Editor/Cooker/GameCooker.cpp | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/Source/Editor/Cooker/GameCooker.cpp b/Source/Editor/Cooker/GameCooker.cpp index 17392adee..36f2da11c 100644 --- a/Source/Editor/Cooker/GameCooker.cpp +++ b/Source/Editor/Cooker/GameCooker.cpp @@ -671,11 +671,14 @@ bool GameCookerImpl::Build() MCore::Thread::Attach(); // Build Started - CallEvent(GameCooker::EventType::BuildStarted); - data.Tools->OnBuildStarted(data); - for (int32 stepIndex = 0; stepIndex < Steps.Count(); stepIndex++) - Steps[stepIndex]->OnBuildStarted(data); - data.InitProgress(Steps.Count()); + if (!EnumHasAnyFlags(data.Options, BuildOptions::NoCook)) + { + CallEvent(GameCooker::EventType::BuildStarted); + data.Tools->OnBuildStarted(data); + for (int32 stepIndex = 0; stepIndex < Steps.Count(); stepIndex++) + Steps[stepIndex]->OnBuildStarted(data); + data.InitProgress(Steps.Count()); + } // Execute all steps in a sequence bool failed = false; @@ -741,10 +744,13 @@ bool GameCookerImpl::Build() } IsRunning = false; CancelFlag = 0; - for (int32 stepIndex = 0; stepIndex < Steps.Count(); stepIndex++) - Steps[stepIndex]->OnBuildEnded(data, failed); - data.Tools->OnBuildEnded(data, failed); - CallEvent(failed ? GameCooker::EventType::BuildFailed : GameCooker::EventType::BuildDone); + if (!EnumHasAnyFlags(data.Options, BuildOptions::NoCook)) + { + for (int32 stepIndex = 0; stepIndex < Steps.Count(); stepIndex++) + Steps[stepIndex]->OnBuildEnded(data, failed); + data.Tools->OnBuildEnded(data, failed); + CallEvent(failed ? GameCooker::EventType::BuildFailed : GameCooker::EventType::BuildDone); + } Delete(Data); Data = nullptr; From 899528e087bead777440cc2f179ca1c307c6c53c Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Mon, 30 Dec 2024 21:27:03 -0600 Subject: [PATCH 37/69] Add invert options for texture imports for Red, Blue, and Alpha channels. --- .../TextureTool/TextureTool.DirectXTex.cpp | 83 ++++++++++++++++++- Source/Engine/Tools/TextureTool/TextureTool.h | 18 +++- 2 files changed, 96 insertions(+), 5 deletions(-) diff --git a/Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp b/Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp index dc2b20778..f3515ebfb 100644 --- a/Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp +++ b/Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp @@ -730,6 +730,9 @@ bool TextureTool::ImportTextureDirectXTex(ImageType type, const StringView& path if (!options.FlipY && !options.FlipX && !options.InvertGreenChannel && + !options.InvertRedChannel && + !options.InvertAlphaChannel && + !options.InvertBlueChannel && !options.ReconstructZChannel && options.Compress && type == ImageType::DDS && @@ -831,9 +834,7 @@ bool TextureTool::ImportTextureDirectXTex(ImageType type, const StringView& path for (size_t j = 0; j < w; ++j) { const DirectX::XMVECTOR value = inPixels[j]; - const DirectX::XMVECTOR inverty = DirectX::XMVectorSubtract(DirectX::g_XMOne, value); - outPixels[j] = DirectX::XMVectorSelect(value, inverty, s_selecty); } }, timage); @@ -844,6 +845,84 @@ bool TextureTool::ImportTextureDirectXTex(ImageType type, const StringView& path } SET_CURRENT_IMG(timage); } + + // Check if invert red channel + if (!keepAsIs && options.InvertRedChannel) + { + auto& timage = GET_TMP_IMG(); + result = TransformImage(currentImage->GetImages(), currentImage->GetImageCount(), currentImage->GetMetadata(), + [&](DirectX::XMVECTOR* outPixels, const DirectX::XMVECTOR* inPixels, size_t w, size_t y) + { + static const DirectX::XMVECTORU32 s_selectx = { { { DirectX::XM_SELECT_1, DirectX::XM_SELECT_0, DirectX::XM_SELECT_0, DirectX::XM_SELECT_0 } } }; + + UNREFERENCED_PARAMETER(y); + + for (size_t j = 0; j < w; ++j) + { + const DirectX::XMVECTOR value = inPixels[j]; + const DirectX::XMVECTOR inverty = DirectX::XMVectorSubtract(DirectX::g_XMOne, value); + outPixels[j] = DirectX::XMVectorSelect(value, inverty, s_selectx); + } + }, timage); + if (FAILED(result)) + { + errorMsg = String::Format(TEXT("Cannot invert red channel in texture, error: {0:x}"), static_cast(result)); + return true; + } + SET_CURRENT_IMG(timage); + } + + // Check if invert red channel + if (!keepAsIs && options.InvertBlueChannel) + { + auto& timage = GET_TMP_IMG(); + result = TransformImage(currentImage->GetImages(), currentImage->GetImageCount(), currentImage->GetMetadata(), + [&](DirectX::XMVECTOR* outPixels, const DirectX::XMVECTOR* inPixels, size_t w, size_t y) + { + static const DirectX::XMVECTORU32 s_selectz = { { { DirectX::XM_SELECT_0, DirectX::XM_SELECT_0, DirectX::XM_SELECT_1, DirectX::XM_SELECT_0 } } }; + + UNREFERENCED_PARAMETER(y); + + for (size_t j = 0; j < w; ++j) + { + const DirectX::XMVECTOR value = inPixels[j]; + const DirectX::XMVECTOR inverty = DirectX::XMVectorSubtract(DirectX::g_XMOne, value); + outPixels[j] = DirectX::XMVectorSelect(value, inverty, s_selectz); + } + }, timage); + if (FAILED(result)) + { + errorMsg = String::Format(TEXT("Cannot invert blue channel in texture, error: {0:x}"), static_cast(result)); + return true; + } + SET_CURRENT_IMG(timage); + } + + // Check if invert alpha channel + if (!keepAsIs && options.InvertAlphaChannel) + { + auto& timage = GET_TMP_IMG(); + result = TransformImage(currentImage->GetImages(), currentImage->GetImageCount(), currentImage->GetMetadata(), + [&](DirectX::XMVECTOR* outPixels, const DirectX::XMVECTOR* inPixels, size_t w, size_t y) + { + static const DirectX::XMVECTORU32 s_selectw = { { { DirectX::XM_SELECT_0, DirectX::XM_SELECT_0, DirectX::XM_SELECT_0, DirectX::XM_SELECT_1 } } }; + + UNREFERENCED_PARAMETER(y); + + for (size_t j = 0; j < w; ++j) + { + const DirectX::XMVECTOR value = inPixels[j]; + const DirectX::XMVECTOR inverty = DirectX::XMVectorSubtract(DirectX::g_XMOne, value); + outPixels[j] = DirectX::XMVectorSelect(value, inverty, s_selectw); + } + }, timage); + if (FAILED(result)) + { + errorMsg = String::Format(TEXT("Cannot invert alpha channel in texture, error: {0:x}"), static_cast(result)); + return true; + } + SET_CURRENT_IMG(timage); + } // Reconstruct Z Channel if (!keepAsIs & options.ReconstructZChannel) diff --git a/Source/Engine/Tools/TextureTool/TextureTool.h b/Source/Engine/Tools/TextureTool/TextureTool.h index 13bac0dc5..cfca9aec5 100644 --- a/Source/Engine/Tools/TextureTool/TextureTool.h +++ b/Source/Engine/Tools/TextureTool/TextureTool.h @@ -61,12 +61,24 @@ API_CLASS(Namespace="FlaxEngine.Tools", Static) class FLAXENGINE_API TextureTool API_FIELD(Attributes="EditorOrder(71)") bool FlipX = false; - // True if to invert the green channel on a normal map. Good for OpenGL to DirectX conversion. - API_FIELD(Attributes = "EditorOrder(72)") + // Invert the red channel. + API_FIELD(Attributes = "EditorOrder(72), EditorDisplay(\"Invert Channels\"), ExpandGroups") + bool InvertRedChannel = false; + + // Invert the green channel. Good for OpenGL to DirectX conversion. + API_FIELD(Attributes = "EditorOrder(73), EditorDisplay(\"Invert Channels\")") bool InvertGreenChannel = false; + // Invert the blue channel. + API_FIELD(Attributes = "EditorOrder(74), EditorDisplay(\"Invert Channels\")") + bool InvertBlueChannel = false; + + // Invert the alpha channel. + API_FIELD(Attributes = "EditorOrder(75), EditorDisplay(\"Invert Channels\")") + bool InvertAlphaChannel = false; + // Rebuild Z (blue) channel assuming X/Y are normals. - API_FIELD(Attributes = "EditorOrder(73)") + API_FIELD(Attributes = "EditorOrder(76)") bool ReconstructZChannel = false; // Texture size scale. Allows increasing or decreasing the imported texture resolution. Default is 1. From cb6ab6a6478b3c299f0e818c505225d0f456ec77 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Mon, 30 Dec 2024 22:14:18 -0600 Subject: [PATCH 38/69] Fix comment --- Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp b/Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp index f3515ebfb..683bcc292 100644 --- a/Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp +++ b/Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp @@ -872,7 +872,7 @@ bool TextureTool::ImportTextureDirectXTex(ImageType type, const StringView& path SET_CURRENT_IMG(timage); } - // Check if invert red channel + // Check if invert blue channel if (!keepAsIs && options.InvertBlueChannel) { auto& timage = GET_TMP_IMG(); From f71e731e54be8401527a82510fd0f0b9f482b9e4 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Mon, 30 Dec 2024 23:42:32 -0600 Subject: [PATCH 39/69] Add saving and loading. --- Source/Engine/Tools/TextureTool/TextureTool.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Source/Engine/Tools/TextureTool/TextureTool.cpp b/Source/Engine/Tools/TextureTool/TextureTool.cpp index 550e26699..bc4c544d7 100644 --- a/Source/Engine/Tools/TextureTool/TextureTool.cpp +++ b/Source/Engine/Tools/TextureTool/TextureTool.cpp @@ -27,7 +27,7 @@ namespace String TextureTool::Options::ToString() const { - return String::Format(TEXT("Type: {}, IsAtlas: {}, NeverStream: {}, IndependentChannels: {}, sRGB: {}, GenerateMipMaps: {}, FlipY: {}, InvertGreen: {} Scale: {}, MaxSize: {}, Resize: {}, PreserveAlphaCoverage: {}, PreserveAlphaCoverageReference: {}, SizeX: {}, SizeY: {}"), + return String::Format(TEXT("Type: {}, IsAtlas: {}, NeverStream: {}, IndependentChannels: {}, sRGB: {}, GenerateMipMaps: {}, FlipY: {}, InvertRed: {}, InvertGreen: {}, InvertBlue {}, Invert Alpha {}, Scale: {}, MaxSize: {}, Resize: {}, PreserveAlphaCoverage: {}, PreserveAlphaCoverageReference: {}, SizeX: {}, SizeY: {}"), ScriptingEnum::ToString(Type), IsAtlas, NeverStream, @@ -35,7 +35,10 @@ String TextureTool::Options::ToString() const sRGB, GenerateMipMaps, FlipY, + InvertRedChannel, InvertGreenChannel, + InvertBlueChannel, + InvertAlphaChannel, Scale, MaxSize, MaxSize, @@ -76,9 +79,18 @@ void TextureTool::Options::Serialize(SerializeStream& stream, const void* otherO stream.JKEY("FlipX"); stream.Bool(FlipX); + stream.JKEY("InvertRedChannel"); + stream.Bool(InvertRedChannel); + stream.JKEY("InvertGreenChannel"); stream.Bool(InvertGreenChannel); + stream.JKEY("InvertBlueChannel"); + stream.Bool(InvertBlueChannel); + + stream.JKEY("InvertAlphaChannel"); + stream.Bool(InvertAlphaChannel); + stream.JKEY("ReconstructZChannel"); stream.Bool(ReconstructZChannel); @@ -143,7 +155,10 @@ void TextureTool::Options::Deserialize(DeserializeStream& stream, ISerializeModi GenerateMipMaps = JsonTools::GetBool(stream, "GenerateMipMaps", GenerateMipMaps); FlipY = JsonTools::GetBool(stream, "FlipY", FlipY); FlipX = JsonTools::GetBool(stream, "FlipX", FlipX); + InvertRedChannel = JsonTools::GetBool(stream, "InvertRedChannel", InvertRedChannel); InvertGreenChannel = JsonTools::GetBool(stream, "InvertGreenChannel", InvertGreenChannel); + InvertBlueChannel = JsonTools::GetBool(stream, "InvertBlueChannel", InvertBlueChannel); + InvertAlphaChannel = JsonTools::GetBool(stream, "InvertAlphaChannel", InvertAlphaChannel); ReconstructZChannel = JsonTools::GetBool(stream, "ReconstructZChannel", ReconstructZChannel); Resize = JsonTools::GetBool(stream, "Resize", Resize); KeepAspectRatio = JsonTools::GetBool(stream, "KeepAspectRatio", KeepAspectRatio); From e53eddaba564e4c34aca7074212e5a56f35f43a6 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Tue, 31 Dec 2024 12:38:29 -0600 Subject: [PATCH 40/69] Add import path UI and button to open folder in asset import settings. --- .../Editor/Windows/Assets/AnimationWindow.cs | 16 +++++++++++++- .../Editor/Windows/Assets/AudioClipWindow.cs | 14 +++++++++++++ .../Windows/Assets/CubeTextureWindow.cs | 14 +++++++++++++ Source/Editor/Windows/Assets/ModelWindow.cs | 16 +++++++++++++- .../Windows/Assets/SkinnedModelWindow.cs | 15 ++++++++++++- .../Windows/Assets/SpriteAtlasWindow.cs | 21 +++++++++++++++++++ Source/Editor/Windows/Assets/TextureWindow.cs | 21 +++++++++++++++++++ 7 files changed, 114 insertions(+), 3 deletions(-) diff --git a/Source/Editor/Windows/Assets/AnimationWindow.cs b/Source/Editor/Windows/Assets/AnimationWindow.cs index d0e6a3fe9..3c9f2c886 100644 --- a/Source/Editor/Windows/Assets/AnimationWindow.cs +++ b/Source/Editor/Windows/Assets/AnimationWindow.cs @@ -2,6 +2,7 @@ using System; using System.Globalization; +using System.IO; using System.Reflection; using System.Xml; using FlaxEditor.Content; @@ -209,9 +210,22 @@ namespace FlaxEditor.Windows.Assets var importSettingsField = typeof(PropertiesProxy).GetField("ImportSettings", BindingFlags.NonPublic | BindingFlags.Instance); var importSettingsValues = new ValueContainer(new ScriptMemberInfo(importSettingsField)) { proxy.ImportSettings }; group.Object(importSettingsValues); + + (proxy.Window.Item as BinaryAssetItem).GetImportPath(out var path); + if (!string.IsNullOrEmpty(path)) + { + layout.Space(5); + layout.Label("Import Path:"); + var textBox = layout.TextBox().TextBox; + textBox.IsReadOnly = true; + textBox.Text = path; + layout.Space(2); + var button = layout.Button("Open Import Path in Explorer").Button; + button.Clicked += () => FileSystem.ShowFileExplorer(Path.GetDirectoryName(path)); + } layout.Space(5); - var reimportButton = group.Button("Reimport"); + var reimportButton = layout.Button("Reimport"); reimportButton.Button.Clicked += () => ((PropertiesProxy)Values[0]).Reimport(); } } diff --git a/Source/Editor/Windows/Assets/AudioClipWindow.cs b/Source/Editor/Windows/Assets/AudioClipWindow.cs index 998073858..be9e64ee4 100644 --- a/Source/Editor/Windows/Assets/AudioClipWindow.cs +++ b/Source/Editor/Windows/Assets/AudioClipWindow.cs @@ -1,5 +1,6 @@ // Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. +using System.IO; using System.Xml; using FlaxEditor.Content; using FlaxEditor.Content.Import; @@ -99,6 +100,19 @@ namespace FlaxEditor.Windows.Assets } base.Initialize(layout); + + (window.Item as BinaryAssetItem).GetImportPath(out var path); + if (!string.IsNullOrEmpty(path)) + { + layout.Space(5); + layout.Label("Import Path:"); + var textBox = layout.TextBox().TextBox; + textBox.IsReadOnly = true; + textBox.Text = path; + layout.Space(2); + var button = layout.Button("Open Import Path in Explorer").Button; + button.Clicked += () => FileSystem.ShowFileExplorer(Path.GetDirectoryName(path)); + } layout.Space(10); var reimportButton = layout.Button("Reimport"); diff --git a/Source/Editor/Windows/Assets/CubeTextureWindow.cs b/Source/Editor/Windows/Assets/CubeTextureWindow.cs index 56585bba8..13d3a9398 100644 --- a/Source/Editor/Windows/Assets/CubeTextureWindow.cs +++ b/Source/Editor/Windows/Assets/CubeTextureWindow.cs @@ -1,5 +1,6 @@ // Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. +using System.IO; using System.Xml; using FlaxEditor.Content; using FlaxEditor.Content.Import; @@ -52,6 +53,19 @@ namespace FlaxEditor.Windows.Assets } base.Initialize(layout); + + (window.Item as BinaryAssetItem).GetImportPath(out var path); + if (!string.IsNullOrEmpty(path)) + { + layout.Space(5); + layout.Label("Import Path:"); + var textBox = layout.TextBox().TextBox; + textBox.IsReadOnly = true; + textBox.Text = path; + layout.Space(2); + var button = layout.Button("Open Import Path in Explorer").Button; + button.Clicked += () => FileSystem.ShowFileExplorer(Path.GetDirectoryName(path)); + } layout.Space(10); var reimportButton = layout.Button("Reimport"); diff --git a/Source/Editor/Windows/Assets/ModelWindow.cs b/Source/Editor/Windows/Assets/ModelWindow.cs index c3e285973..0d4863cd1 100644 --- a/Source/Editor/Windows/Assets/ModelWindow.cs +++ b/Source/Editor/Windows/Assets/ModelWindow.cs @@ -1,6 +1,7 @@ // Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. using System.Collections.Generic; +using System.IO; using System.Linq; using System.Reflection; using System.Threading.Tasks; @@ -758,8 +759,21 @@ namespace FlaxEditor.Windows.Assets var importSettingsValues = new ValueContainer(new ScriptMemberInfo(importSettingsField)) { proxy.ImportSettings }; group.Object(importSettingsValues); + (proxy.Window.Item as BinaryAssetItem).GetImportPath(out var path); + if (!string.IsNullOrEmpty(path)) + { + layout.Space(5); + layout.Label("Import Path:"); + var textBox = layout.TextBox().TextBox; + textBox.IsReadOnly = true; + textBox.Text = path; + layout.Space(2); + var button = layout.Button("Open Import Path in Explorer").Button; + button.Clicked += () => FileSystem.ShowFileExplorer(Path.GetDirectoryName(path)); + } + layout.Space(5); - var reimportButton = group.Button("Reimport"); + var reimportButton = layout.Button("Reimport"); reimportButton.Button.Clicked += () => ((ImportPropertiesProxy)Values[0]).Reimport(); } } diff --git a/Source/Editor/Windows/Assets/SkinnedModelWindow.cs b/Source/Editor/Windows/Assets/SkinnedModelWindow.cs index 671512584..27f14af5c 100644 --- a/Source/Editor/Windows/Assets/SkinnedModelWindow.cs +++ b/Source/Editor/Windows/Assets/SkinnedModelWindow.cs @@ -1022,9 +1022,22 @@ namespace FlaxEditor.Windows.Assets var importSettingsField = typeof(ImportPropertiesProxy).GetField("ImportSettings", BindingFlags.NonPublic | BindingFlags.Instance); var importSettingsValues = new ValueContainer(new ScriptMemberInfo(importSettingsField)) { proxy.ImportSettings }; group.Object(importSettingsValues); + + (proxy.Window.Item as BinaryAssetItem).GetImportPath(out var path); + if (!string.IsNullOrEmpty(path)) + { + layout.Space(5); + layout.Label("Import Path:"); + var textBox = layout.TextBox().TextBox; + textBox.IsReadOnly = true; + textBox.Text = path; + layout.Space(2); + var button = layout.Button("Open Import Path in Explorer").Button; + button.Clicked += () => FileSystem.ShowFileExplorer(Path.GetDirectoryName(path)); + } layout.Space(5); - var reimportButton = group.Button("Reimport"); + var reimportButton = layout.Button("Reimport"); reimportButton.Button.Clicked += () => ((ImportPropertiesProxy)Values[0]).Reimport(); } } diff --git a/Source/Editor/Windows/Assets/SpriteAtlasWindow.cs b/Source/Editor/Windows/Assets/SpriteAtlasWindow.cs index 9601555d2..73646b660 100644 --- a/Source/Editor/Windows/Assets/SpriteAtlasWindow.cs +++ b/Source/Editor/Windows/Assets/SpriteAtlasWindow.cs @@ -1,5 +1,6 @@ // Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. +using System.IO; using System.Linq; using System.Xml; using FlaxEditor.Content; @@ -110,8 +111,28 @@ namespace FlaxEditor.Windows.Assets { public override void Initialize(LayoutElementsContainer layout) { + var proxy = (PropertiesProxy)Values[0]; + if (proxy._window == null) + { + layout.Label("Loading...", TextAlignment.Center); + return; + } + base.Initialize(layout); + (proxy._window.Item as BinaryAssetItem).GetImportPath(out var path); + if (!string.IsNullOrEmpty(path)) + { + layout.Space(5); + layout.Label("Import Path:"); + var textBox = layout.TextBox().TextBox; + textBox.IsReadOnly = true; + textBox.Text = path; + layout.Space(2); + var button = layout.Button("Open Import Path in Explorer").Button; + button.Clicked += () => FileSystem.ShowFileExplorer(Path.GetDirectoryName(path)); + } + layout.Space(10); var reimportButton = layout.Button("Reimport"); reimportButton.Button.Clicked += () => ((PropertiesProxy)Values[0]).Reimport(); diff --git a/Source/Editor/Windows/Assets/TextureWindow.cs b/Source/Editor/Windows/Assets/TextureWindow.cs index 68f138978..c1500adf2 100644 --- a/Source/Editor/Windows/Assets/TextureWindow.cs +++ b/Source/Editor/Windows/Assets/TextureWindow.cs @@ -1,5 +1,6 @@ // Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. +using System.IO; using System.Xml; using FlaxEditor.Content; using FlaxEditor.Content.Import; @@ -134,8 +135,28 @@ namespace FlaxEditor.Windows.Assets { public override void Initialize(LayoutElementsContainer layout) { + var proxy = (ImportPropertiesProxy)Values[0]; + if (proxy._window == null) + { + layout.Label("Loading...", TextAlignment.Center); + return; + } + // Import settings base.Initialize(layout); + + (proxy._window.Item as BinaryAssetItem).GetImportPath(out var path); + if (!string.IsNullOrEmpty(path)) + { + layout.Space(5); + layout.Label("Import Path:"); + var textBox = layout.TextBox().TextBox; + textBox.IsReadOnly = true; + textBox.Text = path; + layout.Space(2); + var button = layout.Button("Open Import Path in Explorer").Button; + button.Clicked += () => FileSystem.ShowFileExplorer(Path.GetDirectoryName(path)); + } // Reimport layout.Space(10); From a313db22d25721925934a4f2e3b35aed519697a5 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Tue, 31 Dec 2024 12:52:54 -0600 Subject: [PATCH 41/69] Add tooltip text for path to let user know it is not editable. --- Source/Editor/Windows/Assets/AnimationWindow.cs | 1 + Source/Editor/Windows/Assets/AudioClipWindow.cs | 1 + Source/Editor/Windows/Assets/CubeTextureWindow.cs | 1 + Source/Editor/Windows/Assets/ModelWindow.cs | 1 + Source/Editor/Windows/Assets/SkinnedModelWindow.cs | 1 + Source/Editor/Windows/Assets/SpriteAtlasWindow.cs | 1 + Source/Editor/Windows/Assets/TextureWindow.cs | 1 + 7 files changed, 7 insertions(+) diff --git a/Source/Editor/Windows/Assets/AnimationWindow.cs b/Source/Editor/Windows/Assets/AnimationWindow.cs index 3c9f2c886..b03eae515 100644 --- a/Source/Editor/Windows/Assets/AnimationWindow.cs +++ b/Source/Editor/Windows/Assets/AnimationWindow.cs @@ -217,6 +217,7 @@ namespace FlaxEditor.Windows.Assets layout.Space(5); layout.Label("Import Path:"); var textBox = layout.TextBox().TextBox; + textBox.TooltipText = "Path is not editable here."; textBox.IsReadOnly = true; textBox.Text = path; layout.Space(2); diff --git a/Source/Editor/Windows/Assets/AudioClipWindow.cs b/Source/Editor/Windows/Assets/AudioClipWindow.cs index be9e64ee4..e44a4dd4c 100644 --- a/Source/Editor/Windows/Assets/AudioClipWindow.cs +++ b/Source/Editor/Windows/Assets/AudioClipWindow.cs @@ -107,6 +107,7 @@ namespace FlaxEditor.Windows.Assets layout.Space(5); layout.Label("Import Path:"); var textBox = layout.TextBox().TextBox; + textBox.TooltipText = "Path is not editable here."; textBox.IsReadOnly = true; textBox.Text = path; layout.Space(2); diff --git a/Source/Editor/Windows/Assets/CubeTextureWindow.cs b/Source/Editor/Windows/Assets/CubeTextureWindow.cs index 13d3a9398..0efcc3fde 100644 --- a/Source/Editor/Windows/Assets/CubeTextureWindow.cs +++ b/Source/Editor/Windows/Assets/CubeTextureWindow.cs @@ -60,6 +60,7 @@ namespace FlaxEditor.Windows.Assets layout.Space(5); layout.Label("Import Path:"); var textBox = layout.TextBox().TextBox; + textBox.TooltipText = "Path is not editable here."; textBox.IsReadOnly = true; textBox.Text = path; layout.Space(2); diff --git a/Source/Editor/Windows/Assets/ModelWindow.cs b/Source/Editor/Windows/Assets/ModelWindow.cs index 0d4863cd1..58ee67d67 100644 --- a/Source/Editor/Windows/Assets/ModelWindow.cs +++ b/Source/Editor/Windows/Assets/ModelWindow.cs @@ -765,6 +765,7 @@ namespace FlaxEditor.Windows.Assets layout.Space(5); layout.Label("Import Path:"); var textBox = layout.TextBox().TextBox; + textBox.TooltipText = "Path is not editable here."; textBox.IsReadOnly = true; textBox.Text = path; layout.Space(2); diff --git a/Source/Editor/Windows/Assets/SkinnedModelWindow.cs b/Source/Editor/Windows/Assets/SkinnedModelWindow.cs index 27f14af5c..e2e1bf4da 100644 --- a/Source/Editor/Windows/Assets/SkinnedModelWindow.cs +++ b/Source/Editor/Windows/Assets/SkinnedModelWindow.cs @@ -1029,6 +1029,7 @@ namespace FlaxEditor.Windows.Assets layout.Space(5); layout.Label("Import Path:"); var textBox = layout.TextBox().TextBox; + textBox.TooltipText = "Path is not editable here."; textBox.IsReadOnly = true; textBox.Text = path; layout.Space(2); diff --git a/Source/Editor/Windows/Assets/SpriteAtlasWindow.cs b/Source/Editor/Windows/Assets/SpriteAtlasWindow.cs index 73646b660..b220a6156 100644 --- a/Source/Editor/Windows/Assets/SpriteAtlasWindow.cs +++ b/Source/Editor/Windows/Assets/SpriteAtlasWindow.cs @@ -126,6 +126,7 @@ namespace FlaxEditor.Windows.Assets layout.Space(5); layout.Label("Import Path:"); var textBox = layout.TextBox().TextBox; + textBox.TooltipText = "Path is not editable here."; textBox.IsReadOnly = true; textBox.Text = path; layout.Space(2); diff --git a/Source/Editor/Windows/Assets/TextureWindow.cs b/Source/Editor/Windows/Assets/TextureWindow.cs index c1500adf2..3e1d436b3 100644 --- a/Source/Editor/Windows/Assets/TextureWindow.cs +++ b/Source/Editor/Windows/Assets/TextureWindow.cs @@ -151,6 +151,7 @@ namespace FlaxEditor.Windows.Assets layout.Space(5); layout.Label("Import Path:"); var textBox = layout.TextBox().TextBox; + textBox.TooltipText = "Path is not editable here."; textBox.IsReadOnly = true; textBox.Text = path; layout.Space(2); From f2e4fe300b5fc786a29389cfd6fe0d80493702f8 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Tue, 31 Dec 2024 12:56:43 -0600 Subject: [PATCH 42/69] Change color for readonly text. Fix selection still showing when text box is not focused. --- Source/Engine/UI/GUI/Common/TextBox.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Source/Engine/UI/GUI/Common/TextBox.cs b/Source/Engine/UI/GUI/Common/TextBox.cs index da8b299cb..64e8e1869 100644 --- a/Source/Engine/UI/GUI/Common/TextBox.cs +++ b/Source/Engine/UI/GUI/Common/TextBox.cs @@ -249,7 +249,7 @@ namespace FlaxEngine.GUI var text = ConvertedText(); // Check if sth is selected to draw selection - if (HasSelection) + if (HasSelection && IsFocused) { var leftEdge = font.GetCharPosition(text, SelectionLeft, ref _layout); var rightEdge = font.GetCharPosition(text, SelectionRight, ref _layout); @@ -294,6 +294,8 @@ namespace FlaxEngine.GUI var color = TextColor; if (!enabled) color *= 0.6f; + else if (_isReadOnly) + color *= 0.85f; Render2D.DrawText(font, text, color, ref _layout, TextMaterial); } else if (!string.IsNullOrEmpty(_watermarkText)) From 26d0b9a42c743e110bd361f2b10d29dde86db491 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Tue, 31 Dec 2024 14:06:17 -0600 Subject: [PATCH 43/69] Fix rotation of UI size handles. --- Source/Editor/Gizmo/UIEditorGizmo.cs | 30 +++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/Source/Editor/Gizmo/UIEditorGizmo.cs b/Source/Editor/Gizmo/UIEditorGizmo.cs index 3fa574e1b..a7da826bd 100644 --- a/Source/Editor/Gizmo/UIEditorGizmo.cs +++ b/Source/Editor/Gizmo/UIEditorGizmo.cs @@ -1,5 +1,6 @@ // Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. +using System; using System.Collections.Generic; using System.Linq; using FlaxEditor.Gizmo; @@ -647,7 +648,34 @@ namespace FlaxEditor private void DrawControlWidget(UIControl uiControl, ref Float2 pos, ref Float2 mousePos, ref Float2 size, float scale, Float2 resizeAxis, CursorType cursor) { var style = Style.Current; - var rect = new Rectangle((pos + resizeAxis * 10 * scale) - size * 0.5f, size); + var control = uiControl.Control; + var rect = new Rectangle( + (pos + + new Float2(resizeAxis.X * Mathf.Cos(Mathf.DegreesToRadians * control.Rotation) - resizeAxis.Y * Mathf.Sin(Mathf.DegreesToRadians * control.Rotation), + resizeAxis.Y * Mathf.Cos(Mathf.DegreesToRadians * control.Rotation) + resizeAxis.X * Mathf.Sin(Mathf.DegreesToRadians * control.Rotation)) * 10 * scale) - size * 0.5f, + size); + + // Find more correct cursor at different angles + var unwindRotation = Mathf.UnwindDegrees(control.Rotation); + if (unwindRotation is (>= 45 and < 135) or (> -135 and <= -45) ) + { + switch (cursor) + { + case CursorType.SizeNESW: + cursor = CursorType.SizeNWSE; + break; + case CursorType.SizeNS: + cursor = CursorType.SizeWE; + break; + case CursorType.SizeNWSE: + cursor = CursorType.SizeNESW; + break; + case CursorType.SizeWE: + cursor = CursorType.SizeNS; + break; + default: break; + } + } if (rect.Contains(ref mousePos)) { Render2D.FillRectangle(rect, style.Foreground); From 867f7d01439ea764664021f00454f6ae547aa621 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Tue, 31 Dec 2024 14:12:23 -0600 Subject: [PATCH 44/69] Add local variables to simplify math. --- Source/Editor/Gizmo/UIEditorGizmo.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Source/Editor/Gizmo/UIEditorGizmo.cs b/Source/Editor/Gizmo/UIEditorGizmo.cs index a7da826bd..aba177b7d 100644 --- a/Source/Editor/Gizmo/UIEditorGizmo.cs +++ b/Source/Editor/Gizmo/UIEditorGizmo.cs @@ -649,14 +649,16 @@ namespace FlaxEditor { var style = Style.Current; var control = uiControl.Control; + var rotation = control.Rotation; + var rotationInRadians = rotation * Mathf.DegreesToRadians; var rect = new Rectangle( (pos + - new Float2(resizeAxis.X * Mathf.Cos(Mathf.DegreesToRadians * control.Rotation) - resizeAxis.Y * Mathf.Sin(Mathf.DegreesToRadians * control.Rotation), - resizeAxis.Y * Mathf.Cos(Mathf.DegreesToRadians * control.Rotation) + resizeAxis.X * Mathf.Sin(Mathf.DegreesToRadians * control.Rotation)) * 10 * scale) - size * 0.5f, + new Float2(resizeAxis.X * Mathf.Cos(rotationInRadians) - resizeAxis.Y * Mathf.Sin(rotationInRadians), + resizeAxis.Y * Mathf.Cos(rotationInRadians) + resizeAxis.X * Mathf.Sin(rotationInRadians)) * 10 * scale) - size * 0.5f, size); // Find more correct cursor at different angles - var unwindRotation = Mathf.UnwindDegrees(control.Rotation); + var unwindRotation = Mathf.UnwindDegrees(rotation); if (unwindRotation is (>= 45 and < 135) or (> -135 and <= -45) ) { switch (cursor) From 5af13bcc936dd04f71b873685042761e1b98b231 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Fri, 3 Jan 2025 13:04:52 -0600 Subject: [PATCH 45/69] Re-enable scale center gizmo. --- Source/Editor/Gizmo/TransformGizmoBase.Selection.cs | 6 +++--- Source/Editor/Gizmo/TransformGizmoBase.Settings.cs | 2 +- Source/Editor/Gizmo/TransformGizmoBase.cs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Source/Editor/Gizmo/TransformGizmoBase.Selection.cs b/Source/Editor/Gizmo/TransformGizmoBase.Selection.cs index 443a107e5..deeff8cb9 100644 --- a/Source/Editor/Gizmo/TransformGizmoBase.Selection.cs +++ b/Source/Editor/Gizmo/TransformGizmoBase.Selection.cs @@ -169,12 +169,12 @@ namespace FlaxEditor.Gizmo closestIntersection = intersection; } - /*// Center - if (CenterBoxRaw.Intersects(ref localRay, out intersection) && intersection < closestIntersection) + // Center + if (CenterBoxRaw.Intersects(ref localRay, out intersection) && intersection > closestIntersection) { _activeAxis = Axis.Center; closestIntersection = intersection; - }*/ + } break; } diff --git a/Source/Editor/Gizmo/TransformGizmoBase.Settings.cs b/Source/Editor/Gizmo/TransformGizmoBase.Settings.cs index bbd13f688..5b54a7c79 100644 --- a/Source/Editor/Gizmo/TransformGizmoBase.Settings.cs +++ b/Source/Editor/Gizmo/TransformGizmoBase.Settings.cs @@ -20,7 +20,7 @@ namespace FlaxEditor.Gizmo /// /// Offset to move axis away from center /// - private const float AxisOffset = 0.8f; + private const float AxisOffset = 1.2f; /// /// How thick the axis should be diff --git a/Source/Editor/Gizmo/TransformGizmoBase.cs b/Source/Editor/Gizmo/TransformGizmoBase.cs index 8fe91c252..cab0ab462 100644 --- a/Source/Editor/Gizmo/TransformGizmoBase.cs +++ b/Source/Editor/Gizmo/TransformGizmoBase.cs @@ -501,7 +501,7 @@ namespace FlaxEditor.Gizmo _scaleDelta = Vector3.Zero; if (ActiveAxis == Axis.Center) - scaleDelta = new Vector3(scaleDelta.AvgValue); + scaleDelta = new Vector3(scaleDelta.ValuesSum); } // Apply transformation (but to the parents, not whole selection pool) From 22914dc2328890b18631655fe6c001104028b940 Mon Sep 17 00:00:00 2001 From: Jake Young Date: Fri, 3 Jan 2025 17:31:21 -0500 Subject: [PATCH 46/69] Fix typo for error message when trying to load a project file that does not exist. --- Source/Editor/Editor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Editor/Editor.cpp b/Source/Editor/Editor.cpp index 8e4090c40..3d77445b9 100644 --- a/Source/Editor/Editor.cpp +++ b/Source/Editor/Editor.cpp @@ -550,7 +550,7 @@ int32 Editor::LoadProduct() } if (!FileSystem::FileExists(files[0])) { - Platform::Fatal(TEXT("Cannot opoen selected project file because it doesn't exist.")); + Platform::Fatal(TEXT("Cannot open selected project file because it doesn't exist.")); return -1; } projectPath = StringUtils::GetDirectoryName(files[0]); From a66cb4d1b2dbe435fe2061596a7edbccc1193415 Mon Sep 17 00:00:00 2001 From: Jake Young Date: Fri, 3 Jan 2025 18:57:23 -0500 Subject: [PATCH 47/69] Added a confirmation dialog for editors when the reset button is clicked. --- Source/Editor/Options/Editor.cs | 34 ++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/Source/Editor/Options/Editor.cs b/Source/Editor/Options/Editor.cs index b4f2de6e4..a1836fd6d 100644 --- a/Source/Editor/Options/Editor.cs +++ b/Source/Editor/Options/Editor.cs @@ -1,7 +1,9 @@ // Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. +using System.Text; using FlaxEditor.CustomEditors; using FlaxEditor.CustomEditors.Editors; +using FlaxEngine; using FlaxEngine.GUI; using FlaxEngine.Json; @@ -31,11 +33,33 @@ namespace FlaxEditor.Options private void OnResetButtonClicked() { - var obj = new T(); - var str = JsonSerializer.Serialize(obj); - JsonSerializer.Deserialize(Values[0], str); - SetValue(Values[0]); - Refresh(); + var editorClassName = typeof(T).Name; + + var editorName = new StringBuilder(); + editorName.Append(editorClassName[0]); + for (var i = 1; i < editorClassName.Length; i++) + { + // Whenever there is an uppercase letter, add a space to make it more pretty for the end user + if (char.IsUpper(editorClassName[i])) + { + editorName.Append(' '); + } + editorName.Append(editorClassName[i]); + } + + var result = MessageBox.Show($"Are you sure you want to reset \"{editorName}\" to default values?", + "Reset values?", + MessageBoxButtons.YesNo + ); + + if (result == DialogResult.Yes || result == DialogResult.OK) + { + var obj = new T(); + var str = JsonSerializer.Serialize(obj); + JsonSerializer.Deserialize(Values[0], str); + SetValue(Values[0]); + Refresh(); + } } } } From 7eb2088af0ad0c489bdb15df8e486ca6964bd642 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Mon, 6 Jan 2025 15:40:38 -0600 Subject: [PATCH 48/69] Use `Variant::CanCast()` for type check. --- Source/Engine/Content/Assets/MaterialBase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Engine/Content/Assets/MaterialBase.cpp b/Source/Engine/Content/Assets/MaterialBase.cpp index 6f111da68..9751f86d4 100644 --- a/Source/Engine/Content/Assets/MaterialBase.cpp +++ b/Source/Engine/Content/Assets/MaterialBase.cpp @@ -30,7 +30,7 @@ void MaterialBase::SetParameterValue(const StringView& name, const Variant& valu const auto param = Params.Get(name); if (param) { - if (param->GetValue().Type == value.Type) + if (Variant::CanCast(value, param->GetValue().Type)) { param->SetValue(value); param->SetIsOverride(true); From 99ba59d02a50fe6c093dfde2696aa58073476af0 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Mon, 6 Jan 2025 15:58:09 -0600 Subject: [PATCH 49/69] Change to use static method for import path ui. --- Source/Editor/Utilities/Utils.cs | 22 +++++++++++++++++++ .../Editor/Windows/Assets/AnimationWindow.cs | 17 +++----------- .../Editor/Windows/Assets/AudioClipWindow.cs | 17 +++----------- .../Windows/Assets/CubeTextureWindow.cs | 17 +++----------- Source/Editor/Windows/Assets/ModelWindow.cs | 15 ++----------- .../Windows/Assets/SkinnedModelWindow.cs | 17 +++----------- .../Windows/Assets/SpriteAtlasWindow.cs | 17 +++----------- Source/Editor/Windows/Assets/TextureWindow.cs | 17 +++----------- 8 files changed, 42 insertions(+), 97 deletions(-) diff --git a/Source/Editor/Utilities/Utils.cs b/Source/Editor/Utilities/Utils.cs index 8d73abf4d..43d81ee1e 100644 --- a/Source/Editor/Utilities/Utils.cs +++ b/Source/Editor/Utilities/Utils.cs @@ -383,6 +383,28 @@ namespace FlaxEditor.Utilities File.Delete(file); } + /// + /// Creates an Import path ui that show the asset import path and adds a button to show the folder in the file system. + /// + /// The parent layout container. + /// The asset item to get the import path of. + public static void CreateImportPathUI(CustomEditors.LayoutElementsContainer parentLayout, Content.BinaryAssetItem assetItem) + { + assetItem.GetImportPath(out var path); + if (!string.IsNullOrEmpty(path)) + { + parentLayout.Space(5); + parentLayout.Label("Import Path:"); + var textBox = parentLayout.TextBox().TextBox; + textBox.TooltipText = "Path is not editable here."; + textBox.IsReadOnly = true; + textBox.Text = path; + parentLayout.Space(2); + var button = parentLayout.Button(Constants.ShowInExplorer).Button; + button.Clicked += () => FileSystem.ShowFileExplorer(Path.GetDirectoryName(path)); + } + } + /// /// Copies the directory. Supports subdirectories copy with files override option. /// diff --git a/Source/Editor/Windows/Assets/AnimationWindow.cs b/Source/Editor/Windows/Assets/AnimationWindow.cs index b03eae515..09127a818 100644 --- a/Source/Editor/Windows/Assets/AnimationWindow.cs +++ b/Source/Editor/Windows/Assets/AnimationWindow.cs @@ -210,20 +210,9 @@ namespace FlaxEditor.Windows.Assets var importSettingsField = typeof(PropertiesProxy).GetField("ImportSettings", BindingFlags.NonPublic | BindingFlags.Instance); var importSettingsValues = new ValueContainer(new ScriptMemberInfo(importSettingsField)) { proxy.ImportSettings }; group.Object(importSettingsValues); - - (proxy.Window.Item as BinaryAssetItem).GetImportPath(out var path); - if (!string.IsNullOrEmpty(path)) - { - layout.Space(5); - layout.Label("Import Path:"); - var textBox = layout.TextBox().TextBox; - textBox.TooltipText = "Path is not editable here."; - textBox.IsReadOnly = true; - textBox.Text = path; - layout.Space(2); - var button = layout.Button("Open Import Path in Explorer").Button; - button.Clicked += () => FileSystem.ShowFileExplorer(Path.GetDirectoryName(path)); - } + + // Creates the import path UI + Utilities.Utils.CreateImportPathUI(layout, proxy.Window.Item as BinaryAssetItem); layout.Space(5); var reimportButton = layout.Button("Reimport"); diff --git a/Source/Editor/Windows/Assets/AudioClipWindow.cs b/Source/Editor/Windows/Assets/AudioClipWindow.cs index e44a4dd4c..87638f8e0 100644 --- a/Source/Editor/Windows/Assets/AudioClipWindow.cs +++ b/Source/Editor/Windows/Assets/AudioClipWindow.cs @@ -100,20 +100,9 @@ namespace FlaxEditor.Windows.Assets } base.Initialize(layout); - - (window.Item as BinaryAssetItem).GetImportPath(out var path); - if (!string.IsNullOrEmpty(path)) - { - layout.Space(5); - layout.Label("Import Path:"); - var textBox = layout.TextBox().TextBox; - textBox.TooltipText = "Path is not editable here."; - textBox.IsReadOnly = true; - textBox.Text = path; - layout.Space(2); - var button = layout.Button("Open Import Path in Explorer").Button; - button.Clicked += () => FileSystem.ShowFileExplorer(Path.GetDirectoryName(path)); - } + + // Creates the import path UI + Utilities.Utils.CreateImportPathUI(layout, window.Item as BinaryAssetItem); layout.Space(10); var reimportButton = layout.Button("Reimport"); diff --git a/Source/Editor/Windows/Assets/CubeTextureWindow.cs b/Source/Editor/Windows/Assets/CubeTextureWindow.cs index 0efcc3fde..63c697ef2 100644 --- a/Source/Editor/Windows/Assets/CubeTextureWindow.cs +++ b/Source/Editor/Windows/Assets/CubeTextureWindow.cs @@ -53,20 +53,9 @@ namespace FlaxEditor.Windows.Assets } base.Initialize(layout); - - (window.Item as BinaryAssetItem).GetImportPath(out var path); - if (!string.IsNullOrEmpty(path)) - { - layout.Space(5); - layout.Label("Import Path:"); - var textBox = layout.TextBox().TextBox; - textBox.TooltipText = "Path is not editable here."; - textBox.IsReadOnly = true; - textBox.Text = path; - layout.Space(2); - var button = layout.Button("Open Import Path in Explorer").Button; - button.Clicked += () => FileSystem.ShowFileExplorer(Path.GetDirectoryName(path)); - } + + // Creates the import path UI + Utilities.Utils.CreateImportPathUI(layout, window.Item as BinaryAssetItem); layout.Space(10); var reimportButton = layout.Button("Reimport"); diff --git a/Source/Editor/Windows/Assets/ModelWindow.cs b/Source/Editor/Windows/Assets/ModelWindow.cs index 58ee67d67..3410db0b1 100644 --- a/Source/Editor/Windows/Assets/ModelWindow.cs +++ b/Source/Editor/Windows/Assets/ModelWindow.cs @@ -759,19 +759,8 @@ namespace FlaxEditor.Windows.Assets var importSettingsValues = new ValueContainer(new ScriptMemberInfo(importSettingsField)) { proxy.ImportSettings }; group.Object(importSettingsValues); - (proxy.Window.Item as BinaryAssetItem).GetImportPath(out var path); - if (!string.IsNullOrEmpty(path)) - { - layout.Space(5); - layout.Label("Import Path:"); - var textBox = layout.TextBox().TextBox; - textBox.TooltipText = "Path is not editable here."; - textBox.IsReadOnly = true; - textBox.Text = path; - layout.Space(2); - var button = layout.Button("Open Import Path in Explorer").Button; - button.Clicked += () => FileSystem.ShowFileExplorer(Path.GetDirectoryName(path)); - } + // Creates the import path UI + Utilities.Utils.CreateImportPathUI(layout, proxy.Window.Item as BinaryAssetItem); layout.Space(5); var reimportButton = layout.Button("Reimport"); diff --git a/Source/Editor/Windows/Assets/SkinnedModelWindow.cs b/Source/Editor/Windows/Assets/SkinnedModelWindow.cs index e2e1bf4da..a53e7a44f 100644 --- a/Source/Editor/Windows/Assets/SkinnedModelWindow.cs +++ b/Source/Editor/Windows/Assets/SkinnedModelWindow.cs @@ -1022,20 +1022,9 @@ namespace FlaxEditor.Windows.Assets var importSettingsField = typeof(ImportPropertiesProxy).GetField("ImportSettings", BindingFlags.NonPublic | BindingFlags.Instance); var importSettingsValues = new ValueContainer(new ScriptMemberInfo(importSettingsField)) { proxy.ImportSettings }; group.Object(importSettingsValues); - - (proxy.Window.Item as BinaryAssetItem).GetImportPath(out var path); - if (!string.IsNullOrEmpty(path)) - { - layout.Space(5); - layout.Label("Import Path:"); - var textBox = layout.TextBox().TextBox; - textBox.TooltipText = "Path is not editable here."; - textBox.IsReadOnly = true; - textBox.Text = path; - layout.Space(2); - var button = layout.Button("Open Import Path in Explorer").Button; - button.Clicked += () => FileSystem.ShowFileExplorer(Path.GetDirectoryName(path)); - } + + // Creates the import path UI + Utilities.Utils.CreateImportPathUI(layout, proxy.Window.Item as BinaryAssetItem); layout.Space(5); var reimportButton = layout.Button("Reimport"); diff --git a/Source/Editor/Windows/Assets/SpriteAtlasWindow.cs b/Source/Editor/Windows/Assets/SpriteAtlasWindow.cs index b220a6156..cbcecf1df 100644 --- a/Source/Editor/Windows/Assets/SpriteAtlasWindow.cs +++ b/Source/Editor/Windows/Assets/SpriteAtlasWindow.cs @@ -119,20 +119,9 @@ namespace FlaxEditor.Windows.Assets } base.Initialize(layout); - - (proxy._window.Item as BinaryAssetItem).GetImportPath(out var path); - if (!string.IsNullOrEmpty(path)) - { - layout.Space(5); - layout.Label("Import Path:"); - var textBox = layout.TextBox().TextBox; - textBox.TooltipText = "Path is not editable here."; - textBox.IsReadOnly = true; - textBox.Text = path; - layout.Space(2); - var button = layout.Button("Open Import Path in Explorer").Button; - button.Clicked += () => FileSystem.ShowFileExplorer(Path.GetDirectoryName(path)); - } + + // Creates the import path UI + Utilities.Utils.CreateImportPathUI(layout, proxy._window.Item as BinaryAssetItem); layout.Space(10); var reimportButton = layout.Button("Reimport"); diff --git a/Source/Editor/Windows/Assets/TextureWindow.cs b/Source/Editor/Windows/Assets/TextureWindow.cs index 3e1d436b3..43c499f6e 100644 --- a/Source/Editor/Windows/Assets/TextureWindow.cs +++ b/Source/Editor/Windows/Assets/TextureWindow.cs @@ -144,20 +144,9 @@ namespace FlaxEditor.Windows.Assets // Import settings base.Initialize(layout); - - (proxy._window.Item as BinaryAssetItem).GetImportPath(out var path); - if (!string.IsNullOrEmpty(path)) - { - layout.Space(5); - layout.Label("Import Path:"); - var textBox = layout.TextBox().TextBox; - textBox.TooltipText = "Path is not editable here."; - textBox.IsReadOnly = true; - textBox.Text = path; - layout.Space(2); - var button = layout.Button("Open Import Path in Explorer").Button; - button.Clicked += () => FileSystem.ShowFileExplorer(Path.GetDirectoryName(path)); - } + + // Creates the import path UI + Utilities.Utils.CreateImportPathUI(layout, proxy._window.Item as BinaryAssetItem); // Reimport layout.Space(10); From 12b98f2df103e2c8b207001db906b17f53311f00 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 6 Jan 2025 23:44:34 +0100 Subject: [PATCH 50/69] Migrate to `actions/upload-artifact@v4` https://github.blog/changelog/2024-04-16-deprecation-notice-v3-of-the-artifact-actions/ --- .github/workflows/cd.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 428dea933..405b78037 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -35,12 +35,12 @@ jobs: run: | .\PackageEditor.bat -arch=x64 -platform=Windows -deployOutput=Output - name: Upload - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Windows-Editor path: Output/Editor.zip - name: Upload - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Windows-EditorDebugSymbols path: Output/EditorDebugSymbols.zip @@ -68,7 +68,7 @@ jobs: run: | .\PackagePlatforms.bat -arch=x64 -platform=Windows -deployOutput=Output - name: Upload - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Windows-Game path: Output/Windows.zip @@ -101,7 +101,7 @@ jobs: run: | ./PackageEditor.sh -arch=x64 -platform=Linux -deployOutput=Output - name: Upload - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Linux-Editor path: Output/FlaxEditorLinux.zip @@ -132,7 +132,7 @@ jobs: run: | ./PackagePlatforms.sh -arch=x64 -platform=Linux -deployOutput=Output - name: Upload - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Linux-Game path: Output/Linux.zip @@ -162,7 +162,7 @@ jobs: run: | ./PackageEditor.command -arch=ARM64 -platform=Mac -deployOutput=Output - name: Upload - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Mac-Editor path: Output/FlaxEditorMac.zip @@ -190,7 +190,7 @@ jobs: run: | ./PackagePlatforms.command -arch=ARM64 -platform=Mac -deployOutput=Output - name: Upload - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Mac-Game path: Output/Mac.zip From 3f201c386320c13cab7eef34a3c671b2352f34b5 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 6 Jan 2025 23:53:27 +0100 Subject: [PATCH 51/69] Resave terrain material #3115 --- Content/Engine/DefaultTerrainMaterial.flax | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Content/Engine/DefaultTerrainMaterial.flax b/Content/Engine/DefaultTerrainMaterial.flax index 355158581..2f13023ee 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:cce61627c31b12d2d79abf59c485889044b4b9a803c0d2b7a988dc25906d6a35 -size 30264 +oid sha256:c03a9676ce8236d2770e64fb4ec8e039aa5cd3609fd32d35d802f5a1c35c798b +size 23658 From 13863344d26f90b041ac4c4fbb172ab443bfa322 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Tue, 7 Jan 2025 20:26:25 -0600 Subject: [PATCH 52/69] Warn if value is the wrong type for the animation graph parameter trying to be set. --- Source/Engine/Level/Actors/AnimatedModel.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Source/Engine/Level/Actors/AnimatedModel.cpp b/Source/Engine/Level/Actors/AnimatedModel.cpp index b09b76394..3d27dc9e8 100644 --- a/Source/Engine/Level/Actors/AnimatedModel.cpp +++ b/Source/Engine/Level/Actors/AnimatedModel.cpp @@ -292,7 +292,11 @@ void AnimatedModel::SetParameterValue(const StringView& name, const Variant& val { if (param.Name == name) { - param.Value = value; + if (Variant::CanCast(value, param.Value.Type)) + param.Value = value; + else + LOG(Warning, "Animation Graph parameter '{0}' in AnimatedModel {1} is type '{2}' and not type '{3}'.", String(name), ToString(), param.Value.Type, value.Type); + return; } } From e87bb2325bd63386169fa29069598c999709c364 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Tue, 7 Jan 2025 20:43:57 -0600 Subject: [PATCH 53/69] Standardize spacing for import path ui in assets. add import path ui to model prefab. --- .../CustomEditors/Dedicated/ModelPrefabEditor.cs | 3 +++ Source/Editor/Utilities/Utils.cs | 16 ++++++++++++++-- Source/Editor/Windows/Assets/AudioClipWindow.cs | 2 +- .../Editor/Windows/Assets/CubeTextureWindow.cs | 2 +- .../Editor/Windows/Assets/SpriteAtlasWindow.cs | 2 +- Source/Editor/Windows/Assets/TextureWindow.cs | 2 +- Source/Engine/Level/Scripts/ModelPrefab.h | 2 +- 7 files changed, 22 insertions(+), 7 deletions(-) diff --git a/Source/Editor/CustomEditors/Dedicated/ModelPrefabEditor.cs b/Source/Editor/CustomEditors/Dedicated/ModelPrefabEditor.cs index fbb817768..3df5cb72e 100644 --- a/Source/Editor/CustomEditors/Dedicated/ModelPrefabEditor.cs +++ b/Source/Editor/CustomEditors/Dedicated/ModelPrefabEditor.cs @@ -53,6 +53,9 @@ public class ModelPrefabEditor : GenericEditor } } + // Creates the import path UI + Utilities.Utils.CreateImportPathUI(layout, modelPrefab.ImportPath, false); + var button = layout.Button("Reimport", "Reimports the source asset as prefab."); _reimportButton = button.Button; _reimportButton.Clicked += OnReimport; diff --git a/Source/Editor/Utilities/Utils.cs b/Source/Editor/Utilities/Utils.cs index 43d81ee1e..db824857a 100644 --- a/Source/Editor/Utilities/Utils.cs +++ b/Source/Editor/Utilities/Utils.cs @@ -391,10 +391,22 @@ namespace FlaxEditor.Utilities public static void CreateImportPathUI(CustomEditors.LayoutElementsContainer parentLayout, Content.BinaryAssetItem assetItem) { assetItem.GetImportPath(out var path); + CreateImportPathUI(parentLayout, path); + } + + /// + /// Creates an Import path ui that show the import path and adds a button to show the folder in the file system. + /// + /// The parent layout container. + /// The import path. + /// Whether to use an initial layout space of 5 for separation. + public static void CreateImportPathUI(CustomEditors.LayoutElementsContainer parentLayout, string path, bool useInitialSpacing = true) + { if (!string.IsNullOrEmpty(path)) { - parentLayout.Space(5); - parentLayout.Label("Import Path:"); + if (useInitialSpacing) + parentLayout.Space(5); + parentLayout.Label("Import Path:").Label.TooltipText = "Source asset path (can be relative or absolute to the project)"; var textBox = parentLayout.TextBox().TextBox; textBox.TooltipText = "Path is not editable here."; textBox.IsReadOnly = true; diff --git a/Source/Editor/Windows/Assets/AudioClipWindow.cs b/Source/Editor/Windows/Assets/AudioClipWindow.cs index 87638f8e0..35072620b 100644 --- a/Source/Editor/Windows/Assets/AudioClipWindow.cs +++ b/Source/Editor/Windows/Assets/AudioClipWindow.cs @@ -104,7 +104,7 @@ namespace FlaxEditor.Windows.Assets // Creates the import path UI Utilities.Utils.CreateImportPathUI(layout, window.Item as BinaryAssetItem); - layout.Space(10); + layout.Space(5); var reimportButton = layout.Button("Reimport"); reimportButton.Button.Clicked += () => ((PropertiesProxy)Values[0]).Reimport(); } diff --git a/Source/Editor/Windows/Assets/CubeTextureWindow.cs b/Source/Editor/Windows/Assets/CubeTextureWindow.cs index 63c697ef2..960d806d2 100644 --- a/Source/Editor/Windows/Assets/CubeTextureWindow.cs +++ b/Source/Editor/Windows/Assets/CubeTextureWindow.cs @@ -57,7 +57,7 @@ namespace FlaxEditor.Windows.Assets // Creates the import path UI Utilities.Utils.CreateImportPathUI(layout, window.Item as BinaryAssetItem); - layout.Space(10); + layout.Space(5); var reimportButton = layout.Button("Reimport"); reimportButton.Button.Clicked += () => ((PropertiesProxy)Values[0]).Reimport(); } diff --git a/Source/Editor/Windows/Assets/SpriteAtlasWindow.cs b/Source/Editor/Windows/Assets/SpriteAtlasWindow.cs index cbcecf1df..167a86f41 100644 --- a/Source/Editor/Windows/Assets/SpriteAtlasWindow.cs +++ b/Source/Editor/Windows/Assets/SpriteAtlasWindow.cs @@ -123,7 +123,7 @@ namespace FlaxEditor.Windows.Assets // Creates the import path UI Utilities.Utils.CreateImportPathUI(layout, proxy._window.Item as BinaryAssetItem); - layout.Space(10); + layout.Space(5); var reimportButton = layout.Button("Reimport"); reimportButton.Button.Clicked += () => ((PropertiesProxy)Values[0]).Reimport(); } diff --git a/Source/Editor/Windows/Assets/TextureWindow.cs b/Source/Editor/Windows/Assets/TextureWindow.cs index 43c499f6e..894c0d352 100644 --- a/Source/Editor/Windows/Assets/TextureWindow.cs +++ b/Source/Editor/Windows/Assets/TextureWindow.cs @@ -149,7 +149,7 @@ namespace FlaxEditor.Windows.Assets Utilities.Utils.CreateImportPathUI(layout, proxy._window.Item as BinaryAssetItem); // Reimport - layout.Space(10); + layout.Space(5); var reimportButton = layout.Button("Reimport"); reimportButton.Button.Clicked += () => ((ImportPropertiesProxy)Values[0]).Reimport(); } diff --git a/Source/Engine/Level/Scripts/ModelPrefab.h b/Source/Engine/Level/Scripts/ModelPrefab.h index 0adf0edea..fd6b66097 100644 --- a/Source/Engine/Level/Scripts/ModelPrefab.h +++ b/Source/Engine/Level/Scripts/ModelPrefab.h @@ -19,7 +19,7 @@ API_CLASS(Attributes="HideInEditor") class FLAXENGINE_API ModelPrefab : public S /// /// Source model file path (absolute or relative to the project). /// - API_FIELD(Attributes="ReadOnly") String ImportPath; + API_FIELD(Attributes="ReadOnly, HideInEditor") String ImportPath; /// /// Model file import settings. From ccbcab979342bc1d24c96fc6b877199e76c4a560 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Wed, 8 Jan 2025 22:11:21 -0600 Subject: [PATCH 54/69] Fix android build on .net9 and use DotNet version that is found by build tool path. --- Source/Editor/Cooker/Steps/DeployDataStep.cpp | 39 +++++++++++++++---- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/Source/Editor/Cooker/Steps/DeployDataStep.cpp b/Source/Editor/Cooker/Steps/DeployDataStep.cpp index 6b1a6829e..38a7bcbb6 100644 --- a/Source/Editor/Cooker/Steps/DeployDataStep.cpp +++ b/Source/Editor/Cooker/Steps/DeployDataStep.cpp @@ -214,6 +214,30 @@ bool DeployDataStep::Perform(CookingData& data) FileSystem::NormalizePath(srcDotnet); LOG(Info, "Using .NET Runtime {} at {}", TEXT("Host"), srcDotnet); + // Get major Version + Array pathParts; + srcDotnet.Split('/', pathParts); + String version; + for (int i = 0; i < pathParts.Count(); i++) + { + if (pathParts[i] == TEXT("runtimes")) + { + Array versionParts; + pathParts[i - 1].Split('.', versionParts); + const String majorVersion = versionParts[0].TrimTrailing(); + uint32 versionNum; + StringUtils::Parse(*majorVersion, majorVersion.Length(), &versionNum); + if (versionNum < GAME_BUILD_DOTNET_RUNTIME_MAX_VER || versionNum > GAME_BUILD_DOTNET_RUNTIME_MIN_VER) // Check for major part + version = majorVersion; + } + } + + if (version.IsEmpty()) + { + data.Error(TEXT("Failed to find supported .NET version for the current host platform.")); + return true; + } + // Deploy runtime files const Char* corlibPrivateName = TEXT("System.Private.CoreLib.dll"); const bool srcDotnetFromEngine = srcDotnet.Contains(TEXT("Source/Platforms")); @@ -226,14 +250,14 @@ bool DeployDataStep::Perform(CookingData& data) { // AOT runtime files inside Engine Platform folder packFolder /= TEXT("Dotnet"); - dstDotnetLibs /= TEXT("lib/net8.0"); - srcDotnetLibs = packFolder / TEXT("lib/net8.0"); + dstDotnetLibs /= String::Format(TEXT("lib/net{}.0"), version); + srcDotnetLibs = packFolder / String::Format(TEXT("lib/net{}.0"), version); } else { // Runtime files inside Dotnet SDK folder but placed for AOT - dstDotnetLibs /= TEXT("lib/net8.0"); - srcDotnetLibs /= TEXT("../lib/net8.0"); + dstDotnetLibs /= String::Format(TEXT("lib/net{}.0"), version); + srcDotnetLibs /= String::Format(TEXT("../lib/net{}.0"), version); } } else @@ -241,14 +265,14 @@ bool DeployDataStep::Perform(CookingData& data) if (srcDotnetFromEngine) { // Runtime files inside Engine Platform folder - dstDotnetLibs /= TEXT("lib/net8.0"); - srcDotnetLibs /= TEXT("lib/net8.0"); + dstDotnetLibs /= String::Format(TEXT("lib/net{}.0"), version); + srcDotnetLibs /= String::Format(TEXT("lib/net{}.0"), version); } else { // Runtime files inside Dotnet SDK folder dstDotnetLibs /= TEXT("shared/Microsoft.NETCore.App"); - srcDotnetLibs /= TEXT("../lib/net8.0"); + srcDotnetLibs /= String::Format(TEXT("../lib/net{}.0"), version); } } LOG(Info, "Copying .NET files from {} to {}", packFolder, dstDotnet); @@ -273,6 +297,7 @@ bool DeployDataStep::Perform(CookingData& data) DEPLOY_NATIVE_FILE("libmonosgen-2.0.so"); DEPLOY_NATIVE_FILE("libSystem.IO.Compression.Native.so"); DEPLOY_NATIVE_FILE("libSystem.Native.so"); + DEPLOY_NATIVE_FILE("libSystem.Globalization.Native.so"); DEPLOY_NATIVE_FILE("libSystem.Security.Cryptography.Native.Android.so"); break; case BuildPlatform::iOSARM64: From 77c48c037ec17a5208211553c1c4829b3fa54486 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Thu, 9 Jan 2025 19:19:30 -0600 Subject: [PATCH 55/69] Add `No parameters` UI to particle effect and animated model --- Source/Editor/CustomEditors/Dedicated/AnimatedModelEditor.cs | 3 +++ Source/Editor/CustomEditors/Dedicated/ParticleEffectEditor.cs | 3 +++ 2 files changed, 6 insertions(+) diff --git a/Source/Editor/CustomEditors/Dedicated/AnimatedModelEditor.cs b/Source/Editor/CustomEditors/Dedicated/AnimatedModelEditor.cs index 5d06b4a94..f48e1b9c1 100644 --- a/Source/Editor/CustomEditors/Dedicated/AnimatedModelEditor.cs +++ b/Source/Editor/CustomEditors/Dedicated/AnimatedModelEditor.cs @@ -1,6 +1,7 @@ // Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. using System; +using System.Linq; using FlaxEditor.CustomEditors.Elements; using FlaxEditor.Surface; using FlaxEngine; @@ -35,6 +36,8 @@ namespace FlaxEditor.CustomEditors.Dedicated (instance, parameter, tag) => ((AnimatedModel)instance).GetParameterValue(parameter.Identifier), (instance, value, parameter, tag) => ((AnimatedModel)instance).SetParameterValue(parameter.Identifier, value), Values); + if (!parameters.Any()) + group.Label("No parameters", TextAlignment.Center); _parametersAdded = true; } } diff --git a/Source/Editor/CustomEditors/Dedicated/ParticleEffectEditor.cs b/Source/Editor/CustomEditors/Dedicated/ParticleEffectEditor.cs index c207f8949..980ad5fa4 100644 --- a/Source/Editor/CustomEditors/Dedicated/ParticleEffectEditor.cs +++ b/Source/Editor/CustomEditors/Dedicated/ParticleEffectEditor.cs @@ -117,6 +117,9 @@ namespace FlaxEditor.CustomEditors.Dedicated var data = SurfaceUtils.InitGraphParameters(parametersGroup); SurfaceUtils.DisplayGraphParameters(group, data, ParameterGet, ParameterSet, Values, ParameterDefaultValue); } + + if (!parameters.Any()) + groups.Label("No parameters", TextAlignment.Center); } /// From cb7fc6141db783b04d500f3cebc5f8328323a68e Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Thu, 9 Jan 2025 19:40:36 -0600 Subject: [PATCH 56/69] Fix crash in multiblend 2d node when first created. --- .../Surface/Archetypes/Animation.MultiBlend.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Source/Editor/Surface/Archetypes/Animation.MultiBlend.cs b/Source/Editor/Surface/Archetypes/Animation.MultiBlend.cs index b0d7169cc..94e74528c 100644 --- a/Source/Editor/Surface/Archetypes/Animation.MultiBlend.cs +++ b/Source/Editor/Surface/Archetypes/Animation.MultiBlend.cs @@ -1205,13 +1205,16 @@ namespace FlaxEditor.Surface.Archetypes // Highlight selected blend point var style = Style.Current; var selectedIndex = _selectedAnimation.SelectedIndex; - if (selectedIndex != -1 && (ContainsFocus || IsMouseOver)) + if (selectedIndex != -1 && selectedIndex < _editor.BlendPoints.Count && (ContainsFocus || IsMouseOver)) { var point = _editor.BlendPoints[selectedIndex]; - var highlightColor = point.IsMouseDown ? style.SelectionBorder : style.BackgroundSelected; - Render2D.PushTint(ref highlightColor); - Render2D.DrawTriangles(_selectedTriangles, _selectedColors); - Render2D.PopTint(); + if (point != null) + { + var highlightColor = point.IsMouseDown ? style.SelectionBorder : style.BackgroundSelected; + Render2D.PushTint(ref highlightColor); + Render2D.DrawTriangles(_selectedTriangles, _selectedColors); + Render2D.PopTint(); + } } } From 2260236fa6c1b5cf79a1bb38af2aed4ad3e21a28 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Thu, 9 Jan 2025 20:55:30 -0600 Subject: [PATCH 57/69] Fix CPU profiler crash on conversion to ulong. --- Source/Editor/Windows/Profiler/CPU.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Editor/Windows/Profiler/CPU.cs b/Source/Editor/Windows/Profiler/CPU.cs index 8c6ff5e78..ca3c9963f 100644 --- a/Source/Editor/Windows/Profiler/CPU.cs +++ b/Source/Editor/Windows/Profiler/CPU.cs @@ -175,7 +175,7 @@ namespace FlaxEditor.Windows.Profiler private string FormatCellBytes(object x) { - return Utilities.Utils.FormatBytesCount((ulong)x); + return Utilities.Utils.FormatBytesCount(Convert.ToUInt64(x)); } /// From e2df7a1e85e7f743fdf9f781ac205b1bfd5f09f7 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Sun, 12 Jan 2025 15:07:43 -0600 Subject: [PATCH 58/69] Handle linked values in `Float3Editor` --- .../CustomEditors/Editors/Vector3Editor.cs | 50 +++++++++++++------ 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/Source/Editor/CustomEditors/Editors/Vector3Editor.cs b/Source/Editor/CustomEditors/Editors/Vector3Editor.cs index 9e01e8323..38e380550 100644 --- a/Source/Editor/CustomEditors/Editors/Vector3Editor.cs +++ b/Source/Editor/CustomEditors/Editors/Vector3Editor.cs @@ -228,7 +228,6 @@ namespace FlaxEditor.CustomEditors.Editors // Handle Sliding if (AllowSlidingForDifferentValues && (isSliding || _slidingEnded)) { - // TODO: handle linked values Float3 average = Float3.Zero; for (int i = 0; i < Values.Count; i++) { @@ -251,12 +250,24 @@ namespace FlaxEditor.CustomEditors.Editors for (int i = 0; i < Values.Count; i++) { var v = Values[i]; - if (v is Vector3 asVector3) - v = asVector3 + new Vector3(_valueChanged == ValueChanged.X ? newValue.X : 0, _valueChanged == ValueChanged.Y ? newValue.Y : 0, _valueChanged == ValueChanged.Z ? newValue.Z : 0); - else if (v is Float3 asFloat3) - v = asFloat3 + new Float3(_valueChanged == ValueChanged.X ? newValue.X : 0, _valueChanged == ValueChanged.Y ? newValue.Y : 0, _valueChanged == ValueChanged.Z ? newValue.Z : 0); - else if (v is Double3 asDouble3) - v = asDouble3 + new Double3(_valueChanged == ValueChanged.X ? newValue.X : 0, _valueChanged == ValueChanged.Y ? newValue.Y : 0, _valueChanged == ValueChanged.Z ? newValue.Z : 0); + if (LinkValues) + { + if (v is Vector3 asVector3) + v = asVector3 + new Vector3(newValue.X, newValue.Y, newValue.Z); + else if (v is Float3 asFloat3) + v = asFloat3 + new Float3(newValue.X, newValue.Y, newValue.Z); + else if (v is Double3 asDouble3) + v = asDouble3 + new Double3(newValue.X, newValue.Y, newValue.Z); + } + else + { + if (v is Vector3 asVector3) + v = asVector3 + new Vector3(_valueChanged == ValueChanged.X ? newValue.X : 0, _valueChanged == ValueChanged.Y ? newValue.Y : 0, _valueChanged == ValueChanged.Z ? newValue.Z : 0); + else if (v is Float3 asFloat3) + v = asFloat3 + new Float3(_valueChanged == ValueChanged.X ? newValue.X : 0, _valueChanged == ValueChanged.Y ? newValue.Y : 0, _valueChanged == ValueChanged.Z ? newValue.Z : 0); + else if (v is Double3 asDouble3) + v = asDouble3 + new Double3(_valueChanged == ValueChanged.X ? newValue.X : 0, _valueChanged == ValueChanged.Y ? newValue.Y : 0, _valueChanged == ValueChanged.Z ? newValue.Z : 0); + } newObjects[i] = v; } @@ -267,16 +278,27 @@ namespace FlaxEditor.CustomEditors.Editors } else { - // TODO: handle linked values for (int i = 0; i < Values.Count; i++) { object v = Values[i]; - if (v is Vector3 asVector3) - v = new Vector3(_valueChanged == ValueChanged.X ? xValue : asVector3.X, _valueChanged == ValueChanged.Y ? yValue : asVector3.Y, _valueChanged == ValueChanged.Z ? zValue : asVector3.Z); - else if (v is Float3 asFloat3) - v = new Float3(_valueChanged == ValueChanged.X ? xValue : asFloat3.X, _valueChanged == ValueChanged.Y ? yValue : asFloat3.Y, _valueChanged == ValueChanged.Z ? zValue : asFloat3.Z); - else if (v is Double3 asDouble3) - v = new Double3(_valueChanged == ValueChanged.X ? xValue : asDouble3.X, _valueChanged == ValueChanged.Y ? yValue : asDouble3.Y, _valueChanged == ValueChanged.Z ? zValue : asDouble3.Z); + if (LinkValues) + { + if (v is Vector3 asVector3) + v = asVector3 + new Vector3(xValue, yValue, zValue); + else if (v is Float3 asFloat3) + v = asFloat3 + new Float3(xValue, yValue, zValue); + else if (v is Double3 asDouble3) + v = asDouble3 + new Double3(xValue, yValue, zValue); + } + else + { + if (v is Vector3 asVector3) + v = new Vector3(_valueChanged == ValueChanged.X ? xValue : asVector3.X, _valueChanged == ValueChanged.Y ? yValue : asVector3.Y, _valueChanged == ValueChanged.Z ? zValue : asVector3.Z); + else if (v is Float3 asFloat3) + v = new Float3(_valueChanged == ValueChanged.X ? xValue : asFloat3.X, _valueChanged == ValueChanged.Y ? yValue : asFloat3.Y, _valueChanged == ValueChanged.Z ? zValue : asFloat3.Z); + else if (v is Double3 asDouble3) + v = new Double3(_valueChanged == ValueChanged.X ? xValue : asDouble3.X, _valueChanged == ValueChanged.Y ? yValue : asDouble3.Y, _valueChanged == ValueChanged.Z ? zValue : asDouble3.Z); + } newObjects[i] = v; } From ca995093b6078a5d87f233602cfcd1eb7b0f664e Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Sun, 12 Jan 2025 16:50:16 -0600 Subject: [PATCH 59/69] Add .aab bundling for Android. --- .../Platform/Android/AndroidPlatformTools.cpp | 55 ++++++++++++++----- Source/Editor/Windows/GameCookerWindow.cs | 38 +++++++++++++ 2 files changed, 79 insertions(+), 14 deletions(-) diff --git a/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp b/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp index eb5469b47..b81166346 100644 --- a/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp +++ b/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp @@ -364,27 +364,54 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data) } #endif const bool distributionPackage = buildSettings->ForDistribution || data.Configuration == BuildConfiguration::Release; + if (data.CustomDefines.Contains(String(TEXT("BuildAAB")))) { - CreateProcessSettings procSettings; - procSettings.FileName = String::Format(TEXT("\"{0}\" {1}"), data.OriginalOutputPath / gradlew, distributionPackage ? TEXT("assemble") : TEXT("assembleDebug")); - procSettings.WorkingDirectory = data.OriginalOutputPath; - const int32 result = Platform::CreateProcess(procSettings); - if (result != 0) + // .aab { - data.Error(String::Format(TEXT("Failed to build Gradle project into package (result code: {0}). See log for more info."), result)); + CreateProcessSettings procSettings; + procSettings.FileName = String::Format(TEXT("\"{0}\" {1}"), data.OriginalOutputPath / gradlew, distributionPackage ? TEXT(":app:bundle") : TEXT(":app:bundleDebug")); + procSettings.WorkingDirectory = data.OriginalOutputPath; + const int32 result = Platform::CreateProcess(procSettings); + if (result != 0) + { + data.Error(String::Format(TEXT("Failed to build Gradle project into package (result code: {0}). See log for more info."), result)); + return true; + } + } + // Copy result package + const String aab = data.OriginalOutputPath / (distributionPackage ? TEXT("app/build/outputs/apk/release/app-release.aab") : TEXT("app/build/outputs/bundle/debug/app-debug.aab")); + const String outputAab = data.OriginalOutputPath / EditorUtilities::GetOutputName() + TEXT(".aab"); + if (FileSystem::CopyFile(outputAab, aab)) + { + LOG(Error, "Failed to copy package from {0} to {1}", aab, outputAab); return true; } + LOG(Info, "Output Android application package: {0} (size: {1} MB)", outputAab, FileSystem::GetFileSize(outputAab) / 1024 / 1024); } - - // Copy result package - const String apk = data.OriginalOutputPath / (distributionPackage ? TEXT("app/build/outputs/apk/release/app-release-unsigned.apk") : TEXT("app/build/outputs/apk/debug/app-debug.apk")); - const String outputApk = data.OriginalOutputPath / EditorUtilities::GetOutputName() + TEXT(".apk"); - if (FileSystem::CopyFile(outputApk, apk)) + else { - LOG(Error, "Failed to copy package from {0} to {1}", apk, outputApk); - return true; + // .apk + { + CreateProcessSettings procSettings; + procSettings.FileName = String::Format(TEXT("\"{0}\" {1}"), data.OriginalOutputPath / gradlew, distributionPackage ? TEXT("assemble") : TEXT("assembleDebug")); + procSettings.WorkingDirectory = data.OriginalOutputPath; + const int32 result = Platform::CreateProcess(procSettings); + if (result != 0) + { + data.Error(String::Format(TEXT("Failed to build Gradle project into package (result code: {0}). See log for more info."), result)); + return true; + } + } + // Copy result package + const String apk = data.OriginalOutputPath / (distributionPackage ? TEXT("app/build/outputs/apk/release/app-release-unsigned.apk") : TEXT("app/build/outputs/apk/debug/app-debug.apk")); + const String outputApk = data.OriginalOutputPath / EditorUtilities::GetOutputName() + TEXT(".apk"); + if (FileSystem::CopyFile(outputApk, apk)) + { + LOG(Error, "Failed to copy package from {0} to {1}", apk, outputApk); + return true; + } + LOG(Info, "Output Android application package: {0} (size: {1} MB)", outputApk, FileSystem::GetFileSize(outputApk) / 1024 / 1024); } - LOG(Info, "Output Android application package: {0} (size: {1} MB)", outputApk, FileSystem::GetFileSize(outputApk) / 1024 / 1024); return false; } diff --git a/Source/Editor/Windows/GameCookerWindow.cs b/Source/Editor/Windows/GameCookerWindow.cs index cbe211eca..e4a3a47e8 100644 --- a/Source/Editor/Windows/GameCookerWindow.cs +++ b/Source/Editor/Windows/GameCookerWindow.cs @@ -233,6 +233,44 @@ namespace FlaxEditor.Windows class Android : Platform { protected override BuildPlatform BuildPlatform => BuildPlatform.AndroidARM64; + private bool _buildAAB = false; + + [EditorOrder(21), Tooltip("Build an android app bundle instead of an APK"), EditorDisplay(null, "Build .aab")] + public bool BuildAAB + { + get => _buildAAB; + set + { + _buildAAB = value; + if (value) + { + + var newDefines = new List(); + if (CustomDefines != null) + newDefines.AddRange(CustomDefines); + newDefines.Add("BuildAAB"); + CustomDefines = newDefines.ToArray(); + } + else + { + if (CustomDefines != null) + { + if (CustomDefines.Contains("BuildAAB")) + { + var newDefines = new List(); + foreach (var define in CustomDefines) + { + if (!define.Equals("BuildAAB", StringComparison.Ordinal)) + { + newDefines.Add(define); + } + } + CustomDefines = newDefines.ToArray(); + } + } + } + } + } } class Switch : Platform From 01d1dbba6cc5dbe3ee0df110e085c14f72b32604 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Sun, 12 Jan 2025 16:57:19 -0600 Subject: [PATCH 60/69] Add aditional check for if custom define of BuildAAB already exists. --- Source/Editor/Windows/GameCookerWindow.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/Editor/Windows/GameCookerWindow.cs b/Source/Editor/Windows/GameCookerWindow.cs index e4a3a47e8..89b56f05d 100644 --- a/Source/Editor/Windows/GameCookerWindow.cs +++ b/Source/Editor/Windows/GameCookerWindow.cs @@ -244,7 +244,8 @@ namespace FlaxEditor.Windows _buildAAB = value; if (value) { - + if (CustomDefines != null && CustomDefines.Contains("BuildAAB")) + return; var newDefines = new List(); if (CustomDefines != null) newDefines.AddRange(CustomDefines); From 7ac2376231a3e3f71dfc96f70f7ec93e3c0262d5 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sun, 12 Jan 2025 23:57:52 +0100 Subject: [PATCH 61/69] Simplify code --- Source/Engine/Render2D/Render2D.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Source/Engine/Render2D/Render2D.cpp b/Source/Engine/Render2D/Render2D.cpp index 942cb9e0b..a51d16ecc 100644 --- a/Source/Engine/Render2D/Render2D.cpp +++ b/Source/Engine/Render2D/Render2D.cpp @@ -1377,22 +1377,26 @@ void Render2D::DrawText(Font* font, const StringView& text, const TextRange& tex FORCE_INLINE bool NeedAlphaWithTint(const Color& color) { - return (color.A * TintLayersStack.Peek().A) < 1.0f; + const float tint = TintLayersStack.Peek().A; + return color.A * tint < 1.0f; } FORCE_INLINE bool NeedAlphaWithTint(const Color& color1, const Color& color2) { - return (color1.A * TintLayersStack.Peek().A) < 1.0f || (color2.A * TintLayersStack.Peek().A) < 1.0f; + const float tint = TintLayersStack.Peek().A; + return color1.A * tint < 1.0f || color2.A * tint < 1.0f; } FORCE_INLINE bool NeedAlphaWithTint(const Color& color1, const Color& color2, const Color& color3) { - return (color1.A * TintLayersStack.Peek().A) < 1.0f || (color2.A * TintLayersStack.Peek().A) < 1.0f || (color3.A * TintLayersStack.Peek().A) < 1.0f; + const float tint = TintLayersStack.Peek().A; + return color1.A * tint < 1.0f || color2.A * tint < 1.0f || color3.A * tint < 1.0f; } FORCE_INLINE bool NeedAlphaWithTint(const Color& color1, const Color& color2, const Color& color3, const Color& color4) { - return (color1.A * TintLayersStack.Peek().A) < 1.0f || (color2.A * TintLayersStack.Peek().A) < 1.0f || (color3.A * TintLayersStack.Peek().A) < 1.0f || (color4.A * TintLayersStack.Peek().A) < 1.0f; + const float tint = TintLayersStack.Peek().A; + return color1.A * tint < 1.0f || color2.A * tint < 1.0f || color3.A * tint < 1.0f || color4.A * tint < 1.0f; } void Render2D::FillRectangle(const Rectangle& rect, const Color& color) From f274639e940ec68258ec6bd250c9c06c0bc6e6cd Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Sun, 12 Jan 2025 17:17:59 -0600 Subject: [PATCH 62/69] Fix path bug. --- Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp b/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp index b81166346..69e1a591b 100644 --- a/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp +++ b/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp @@ -379,7 +379,7 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data) } } // Copy result package - const String aab = data.OriginalOutputPath / (distributionPackage ? TEXT("app/build/outputs/apk/release/app-release.aab") : TEXT("app/build/outputs/bundle/debug/app-debug.aab")); + const String aab = data.OriginalOutputPath / (distributionPackage ? TEXT("app/build/outputs/bundle/release/app-release.aab") : TEXT("app/build/outputs/bundle/debug/app-debug.aab")); const String outputAab = data.OriginalOutputPath / EditorUtilities::GetOutputName() + TEXT(".aab"); if (FileSystem::CopyFile(outputAab, aab)) { From 30ea3bc9c25cd3b684a99d70d8fde629d54f0185 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Mon, 13 Jan 2025 07:16:31 -0600 Subject: [PATCH 63/69] Add check for empty array and use `IsInRange` for version check. --- Source/Editor/Cooker/Steps/DeployDataStep.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Source/Editor/Cooker/Steps/DeployDataStep.cpp b/Source/Editor/Cooker/Steps/DeployDataStep.cpp index 38a7bcbb6..489321d99 100644 --- a/Source/Editor/Cooker/Steps/DeployDataStep.cpp +++ b/Source/Editor/Cooker/Steps/DeployDataStep.cpp @@ -224,11 +224,14 @@ bool DeployDataStep::Perform(CookingData& data) { Array versionParts; pathParts[i - 1].Split('.', versionParts); - const String majorVersion = versionParts[0].TrimTrailing(); - uint32 versionNum; - StringUtils::Parse(*majorVersion, majorVersion.Length(), &versionNum); - if (versionNum < GAME_BUILD_DOTNET_RUNTIME_MAX_VER || versionNum > GAME_BUILD_DOTNET_RUNTIME_MIN_VER) // Check for major part - version = majorVersion; + if (!versionParts.IsEmpty()) + { + const String majorVersion = versionParts[0].TrimTrailing(); + int32 versionNum; + StringUtils::Parse(*majorVersion, majorVersion.Length(), &versionNum); + if (Math::IsInRange(versionNum, GAME_BUILD_DOTNET_RUNTIME_MIN_VER, GAME_BUILD_DOTNET_RUNTIME_MAX_VER)) // Check for major part + version = majorVersion; + } } } From 563f0b9ab45b34ec817c34e1358345a042cecc56 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Mon, 13 Jan 2025 07:24:50 -0600 Subject: [PATCH 64/69] Move Build .aab to Android platform settings and make it side-by-side --- .../Platform/Android/AndroidPlatformTools.cpp | 47 +++++++++---------- Source/Editor/Windows/GameCookerWindow.cs | 39 --------------- .../Android/AndroidPlatformSettings.h | 6 +++ 3 files changed, 28 insertions(+), 64 deletions(-) diff --git a/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp b/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp index 69e1a591b..0e46be17b 100644 --- a/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp +++ b/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp @@ -364,7 +364,8 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data) } #endif const bool distributionPackage = buildSettings->ForDistribution || data.Configuration == BuildConfiguration::Release; - if (data.CustomDefines.Contains(String(TEXT("BuildAAB")))) + + if (platformSettings->BuildAAB) { // .aab { @@ -375,43 +376,39 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data) if (result != 0) { data.Error(String::Format(TEXT("Failed to build Gradle project into package (result code: {0}). See log for more info."), result)); - return true; } } // Copy result package const String aab = data.OriginalOutputPath / (distributionPackage ? TEXT("app/build/outputs/bundle/release/app-release.aab") : TEXT("app/build/outputs/bundle/debug/app-debug.aab")); const String outputAab = data.OriginalOutputPath / EditorUtilities::GetOutputName() + TEXT(".aab"); if (FileSystem::CopyFile(outputAab, aab)) - { LOG(Error, "Failed to copy package from {0} to {1}", aab, outputAab); - return true; - } - LOG(Info, "Output Android application package: {0} (size: {1} MB)", outputAab, FileSystem::GetFileSize(outputAab) / 1024 / 1024); + else + LOG(Info, "Output AAB Android application package: {0} (size: {1} MB)", outputAab, FileSystem::GetFileSize(outputAab) / 1024 / 1024); } - else + + // .apk { - // .apk + CreateProcessSettings procSettings; + procSettings.FileName = String::Format(TEXT("\"{0}\" {1}"), data.OriginalOutputPath / gradlew, distributionPackage ? TEXT("assemble") : TEXT("assembleDebug")); + procSettings.WorkingDirectory = data.OriginalOutputPath; + const int32 result = Platform::CreateProcess(procSettings); + if (result != 0) { - CreateProcessSettings procSettings; - procSettings.FileName = String::Format(TEXT("\"{0}\" {1}"), data.OriginalOutputPath / gradlew, distributionPackage ? TEXT("assemble") : TEXT("assembleDebug")); - procSettings.WorkingDirectory = data.OriginalOutputPath; - const int32 result = Platform::CreateProcess(procSettings); - if (result != 0) - { - data.Error(String::Format(TEXT("Failed to build Gradle project into package (result code: {0}). See log for more info."), result)); - return true; - } - } - // Copy result package - const String apk = data.OriginalOutputPath / (distributionPackage ? TEXT("app/build/outputs/apk/release/app-release-unsigned.apk") : TEXT("app/build/outputs/apk/debug/app-debug.apk")); - const String outputApk = data.OriginalOutputPath / EditorUtilities::GetOutputName() + TEXT(".apk"); - if (FileSystem::CopyFile(outputApk, apk)) - { - LOG(Error, "Failed to copy package from {0} to {1}", apk, outputApk); + data.Error(String::Format(TEXT("Failed to build Gradle project into package (result code: {0}). See log for more info."), result)); return true; } - LOG(Info, "Output Android application package: {0} (size: {1} MB)", outputApk, FileSystem::GetFileSize(outputApk) / 1024 / 1024); } + // Copy result package + const String apk = data.OriginalOutputPath / (distributionPackage ? TEXT("app/build/outputs/apk/release/app-release-unsigned.apk") : TEXT("app/build/outputs/apk/debug/app-debug.apk")); + const String outputApk = data.OriginalOutputPath / EditorUtilities::GetOutputName() + TEXT(".apk"); + if (FileSystem::CopyFile(outputApk, apk)) + { + LOG(Error, "Failed to copy package from {0} to {1}", apk, outputApk); + return true; + } + LOG(Info, "Output Android APK application package: {0} (size: {1} MB)", outputApk, FileSystem::GetFileSize(outputApk) / 1024 / 1024); + return false; } diff --git a/Source/Editor/Windows/GameCookerWindow.cs b/Source/Editor/Windows/GameCookerWindow.cs index 89b56f05d..cbe211eca 100644 --- a/Source/Editor/Windows/GameCookerWindow.cs +++ b/Source/Editor/Windows/GameCookerWindow.cs @@ -233,45 +233,6 @@ namespace FlaxEditor.Windows class Android : Platform { protected override BuildPlatform BuildPlatform => BuildPlatform.AndroidARM64; - private bool _buildAAB = false; - - [EditorOrder(21), Tooltip("Build an android app bundle instead of an APK"), EditorDisplay(null, "Build .aab")] - public bool BuildAAB - { - get => _buildAAB; - set - { - _buildAAB = value; - if (value) - { - if (CustomDefines != null && CustomDefines.Contains("BuildAAB")) - return; - var newDefines = new List(); - if (CustomDefines != null) - newDefines.AddRange(CustomDefines); - newDefines.Add("BuildAAB"); - CustomDefines = newDefines.ToArray(); - } - else - { - if (CustomDefines != null) - { - if (CustomDefines.Contains("BuildAAB")) - { - var newDefines = new List(); - foreach (var define in CustomDefines) - { - if (!define.Equals("BuildAAB", StringComparison.Ordinal)) - { - newDefines.Add(define); - } - } - CustomDefines = newDefines.ToArray(); - } - } - } - } - } } class Switch : Platform diff --git a/Source/Engine/Platform/Android/AndroidPlatformSettings.h b/Source/Engine/Platform/Android/AndroidPlatformSettings.h index c42270a05..e66f1bda1 100644 --- a/Source/Engine/Platform/Android/AndroidPlatformSettings.h +++ b/Source/Engine/Platform/Android/AndroidPlatformSettings.h @@ -108,6 +108,12 @@ API_CLASS(sealed, Namespace="FlaxEditor.Content.Settings") class FLAXENGINE_API API_FIELD(Attributes="EditorOrder(500), EditorDisplay(\"General\")") TextureQuality TexturesQuality = TextureQuality::ASTC_Medium; + /// + /// Whether to build android app bundle (aab) side by side with apk. + /// + API_FIELD(Attributes="EditorOrder(500), EditorDisplay(\"General\", \"Build .aab\")") + bool BuildAAB; + /// /// Custom icon texture to use for the application (overrides the default one). /// From 55fa372197445bb761d5a68ed6be16d4aacf2303 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Mon, 13 Jan 2025 07:30:01 -0600 Subject: [PATCH 65/69] re-add returns to aab --- .../Platform/Android/AndroidPlatformTools.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp b/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp index 0e46be17b..9e4f18b2c 100644 --- a/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp +++ b/Source/Editor/Cooker/Platform/Android/AndroidPlatformTools.cpp @@ -375,16 +375,19 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data) const int32 result = Platform::CreateProcess(procSettings); if (result != 0) { - data.Error(String::Format(TEXT("Failed to build Gradle project into package (result code: {0}). See log for more info."), result)); + data.Error(String::Format(TEXT("Failed to build Gradle project into .aab package (result code: {0}). See log for more info."), result)); + return true; } } // Copy result package const String aab = data.OriginalOutputPath / (distributionPackage ? TEXT("app/build/outputs/bundle/release/app-release.aab") : TEXT("app/build/outputs/bundle/debug/app-debug.aab")); const String outputAab = data.OriginalOutputPath / EditorUtilities::GetOutputName() + TEXT(".aab"); if (FileSystem::CopyFile(outputAab, aab)) - LOG(Error, "Failed to copy package from {0} to {1}", aab, outputAab); - else - LOG(Info, "Output AAB Android application package: {0} (size: {1} MB)", outputAab, FileSystem::GetFileSize(outputAab) / 1024 / 1024); + { + LOG(Error, "Failed to copy .aab package from {0} to {1}", aab, outputAab); + return true; + } + LOG(Info, "Output Android AAB application package: {0} (size: {1} MB)", outputAab, FileSystem::GetFileSize(outputAab) / 1024 / 1024); } // .apk @@ -395,7 +398,7 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data) const int32 result = Platform::CreateProcess(procSettings); if (result != 0) { - data.Error(String::Format(TEXT("Failed to build Gradle project into package (result code: {0}). See log for more info."), result)); + data.Error(String::Format(TEXT("Failed to build Gradle project into .apk package (result code: {0}). See log for more info."), result)); return true; } } @@ -404,7 +407,7 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data) const String outputApk = data.OriginalOutputPath / EditorUtilities::GetOutputName() + TEXT(".apk"); if (FileSystem::CopyFile(outputApk, apk)) { - LOG(Error, "Failed to copy package from {0} to {1}", apk, outputApk); + LOG(Error, "Failed to copy .apk package from {0} to {1}", apk, outputApk); return true; } LOG(Info, "Output Android APK application package: {0} (size: {1} MB)", outputApk, FileSystem::GetFileSize(outputApk) / 1024 / 1024); From 90316dfa52995453a67c4830a48e84a69dcb94c2 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 13 Jan 2025 15:46:35 +0100 Subject: [PATCH 66/69] Minor code changes to PR --- .../TextureTool/TextureTool.DirectXTex.cpp | 20 +++++-------------- .../Tools/TextureTool/TextureTool.stb.cpp | 4 ++-- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp b/Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp index 683bcc292..37b914e9c 100644 --- a/Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp +++ b/Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp @@ -827,10 +827,8 @@ bool TextureTool::ImportTextureDirectXTex(ImageType type, const StringView& path result = TransformImage(currentImage->GetImages(), currentImage->GetImageCount(), currentImage->GetMetadata(), [&](DirectX::XMVECTOR* outPixels, const DirectX::XMVECTOR* inPixels, size_t w, size_t y) { - static const DirectX::XMVECTORU32 s_selecty = { { { DirectX::XM_SELECT_0, DirectX::XM_SELECT_1, DirectX::XM_SELECT_0, DirectX::XM_SELECT_0 } } }; - + const DirectX::XMVECTORU32 s_selecty = { { { DirectX::XM_SELECT_0, DirectX::XM_SELECT_1, DirectX::XM_SELECT_0, DirectX::XM_SELECT_0 } } }; UNREFERENCED_PARAMETER(y); - for (size_t j = 0; j < w; ++j) { const DirectX::XMVECTOR value = inPixels[j]; @@ -853,10 +851,8 @@ bool TextureTool::ImportTextureDirectXTex(ImageType type, const StringView& path result = TransformImage(currentImage->GetImages(), currentImage->GetImageCount(), currentImage->GetMetadata(), [&](DirectX::XMVECTOR* outPixels, const DirectX::XMVECTOR* inPixels, size_t w, size_t y) { - static const DirectX::XMVECTORU32 s_selectx = { { { DirectX::XM_SELECT_1, DirectX::XM_SELECT_0, DirectX::XM_SELECT_0, DirectX::XM_SELECT_0 } } }; - + const DirectX::XMVECTORU32 s_selectx = { { { DirectX::XM_SELECT_1, DirectX::XM_SELECT_0, DirectX::XM_SELECT_0, DirectX::XM_SELECT_0 } } }; UNREFERENCED_PARAMETER(y); - for (size_t j = 0; j < w; ++j) { const DirectX::XMVECTOR value = inPixels[j]; @@ -879,10 +875,8 @@ bool TextureTool::ImportTextureDirectXTex(ImageType type, const StringView& path result = TransformImage(currentImage->GetImages(), currentImage->GetImageCount(), currentImage->GetMetadata(), [&](DirectX::XMVECTOR* outPixels, const DirectX::XMVECTOR* inPixels, size_t w, size_t y) { - static const DirectX::XMVECTORU32 s_selectz = { { { DirectX::XM_SELECT_0, DirectX::XM_SELECT_0, DirectX::XM_SELECT_1, DirectX::XM_SELECT_0 } } }; - + const DirectX::XMVECTORU32 s_selectz = { { { DirectX::XM_SELECT_0, DirectX::XM_SELECT_0, DirectX::XM_SELECT_1, DirectX::XM_SELECT_0 } } }; UNREFERENCED_PARAMETER(y); - for (size_t j = 0; j < w; ++j) { const DirectX::XMVECTOR value = inPixels[j]; @@ -905,10 +899,8 @@ bool TextureTool::ImportTextureDirectXTex(ImageType type, const StringView& path result = TransformImage(currentImage->GetImages(), currentImage->GetImageCount(), currentImage->GetMetadata(), [&](DirectX::XMVECTOR* outPixels, const DirectX::XMVECTOR* inPixels, size_t w, size_t y) { - static const DirectX::XMVECTORU32 s_selectw = { { { DirectX::XM_SELECT_0, DirectX::XM_SELECT_0, DirectX::XM_SELECT_0, DirectX::XM_SELECT_1 } } }; - + const DirectX::XMVECTORU32 s_selectw = { { { DirectX::XM_SELECT_0, DirectX::XM_SELECT_0, DirectX::XM_SELECT_0, DirectX::XM_SELECT_1 } } }; UNREFERENCED_PARAMETER(y); - for (size_t j = 0; j < w; ++j) { const DirectX::XMVECTOR value = inPixels[j]; @@ -932,10 +924,8 @@ bool TextureTool::ImportTextureDirectXTex(ImageType type, const StringView& path result = TransformImage(currentImage->GetImages(), currentImage->GetImageCount(), currentImage->GetMetadata(), [&](DirectX::XMVECTOR* outPixels, const DirectX::XMVECTOR* inPixels, size_t w, size_t y) { - static const DirectX::XMVECTORU32 s_selectz = { { { DirectX::XM_SELECT_0, DirectX::XM_SELECT_0, DirectX::XM_SELECT_1, DirectX::XM_SELECT_0 } } }; - + const DirectX::XMVECTORU32 s_selectz = { { { DirectX::XM_SELECT_0, DirectX::XM_SELECT_0, DirectX::XM_SELECT_1, DirectX::XM_SELECT_0 } } }; UNREFERENCED_PARAMETER(y); - for (size_t j = 0; j < w; ++j) { const DirectX::XMVECTOR value = inPixels[j]; diff --git a/Source/Engine/Tools/TextureTool/TextureTool.stb.cpp b/Source/Engine/Tools/TextureTool/TextureTool.stb.cpp index 8ca585c32..0bb2deec2 100644 --- a/Source/Engine/Tools/TextureTool/TextureTool.stb.cpp +++ b/Source/Engine/Tools/TextureTool/TextureTool.stb.cpp @@ -541,10 +541,10 @@ bool TextureTool::ImportTextureStb(ImageType type, const StringView& path, Textu // TODO: impl this LOG(Warning, "Option 'Flip X' is not supported"); } - if (options.InvertGreenChannel) + if (options.InvertRedChannel || options.InvertGreenChannel || options.InvertBlueChannel || options.InvertAlphaChannel) { // TODO: impl this - LOG(Warning, "Option 'Invert Green Channel' is not supported"); + LOG(Warning, "Option to invert channels is not supported"); } if (options.ReconstructZChannel) { From 3796b0ccaef0aeb429313fdfb70b4cb147a03b3b Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 13 Jan 2025 16:07:47 +0100 Subject: [PATCH 67/69] Revert #3117 and do it different way as some types can be valid even if different thus use internal parameter setter for type validation --- Source/Engine/Content/Assets/MaterialBase.cpp | 15 ++++----------- Source/Engine/Content/Assets/MaterialBase.h | 3 +-- .../Engine/Graphics/Materials/MaterialParams.cpp | 7 ++++++- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/Source/Engine/Content/Assets/MaterialBase.cpp b/Source/Engine/Content/Assets/MaterialBase.cpp index 9751f86d4..9e980687a 100644 --- a/Source/Engine/Content/Assets/MaterialBase.cpp +++ b/Source/Engine/Content/Assets/MaterialBase.cpp @@ -25,24 +25,17 @@ Variant MaterialBase::GetParameterValue(const StringView& name) return Variant::Null; } -void MaterialBase::SetParameterValue(const StringView& name, const Variant& value, bool warnIfMissing, bool warnIfWrongType) +void MaterialBase::SetParameterValue(const StringView& name, const Variant& value, bool warnIfMissing) { const auto param = Params.Get(name); if (param) { - if (Variant::CanCast(value, param->GetValue().Type)) - { - param->SetValue(value); - param->SetIsOverride(true); - } - else if (warnIfWrongType) - { - LOG(Warning, "Material parameter '{0}' in material {1} is type '{2}' and not type '{3}'.", String(name), ToString(), param->GetValue().Type, value.Type); - } + param->SetValue(value); + param->SetIsOverride(true); } else if (warnIfMissing) { - LOG(Warning, "Missing material parameter '{0}' in material {1}", String(name), ToString()); + LOG(Warning, "Missing material parameter '{0}' in material {1}", name, ToString()); } } diff --git a/Source/Engine/Content/Assets/MaterialBase.h b/Source/Engine/Content/Assets/MaterialBase.h index 3d6487772..ec5681e27 100644 --- a/Source/Engine/Content/Assets/MaterialBase.h +++ b/Source/Engine/Content/Assets/MaterialBase.h @@ -66,8 +66,7 @@ public: /// The parameter name. /// The value to set. /// True to warn if parameter is missing, otherwise will do nothing. - /// True to warn if value is wrong type, otherwise will do nothing. - API_FUNCTION() void SetParameterValue(const StringView& name, const Variant& value, bool warnIfMissing = true, bool warnIfWrongType = true); + API_FUNCTION() void SetParameterValue(const StringView& name, const Variant& value, bool warnIfMissing = true); /// /// Creates the virtual material instance of this material which allows to override any material parameters. diff --git a/Source/Engine/Graphics/Materials/MaterialParams.cpp b/Source/Engine/Graphics/Materials/MaterialParams.cpp index 30064222b..7329ef2ff 100644 --- a/Source/Engine/Graphics/Materials/MaterialParams.cpp +++ b/Source/Engine/Graphics/Materials/MaterialParams.cpp @@ -214,9 +214,11 @@ void MaterialParameter::SetValue(const Variant& value) break; case VariantType::Object: _asAsset = Cast(value.AsObject); + invalidType = _asAsset == nullptr && value.AsObject != nullptr; break; case VariantType::Asset: _asAsset = Cast(value.AsAsset); + invalidType = _asAsset == nullptr && value.AsAsset != nullptr; break; default: invalidType = true; @@ -239,6 +241,7 @@ void MaterialParameter::SetValue(const Variant& value) break; case VariantType::Object: _asGPUTexture = Cast(value.AsObject); + invalidType = _asGPUTexture == nullptr && value.AsObject != nullptr; break; default: invalidType = true; @@ -258,9 +261,11 @@ void MaterialParameter::SetValue(const Variant& value) break; case VariantType::Object: _asAsset = Cast(value.AsObject); + invalidType = _asAsset == nullptr && value.AsObject != nullptr; break; case VariantType::Asset: _asAsset = Cast(value.AsAsset); + invalidType = _asAsset == nullptr && value.AsAsset != nullptr; break; default: invalidType = true; @@ -273,7 +278,7 @@ void MaterialParameter::SetValue(const Variant& value) } if (invalidType) { - LOG(Error, "Invalid material parameter value type {0} to set (param type: {1})", value.Type, ScriptingEnum::ToString(_type)); + LOG(Error, "Invalid material parameter value '{}' of type '{}' to set (expected type: {})", value.ToString(), value.Type, ScriptingEnum::ToString(_type)); } } From 7fcf8c2d4c5e6f95d0fe4e6bc6b9ab2e1cc1ac49 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 13 Jan 2025 16:08:43 +0100 Subject: [PATCH 68/69] Improve #3138 to pass over setting value to null and via proper cast so value type stays the same --- Source/Engine/Core/Types/Variant.cpp | 27 ++++++++++++++++++++ Source/Engine/Level/Actors/AnimatedModel.cpp | 7 ++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/Source/Engine/Core/Types/Variant.cpp b/Source/Engine/Core/Types/Variant.cpp index 49c72bfad..daa8c6ebb 100644 --- a/Source/Engine/Core/Types/Variant.cpp +++ b/Source/Engine/Core/Types/Variant.cpp @@ -3439,6 +3439,16 @@ bool Variant::CanCast(const Variant& v, const VariantType& to) default: return false; } + case VariantType::Null: + switch (to.Type) + { + case VariantType::Asset: + case VariantType::ManagedObject: + case VariantType::Object: + return true; + default: + return false; + } default: return false; } @@ -3912,6 +3922,23 @@ Variant Variant::Cast(const Variant& v, const VariantType& to) default: ; } break; + case VariantType::Null: + switch (to.Type) + { + case VariantType::Asset: + return Variant((Asset*)nullptr); + case VariantType::Object: + return Variant((ScriptingObject*)nullptr); + case VariantType::ManagedObject: + { + Variant result; + result.SetType(VariantType(VariantType::ManagedObject)); + result.MANAGED_GC_HANDLE = 0; + return result; + } + default: + return false; + } default: ; } LOG(Error, "Cannot cast Variant from {0} to {1}", v.Type, to); diff --git a/Source/Engine/Level/Actors/AnimatedModel.cpp b/Source/Engine/Level/Actors/AnimatedModel.cpp index 3d27dc9e8..464d9aeda 100644 --- a/Source/Engine/Level/Actors/AnimatedModel.cpp +++ b/Source/Engine/Level/Actors/AnimatedModel.cpp @@ -292,11 +292,12 @@ void AnimatedModel::SetParameterValue(const StringView& name, const Variant& val { if (param.Name == name) { - if (Variant::CanCast(value, param.Value.Type)) + if (param.Value.Type == value.Type) param.Value = value; + else if (Variant::CanCast(value, param.Value.Type)) + param.Value = Variant::Cast(value, param.Value.Type); else - LOG(Warning, "Animation Graph parameter '{0}' in AnimatedModel {1} is type '{2}' and not type '{3}'.", String(name), ToString(), param.Value.Type, value.Type); - + LOG(Warning, "Animation Graph parameter '{0}' in AnimatedModel {1} is type '{2}' and not type '{3}'.", name, ToString(), param.Value.Type, value.Type); return; } } From 4add5dcf494b8eac139c221ed776e995d84e6b8d Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 13 Jan 2025 17:31:34 +0100 Subject: [PATCH 69/69] Add missing default value and fix doc comment #3150 --- Source/Engine/Platform/Android/AndroidPlatformSettings.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Engine/Platform/Android/AndroidPlatformSettings.h b/Source/Engine/Platform/Android/AndroidPlatformSettings.h index e66f1bda1..9a035f1ea 100644 --- a/Source/Engine/Platform/Android/AndroidPlatformSettings.h +++ b/Source/Engine/Platform/Android/AndroidPlatformSettings.h @@ -109,10 +109,10 @@ API_CLASS(sealed, Namespace="FlaxEditor.Content.Settings") class FLAXENGINE_API TextureQuality TexturesQuality = TextureQuality::ASTC_Medium; /// - /// Whether to build android app bundle (aab) side by side with apk. + /// Whether to build Android App Bundle (aab) side by side with apk. /// API_FIELD(Attributes="EditorOrder(500), EditorDisplay(\"General\", \"Build .aab\")") - bool BuildAAB; + bool BuildAAB = true; /// /// Custom icon texture to use for the application (overrides the default one).