diff --git a/Source/Editor/Viewport/EditorViewport.cs b/Source/Editor/Viewport/EditorViewport.cs index 7e1c3d887..555e0cb7a 100644 --- a/Source/Editor/Viewport/EditorViewport.cs +++ b/Source/Editor/Viewport/EditorViewport.cs @@ -654,16 +654,20 @@ namespace FlaxEditor.Viewport task.Begin += OnRenderBegin; } - private void OrientViewport(ref Quaternion orientation) + /// + /// Orients the viewport. + /// + /// The orientation. + protected virtual void OrientViewport(ref Quaternion orientation) { - if (Editor.Instance.SceneEditing.HasSthSelected) + if (ViewportCamera is FPSCamera fpsCamera) { - ((FPSCamera)ViewportCamera).ShowActors(Editor.Instance.Windows.EditWin.Viewport.TransformGizmo.SelectedParents, ref orientation); + var pos = Vector3.Zero + Vector3.Backward * orientation * 2000.0f; + fpsCamera.MoveViewport(pos, orientation); } else { - var pos = new Vector3(0.0f) + Vector3.Backward * orientation * 2000.0f; - ((FPSCamera)ViewportCamera).MoveViewport(pos, orientation); + ViewportCamera.SetArcBallView(orientation, Vector3.Zero, 2000.0f); } } @@ -1009,7 +1013,7 @@ namespace FlaxEditor.Viewport // Check if update mouse Vector2 size = Size; - var options = Editor.Instance.Options.Options.Input; + var options = Editor.Instance.Options.Options; if (_isControllingMouse) { var rmbWheel = false; @@ -1033,7 +1037,7 @@ namespace FlaxEditor.Viewport if (rmbWheel) { float step = 4.0f; - _wheelMovementChangeDeltaSum += _input.MouseWheelDelta * Editor.Instance.Options.Options.Viewport.MouseWheelSensitivity; + _wheelMovementChangeDeltaSum += _input.MouseWheelDelta * options.Viewport.MouseWheelSensitivity; int camValueIndex = -1; for (int i = 0; i < EditorViewportCameraSpeedValues.Length; i++) { @@ -1061,27 +1065,27 @@ namespace FlaxEditor.Viewport // Get input movement Vector3 moveDelta = Vector3.Zero; - if (win.GetKey(options.Forward.Key)) + if (win.GetKey(options.Input.Forward.Key)) { moveDelta += Vector3.Forward; } - if (win.GetKey(options.Backward.Key)) + if (win.GetKey(options.Input.Backward.Key)) { moveDelta += Vector3.Backward; } - if (win.GetKey(options.Right.Key)) + if (win.GetKey(options.Input.Right.Key)) { moveDelta += Vector3.Right; } - if (win.GetKey(options.Left.Key)) + if (win.GetKey(options.Input.Left.Key)) { moveDelta += Vector3.Left; } - if (win.GetKey(options.Up.Key)) + if (win.GetKey(options.Input.Up.Key)) { moveDelta += Vector3.Up; } - if (win.GetKey(options.Down.Key)) + if (win.GetKey(options.Input.Down.Key)) { moveDelta += Vector3.Down; } @@ -1152,7 +1156,7 @@ namespace FlaxEditor.Viewport { var scroll = _input.MouseWheelDelta; if (scroll > Mathf.Epsilon || scroll < -Mathf.Epsilon) - _orthoSize -= scroll * Editor.Instance.Options.Options.Viewport.MouseWheelSensitivity * 0.2f * _orthoSize; + _orthoSize -= scroll * options.Viewport.MouseWheelSensitivity * 0.2f * _orthoSize; } } else diff --git a/Source/Editor/Viewport/MainEditorGizmoViewport.cs b/Source/Editor/Viewport/MainEditorGizmoViewport.cs index e79b01313..64ee739df 100644 --- a/Source/Editor/Viewport/MainEditorGizmoViewport.cs +++ b/Source/Editor/Viewport/MainEditorGizmoViewport.cs @@ -9,6 +9,7 @@ using FlaxEditor.GUI.Drag; using FlaxEditor.SceneGraph; using FlaxEditor.SceneGraph.Actors; using FlaxEditor.Scripting; +using FlaxEditor.Viewport.Cameras; using FlaxEditor.Viewport.Widgets; using FlaxEditor.Windows; using FlaxEngine; @@ -698,6 +699,17 @@ namespace FlaxEditor.Viewport } } + /// + protected override void OrientViewport(ref Quaternion orientation) + { + if (TransformGizmo.SelectedParents.Count != 0) + { + ((FPSCamera)ViewportCamera).ShowActors(TransformGizmo.SelectedParents, ref orientation); + } + + base.OrientViewport(ref orientation); + } + /// protected override void OnLeftMouseButtonUp() { diff --git a/Source/Editor/Viewport/PrefabWindowViewport.cs b/Source/Editor/Viewport/PrefabWindowViewport.cs index a9ee39b8c..1b66b8c95 100644 --- a/Source/Editor/Viewport/PrefabWindowViewport.cs +++ b/Source/Editor/Viewport/PrefabWindowViewport.cs @@ -849,6 +849,17 @@ namespace FlaxEditor.Viewport Spawn(actor, ref hitLocation); } + /// + protected override void OrientViewport(ref Quaternion orientation) + { + if (TransformGizmo.SelectedParents.Count != 0) + { + ((FPSCamera)ViewportCamera).ShowActors(TransformGizmo.SelectedParents, ref orientation); + } + + base.OrientViewport(ref orientation); + } + /// public override DragDropEffect OnDragDrop(ref Vector2 location, DragData data) { diff --git a/Source/Editor/Viewport/Previews/TexturePreview.cs b/Source/Editor/Viewport/Previews/TexturePreview.cs index 5e1024609..62e19430a 100644 --- a/Source/Editor/Viewport/Previews/TexturePreview.cs +++ b/Source/Editor/Viewport/Previews/TexturePreview.cs @@ -13,6 +13,7 @@ namespace FlaxEditor.Viewport.Previews /// Base class for texture previews. Draws a surface in the UI and supports view moving/zooming. /// /// + [HideInEditor] public abstract class TexturePreviewBase : ContainerControl { private Rectangle _textureRect; diff --git a/Source/Editor/Windows/Assets/JsonAssetWindow.cs b/Source/Editor/Windows/Assets/JsonAssetWindow.cs index da463c501..779c8cc4e 100644 --- a/Source/Editor/Windows/Assets/JsonAssetWindow.cs +++ b/Source/Editor/Windows/Assets/JsonAssetWindow.cs @@ -18,6 +18,7 @@ namespace FlaxEditor.Windows.Assets private readonly CustomEditorPresenter _presenter; private readonly ToolStripButton _saveButton; private object _object; + private bool _isRegisteredForScriptsReload; /// public JsonAssetWindow(Editor editor, AssetItem item) @@ -43,7 +44,6 @@ namespace FlaxEditor.Windows.Assets private void OnScriptsReloadBegin() { Close(); - ScriptsBuilder.ScriptsReloadBegin -= OnScriptsReloadBegin; } /// @@ -83,8 +83,11 @@ namespace FlaxEditor.Windows.Assets ClearEditedFlag(); // Auto-close on scripting reload if json asset is from game scripts (it might be reloaded) - if (_object != null && FlaxEngine.Scripting.IsTypeFromGameScripts(_object.GetType())) + if (_object != null && FlaxEngine.Scripting.IsTypeFromGameScripts(_object.GetType()) && !_isRegisteredForScriptsReload) + { + _isRegisteredForScriptsReload = true; ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin; + } base.OnAssetLoaded(); } @@ -98,5 +101,17 @@ namespace FlaxEditor.Windows.Assets base.OnItemReimported(item); } + + /// + public override void OnDestroy() + { + if (_isRegisteredForScriptsReload) + { + _isRegisteredForScriptsReload = false; + ScriptsBuilder.ScriptsReloadBegin -= OnScriptsReloadBegin; + } + + base.OnDestroy(); + } } } diff --git a/Source/Editor/Windows/DebugLogWindow.cs b/Source/Editor/Windows/DebugLogWindow.cs index 560e507eb..7ffe5c923 100644 --- a/Source/Editor/Windows/DebugLogWindow.cs +++ b/Source/Editor/Windows/DebugLogWindow.cs @@ -333,8 +333,9 @@ namespace FlaxEditor.Windows AutoWidth = true, AutoHeight = true, Margin = new Margin(4), + VerticalAlignment = TextAlignment.Near, + HorizontalAlignment = TextAlignment.Near, Offsets = Margin.Zero, - AnchorPreset = AnchorPresets.StretchAll, }; // Entries panel diff --git a/Source/Engine/Content/BinaryAsset.cpp b/Source/Engine/Content/BinaryAsset.cpp index 1dbc672f2..baa065698 100644 --- a/Source/Engine/Content/BinaryAsset.cpp +++ b/Source/Engine/Content/BinaryAsset.cpp @@ -1,6 +1,7 @@ // Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. #include "BinaryAsset.h" +#include "Cache/AssetsCache.h" #include "Storage/ContentStorageManager.h" #include "Loading/Tasks/LoadAssetDataTask.h" #include "Engine/ContentImporters/AssetsImportingManager.h" @@ -303,9 +304,13 @@ bool BinaryAsset::SaveAsset(const StringView& path, AssetInitData& data, bool si bool BinaryAsset::SaveToAsset(const StringView& path, AssetInitData& data, bool silentMode) { + // Ensure path is in a valid format + String pathNorm(path); + FileSystem::NormalizePath(pathNorm); + // Find target storage container and the asset - auto storage = ContentStorageManager::TryGetStorage(path); - auto asset = Content::GetAsset(path); + auto storage = ContentStorageManager::TryGetStorage(pathNorm); + auto asset = Content::GetAsset(pathNorm); auto binaryAsset = dynamic_cast(asset); if (asset && !binaryAsset) { @@ -351,8 +356,8 @@ bool BinaryAsset::SaveToAsset(const StringView& path, AssetInitData& data, bool } else { - ASSERT(path.HasChars()); - result = FlaxStorage::Create(path, data, silentMode); + ASSERT(pathNorm.HasChars()); + result = FlaxStorage::Create(pathNorm, data, silentMode); } if (binaryAsset) binaryAsset->_isSaving = false; diff --git a/Source/Engine/Core/Math/Quaternion.cs b/Source/Engine/Core/Math/Quaternion.cs index 125b5b36c..684fb26b4 100644 --- a/Source/Engine/Core/Math/Quaternion.cs +++ b/Source/Engine/Core/Math/Quaternion.cs @@ -697,6 +697,27 @@ namespace FlaxEngine return result; } + /// + /// Calculates the orientation from the direction vector. + /// + /// The direction vector (normalized). + /// The orientation. + public static Quaternion FromDirection(Vector3 direction) + { + Quaternion orientation; + if (Vector3.Dot(direction, Vector3.Up) >= 0.999f) + { + orientation = RotationAxis(Vector3.Left, Mathf.PiOverTwo); + } + else + { + Vector3 right = Vector3.Cross(direction, Vector3.Up); + Vector3 up = Vector3.Cross(right, direction); + orientation = LookRotation(direction, up); + } + return orientation; + } + /// /// Performs a linear interpolation between two quaternions. /// diff --git a/Source/Engine/Level/Level.cpp b/Source/Engine/Level/Level.cpp index 8b8d4ae07..613427d9f 100644 --- a/Source/Engine/Level/Level.cpp +++ b/Source/Engine/Level/Level.cpp @@ -496,14 +496,8 @@ public: // - load scenes (from temporary files) // Note: we don't want to override original scene files - // If no scene loaded just reload scripting - if (!Level::IsAnySceneLoaded()) - { - // Reload scripting - LOG(Info, "No scenes loaded, performing fast scripts reload"); - Scripting::Reload(false); - return false; - } + LOG(Info, "Scripts reloading start"); + const auto startTime = DateTime::NowUTC(); // Cache data struct SceneData @@ -538,8 +532,6 @@ public: scenes[i].Init(Level::Scenes[i]); // Fire event - LOG(Info, "Scripts reloading start"); - const auto startTime = DateTime::NowUTC(); Level::ScriptsReloadStart(); // Save scenes (to memory) @@ -566,9 +558,10 @@ public: Scripting::Reload(); // Restore scenes (from memory) - LOG(Info, "Loading temporary scenes"); for (int32 i = 0; i < scenesCount; i++) { + LOG(Info, "Restoring scene {0}", scenes[i].Name); + // Parse json const auto& sceneData = scenes[i].Data; ISerializable::SerializeDocument document; @@ -590,8 +583,9 @@ public: scenes.Resize(0); // Initialize scenes (will link references and create managed objects using new assembly) - LOG(Info, "Prepare scene objects"); + if (Level::Scenes.HasItems()) { + LOG(Info, "Prepare scene objects"); SceneBeginData beginData; for (int32 i = 0; i < Level::Scenes.Count(); i++) { @@ -601,8 +595,7 @@ public: } // Fire event - const auto endTime = DateTime::NowUTC(); - LOG(Info, "Scripts reloading end. Total time: {0}ms", static_cast((endTime - startTime).GetTotalMilliseconds())); + LOG(Info, "Scripts reloading end. Total time: {0}ms", static_cast((DateTime::NowUTC() - startTime).GetTotalMilliseconds())); Level::ScriptsReloadEnd(); return false; diff --git a/Source/Engine/UI/GUI/Common/Label.cs b/Source/Engine/UI/GUI/Common/Label.cs index d549a9d85..196bbb2b6 100644 --- a/Source/Engine/UI/GUI/Common/Label.cs +++ b/Source/Engine/UI/GUI/Common/Label.cs @@ -77,7 +77,19 @@ namespace FlaxEngine.GUI public FontReference Font { get => _font; - set => _font = value; + set + { + if (_font != value) + { + _font = value; + + if (_autoWidth || _autoHeight || _autoFitText) + { + _textSize = Vector2.Zero; + PerformLayout(); + } + } + } } /// diff --git a/Source/Engine/UI/GUI/Margin.cs b/Source/Engine/UI/GUI/Margin.cs index 40dab7093..01c0ac3ab 100644 --- a/Source/Engine/UI/GUI/Margin.cs +++ b/Source/Engine/UI/GUI/Margin.cs @@ -47,7 +47,12 @@ namespace FlaxEngine.GUI public float Bottom; /// - /// Gets the margin's total size. Cumulative margin size. + /// Gets the margin's location (Left, Top). + /// + public Vector2 Location => new Vector2(Left, Top); + + /// + /// Gets the margin's total size. Cumulative margin size (Left + Right, Top + Bottom). /// public Vector2 Size => new Vector2(Left + Right, Top + Bottom); diff --git a/Source/Engine/UI/GUI/Panels/HorizontalPanel.cs b/Source/Engine/UI/GUI/Panels/HorizontalPanel.cs index d7b54a835..4ff92834d 100644 --- a/Source/Engine/UI/GUI/Panels/HorizontalPanel.cs +++ b/Source/Engine/UI/GUI/Panels/HorizontalPanel.cs @@ -25,7 +25,7 @@ namespace FlaxEngine.GUI for (int i = 0; i < _children.Count; i++) { Control c = _children[i]; - if (c.Visible) + if (c.Visible && Mathf.IsZero(c.AnchorMin.Y) && Mathf.IsZero(c.AnchorMax.Y)) { c.Height = h; } diff --git a/Source/Engine/UI/GUI/Panels/VerticalPanel.cs b/Source/Engine/UI/GUI/Panels/VerticalPanel.cs index 2c821bd3f..b3e51fb86 100644 --- a/Source/Engine/UI/GUI/Panels/VerticalPanel.cs +++ b/Source/Engine/UI/GUI/Panels/VerticalPanel.cs @@ -25,7 +25,7 @@ namespace FlaxEngine.GUI for (int i = 0; i < _children.Count; i++) { Control c = _children[i]; - if (c.Visible) + if (c.Visible && Mathf.IsZero(c.AnchorMin.X) && Mathf.IsZero(c.AnchorMax.X)) { c.Width = w; } diff --git a/Source/Engine/UI/UICanvas.cs b/Source/Engine/UI/UICanvas.cs index cbd554775..4030b66b9 100644 --- a/Source/Engine/UI/UICanvas.cs +++ b/Source/Engine/UI/UICanvas.cs @@ -306,16 +306,13 @@ namespace FlaxEngine { var view = _editorTask.View; var transform = Transform; - var cameraPosition = view.Position; - var cameraDirection = view.Direction; - var up = Vector3.Up; Matrix.Translation(_guiRoot.Width * -0.5f, _guiRoot.Height * -0.5f, 0, out var m1); Matrix.Scaling(ref transform.Scale, out var m2); Matrix.Multiply(ref m1, ref m2, out var m3); Quaternion.Euler(180, 180, 0, out var quat); Matrix.RotationQuaternion(ref quat, out m2); Matrix.Multiply(ref m3, ref m2, out m1); - Matrix.Billboard(ref transform.Translation, ref cameraPosition, ref up, ref cameraDirection, out m2); + m2 = Matrix.Transformation(Vector3.One, Quaternion.FromDirection(-view.Direction), transform.Translation); Matrix.Multiply(ref m1, ref m2, out world); } else if (_renderMode == CanvasRenderMode.CameraSpace) @@ -358,16 +355,13 @@ namespace FlaxEngine { // In 3D world face camera var transform = Transform; - var cameraPosition = camera.Position; - var cameraDirection = camera.Direction; - var up = Vector3.Up; Matrix.Translation(_guiRoot.Width * -0.5f, _guiRoot.Height * -0.5f, 0, out var m1); Matrix.Scaling(ref transform.Scale, out var m2); Matrix.Multiply(ref m1, ref m2, out var m3); Quaternion.Euler(180, 180, 0, out var quat); Matrix.RotationQuaternion(ref quat, out m2); Matrix.Multiply(ref m3, ref m2, out m1); - Matrix.Billboard(ref transform.Translation, ref cameraPosition, ref up, ref cameraDirection, out m2); + m2 = Matrix.Transformation(Vector3.One, Quaternion.FromDirection(-camera.Direction), transform.Translation); Matrix.Multiply(ref m1, ref m2, out world); } else if (_renderMode == CanvasRenderMode.CameraSpace && camera)