From 5de034f0736a40149481db87375af3a06d0a5fa4 Mon Sep 17 00:00:00 2001 From: Nejcraft Date: Sat, 20 Feb 2021 14:20:26 +0100 Subject: [PATCH 01/19] Add some defaults to Quaternion helpers --- Source/Engine/Core/Math/Quaternion.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Engine/Core/Math/Quaternion.cs b/Source/Engine/Core/Math/Quaternion.cs index 938bf48b1..ed09e7307 100644 --- a/Source/Engine/Core/Math/Quaternion.cs +++ b/Source/Engine/Core/Math/Quaternion.cs @@ -975,7 +975,7 @@ namespace FlaxEngine /// The camera look-at target. /// The camera's up vector. /// The created look-at quaternion. - public static Quaternion LookAt(Vector3 eye, Vector3 target, Vector3 up) + public static Quaternion LookAt(Vector3 eye, Vector3 target, Vector3 up = Vector3.Up) { LookAt(ref eye, ref target, ref up, out var result); return result; @@ -999,7 +999,7 @@ namespace FlaxEngine /// The camera's forward direction. /// The camera's up vector. /// The created look-at quaternion. - public static Quaternion RotationLookAt(Vector3 forward, Vector3 up) + public static Quaternion RotationLookAt(Vector3 forward, Vector3 up = Vector3.Up) { RotationLookAt(ref forward, ref up, out var result); return result; @@ -1011,7 +1011,7 @@ namespace FlaxEngine /// The forward direction. Direction to orient towards. /// Up direction. Constrains y axis orientation to a plane this vector lies on. This rule might be broken if forward and up direction are nearly parallel. /// The calculated quaternion. - public static Quaternion LookRotation(Vector3 forward, Vector3 up) + public static Quaternion LookRotation(Vector3 forward, Vector3 up = Vector3.Up) { LookRotation(ref forward, ref up, out var result); return result; From 2f0c96abe209afa50b76eeca8a645b78aa47f8f1 Mon Sep 17 00:00:00 2001 From: Nejcraft Date: Sat, 20 Feb 2021 14:52:02 +0100 Subject: [PATCH 02/19] now it'll work --- Source/Engine/Core/Math/Quaternion.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Source/Engine/Core/Math/Quaternion.cs b/Source/Engine/Core/Math/Quaternion.cs index ed09e7307..19eb199fe 100644 --- a/Source/Engine/Core/Math/Quaternion.cs +++ b/Source/Engine/Core/Math/Quaternion.cs @@ -975,8 +975,10 @@ namespace FlaxEngine /// The camera look-at target. /// The camera's up vector. /// The created look-at quaternion. - public static Quaternion LookAt(Vector3 eye, Vector3 target, Vector3 up = Vector3.Up) + public static Quaternion LookAt(Vector3 eye, Vector3 target, Vector3 up = null) { + if(up == null) + up = Vector3.Up; LookAt(ref eye, ref target, ref up, out var result); return result; } @@ -999,8 +1001,10 @@ namespace FlaxEngine /// The camera's forward direction. /// The camera's up vector. /// The created look-at quaternion. - public static Quaternion RotationLookAt(Vector3 forward, Vector3 up = Vector3.Up) + public static Quaternion RotationLookAt(Vector3 forward, Vector3 up = null) { + if(up == null) + up = Vector3.Up; RotationLookAt(ref forward, ref up, out var result); return result; } @@ -1011,8 +1015,10 @@ namespace FlaxEngine /// The forward direction. Direction to orient towards. /// Up direction. Constrains y axis orientation to a plane this vector lies on. This rule might be broken if forward and up direction are nearly parallel. /// The calculated quaternion. - public static Quaternion LookRotation(Vector3 forward, Vector3 up = Vector3.Up) + public static Quaternion LookRotation(Vector3 forward, Vector3 up = null) { + if(up == null) + up = Vector3.Up; LookRotation(ref forward, ref up, out var result); return result; } From 3da17918aacacdf16895a32231c571a55b691d53 Mon Sep 17 00:00:00 2001 From: Nejcraft Date: Sat, 20 Feb 2021 14:58:05 +0100 Subject: [PATCH 03/19] Overloaded --- Source/Engine/Core/Math/Quaternion.cs | 40 ++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/Source/Engine/Core/Math/Quaternion.cs b/Source/Engine/Core/Math/Quaternion.cs index 19eb199fe..fb763154e 100644 --- a/Source/Engine/Core/Math/Quaternion.cs +++ b/Source/Engine/Core/Math/Quaternion.cs @@ -967,7 +967,17 @@ namespace FlaxEngine Matrix3x3.LookAt(ref eye, ref target, ref up, out var matrix); RotationMatrix(ref matrix, out result); } - + + /// + /// Creates a left-handed, look-at quaternion. + /// + /// The position of the viewer's eye. + /// The camera look-at target. + /// The created look-at quaternion. + public static Quaternion LookAt(Vector3 eye, Vector3 target){ + return LookAt(eye, target, Vector3.Up); + } + /// /// Creates a left-handed, look-at quaternion. /// @@ -975,10 +985,8 @@ namespace FlaxEngine /// The camera look-at target. /// The camera's up vector. /// The created look-at quaternion. - public static Quaternion LookAt(Vector3 eye, Vector3 target, Vector3 up = null) + public static Quaternion LookAt(Vector3 eye, Vector3 target, Vector3 up) { - if(up == null) - up = Vector3.Up; LookAt(ref eye, ref target, ref up, out var result); return result; } @@ -995,20 +1003,38 @@ namespace FlaxEngine LookAt(ref eye, ref forward, ref up, out result); } + /// + /// Creates a left-handed, look-at quaternion. + /// + /// The camera's forward direction. + /// The created look-at quaternion. + public static Quaternion RotationLookAt(Vector3 forward) + { + return RotationLookAt(forward, Vector3.Up); + } + /// /// Creates a left-handed, look-at quaternion. /// /// The camera's forward direction. /// The camera's up vector. /// The created look-at quaternion. - public static Quaternion RotationLookAt(Vector3 forward, Vector3 up = null) + public static Quaternion RotationLookAt(Vector3 forward, Vector3 up) { - if(up == null) - up = Vector3.Up; RotationLookAt(ref forward, ref up, out var result); return result; } + /// + /// Creates a rotation with the specified forward and upwards directions. + /// + /// The forward direction. Direction to orient towards. + /// The calculated quaternion. + public static Quaternion LookRotation(Vector3 forward) + { + return LookRotation(forward, Vector3.Up); + } + /// /// Creates a rotation with the specified forward and upwards directions. /// From db3552509a0375377e931c2f9619dd920151eb20 Mon Sep 17 00:00:00 2001 From: Nejcraft Date: Sat, 20 Feb 2021 14:59:42 +0100 Subject: [PATCH 04/19] How many times can I fuck up? --- Source/Engine/Core/Math/Quaternion.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Source/Engine/Core/Math/Quaternion.cs b/Source/Engine/Core/Math/Quaternion.cs index fb763154e..a3aa0732b 100644 --- a/Source/Engine/Core/Math/Quaternion.cs +++ b/Source/Engine/Core/Math/Quaternion.cs @@ -1041,10 +1041,8 @@ namespace FlaxEngine /// The forward direction. Direction to orient towards. /// Up direction. Constrains y axis orientation to a plane this vector lies on. This rule might be broken if forward and up direction are nearly parallel. /// The calculated quaternion. - public static Quaternion LookRotation(Vector3 forward, Vector3 up = null) + public static Quaternion LookRotation(Vector3 forward, Vector3 up) { - if(up == null) - up = Vector3.Up; LookRotation(ref forward, ref up, out var result); return result; } From b133539c40968def153125f7d27e0789b110b8ba Mon Sep 17 00:00:00 2001 From: Nejcraft Date: Sat, 20 Feb 2021 16:24:48 +0100 Subject: [PATCH 05/19] Add Vector3 Clamp --- Source/Engine/Core/Math/Vector3.cs | 36 +++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/Source/Engine/Core/Math/Vector3.cs b/Source/Engine/Core/Math/Vector3.cs index a57fcb224..22dc1c84f 100644 --- a/Source/Engine/Core/Math/Vector3.cs +++ b/Source/Engine/Core/Math/Vector3.cs @@ -983,7 +983,41 @@ namespace FlaxEngine value.Normalize(); return value; } - + + /// + /// Makes sure that Length of the output vector is always below max and above 0. + /// + /// Input Vector. + /// Max Length + public static Vector3 ClampLength(Vector3 vector, float max) + { + return ClampLength(vector, 0, max); + } + /// + /// Makes sure that Length of the output vector is always below max and above min. + /// + /// Input Vector. + /// Min Length + /// Max Length + public static Vector3 ClampLength(Vector3 vector, float min, float max) + { + Vector3 retVect = new Vector3(vector.X, vector.Y, vector.Z); + if (retVect.LengthSquared > max * max) + { + float scaleFactor = max / (float)Math.Sqrt(retVect.LengthSquared); + retVect.X = retVect.X * scaleFactor; + retVect.Y = retVect.Y * scaleFactor; + retVect.Z = retVect.Z * scaleFactor; + } + if (retVect.LengthSquared < min * min) + { + float scaleFactor = min / (float)Math.Sqrt(retVect.LengthSquared); + retVect.X = retVect.X * scaleFactor; + retVect.Y = retVect.Y * scaleFactor; + retVect.Z = retVect.Z * scaleFactor; + } + return retVect; + } /// /// Performs a linear interpolation between two vectors. /// From 9752bfabee254e886e2b6083bb369f24f09dce29 Mon Sep 17 00:00:00 2001 From: GoaLitiuM Date: Sun, 21 Feb 2021 16:07:02 +0200 Subject: [PATCH 06/19] Allow overriding most of the methods in TextBoxBase --- .../Engine/UI/GUI/Common/RichTextBoxBase.cs | 2 +- Source/Engine/UI/GUI/Common/TextBoxBase.cs | 58 +++++++++++++------ 2 files changed, 40 insertions(+), 20 deletions(-) diff --git a/Source/Engine/UI/GUI/Common/RichTextBoxBase.cs b/Source/Engine/UI/GUI/Common/RichTextBoxBase.cs index 58e5bdaac..eedaa10c2 100644 --- a/Source/Engine/UI/GUI/Common/RichTextBoxBase.cs +++ b/Source/Engine/UI/GUI/Common/RichTextBoxBase.cs @@ -61,7 +61,7 @@ namespace FlaxEngine.GUI /// /// Updates the text blocks. /// - protected void UpdateTextBlocks() + protected virtual void UpdateTextBlocks() { Profiler.BeginEvent("RichTextBoxBase.UpdateTextBlocks"); diff --git a/Source/Engine/UI/GUI/Common/TextBoxBase.cs b/Source/Engine/UI/GUI/Common/TextBoxBase.cs index ccf346ed6..1d4fd2362 100644 --- a/Source/Engine/UI/GUI/Common/TextBoxBase.cs +++ b/Source/Engine/UI/GUI/Common/TextBoxBase.cs @@ -422,7 +422,7 @@ namespace FlaxEngine.GUI /// /// Clears all text from the text box control. /// - public void Clear() + public virtual void Clear() { Text = string.Empty; } @@ -430,7 +430,7 @@ namespace FlaxEngine.GUI /// /// Clear selection range /// - public void ClearSelection() + public virtual void ClearSelection() { OnSelectingEnd(); SetSelection(-1); @@ -439,7 +439,7 @@ namespace FlaxEngine.GUI /// /// Resets the view offset (text scroll view). /// - public void ResetViewOffset() + public virtual void ResetViewOffset() { TargetViewOffset = Vector2.Zero; } @@ -455,7 +455,7 @@ namespace FlaxEngine.GUI /// /// Copies the current selection in the text box to the Clipboard. /// - public void Copy() + public virtual void Copy() { var selectedText = SelectedText; if (selectedText.Length > 0) @@ -468,7 +468,7 @@ namespace FlaxEngine.GUI /// /// Moves the current selection in the text box to the Clipboard. /// - public void Cut() + public virtual void Cut() { var selectedText = SelectedText; if (selectedText.Length > 0) @@ -490,7 +490,7 @@ namespace FlaxEngine.GUI /// /// Replaces the current selection in the text box with the contents of the Clipboard. /// - public void Paste() + public virtual void Paste() { if (IsReadOnly) return; @@ -508,7 +508,7 @@ namespace FlaxEngine.GUI /// /// Duplicates the current selection in the text box. /// - public void Duplicate() + public virtual void Duplicate() { if (IsReadOnly) return; @@ -526,7 +526,7 @@ namespace FlaxEngine.GUI /// /// Ensures that the caret is visible in the TextBox window, by scrolling the TextBox control surface if necessary. /// - public void ScrollToCaret() + public virtual void ScrollToCaret() { // If it's empty if (_text.Length == 0) @@ -547,7 +547,7 @@ namespace FlaxEngine.GUI /// /// Selects all text in the text box. /// - public void SelectAll() + public virtual void SelectAll() { if (TextLength > 0) { @@ -558,7 +558,7 @@ namespace FlaxEngine.GUI /// /// Sets the selection to empty value. /// - public void Deselect() + public virtual void Deselect() { SetSelection(-1); } @@ -568,7 +568,7 @@ namespace FlaxEngine.GUI /// /// The location (in control-space). /// The character index under the location - public int CharIndexAtPoint(ref Vector2 location) + public virtual int CharIndexAtPoint(ref Vector2 location) { return HitTestText(location + _viewOffset); } @@ -577,7 +577,7 @@ namespace FlaxEngine.GUI /// Inserts the specified character (at the current selection). /// /// The character. - public void Insert(char c) + public virtual void Insert(char c) { Insert(c.ToString()); } @@ -586,7 +586,7 @@ namespace FlaxEngine.GUI /// Inserts the specified text (at the current selection). /// /// The string. - public void Insert(string str) + public virtual void Insert(string str) { if (IsReadOnly) return; @@ -622,7 +622,12 @@ namespace FlaxEngine.GUI OnTextChanged(); } - private void MoveRight(bool shift, bool ctrl) + /// + /// Moves the caret right. + /// + /// Shift is held. + /// Control is held. + protected virtual void MoveRight(bool shift, bool ctrl) { if (HasSelection && !shift) { @@ -647,7 +652,12 @@ namespace FlaxEngine.GUI } } - private void MoveLeft(bool shift, bool ctrl) + /// + /// Moves the caret left. + /// + /// Shift is held. + /// Control is held. + protected virtual void MoveLeft(bool shift, bool ctrl) { if (HasSelection && !shift) { @@ -672,7 +682,12 @@ namespace FlaxEngine.GUI } } - private void MoveDown(bool shift, bool ctrl) + /// + /// Moves the caret down. + /// + /// Shift is held. + /// Control is held. + protected virtual void MoveDown(bool shift, bool ctrl) { if (HasSelection && !shift) { @@ -693,7 +708,12 @@ namespace FlaxEngine.GUI } } - private void MoveUp(bool shift, bool ctrl) + /// + /// Moves the caret up. + /// + /// Shift is held. + /// Control is held. + protected virtual void MoveUp(bool shift, bool ctrl) { if (HasSelection && !shift) { @@ -719,7 +739,7 @@ namespace FlaxEngine.GUI /// /// The caret position. /// If set to true with auto-scroll. - protected void SetSelection(int caret, bool withScroll = true) + protected virtual void SetSelection(int caret, bool withScroll = true) { SetSelection(caret, caret); } @@ -730,7 +750,7 @@ namespace FlaxEngine.GUI /// The selection start character. /// The selection end character. /// If set to true with auto-scroll. - protected void SetSelection(int start, int end, bool withScroll = true) + protected virtual void SetSelection(int start, int end, bool withScroll = true) { // Update parameters int textLength = _text.Length; From 5d7940f784b98d8f6c156d979d9165af9727c80f Mon Sep 17 00:00:00 2001 From: Nejcraft Date: Wed, 24 Feb 2021 14:25:49 +0100 Subject: [PATCH 07/19] Unified --- Source/Engine/Core/Math/Vector3.cs | 34 ++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/Source/Engine/Core/Math/Vector3.cs b/Source/Engine/Core/Math/Vector3.cs index 22dc1c84f..be885590a 100644 --- a/Source/Engine/Core/Math/Vector3.cs +++ b/Source/Engine/Core/Math/Vector3.cs @@ -1001,20 +1001,32 @@ namespace FlaxEngine /// Max Length public static Vector3 ClampLength(Vector3 vector, float min, float max) { - Vector3 retVect = new Vector3(vector.X, vector.Y, vector.Z); - if (retVect.LengthSquared > max * max) + ClampLength(vector, min, max, out Vector3 retVect); + return retVect; + } + /// + /// Makes sure that Length of the output vector is always below max and above min. + /// + /// Input Vector. + /// Min Length + /// Max Length + /// The Return Vector + public static void ClampLength(Vector3 vector, float min, float max, out Vector3 retVect) + { + float lenSq = vector.LengthSquared; + if (lenSq > max * max) { - float scaleFactor = max / (float)Math.Sqrt(retVect.LengthSquared); - retVect.X = retVect.X * scaleFactor; - retVect.Y = retVect.Y * scaleFactor; - retVect.Z = retVect.Z * scaleFactor; + float scaleFactor = max / (float)Math.Sqrt(lenSq); + retVect.X = vector.X * scaleFactor; + retVect.Y = vector.Y * scaleFactor; + retVect.Z = vector.Z * scaleFactor; } - if (retVect.LengthSquared < min * min) + if (lenSq < min * min) { - float scaleFactor = min / (float)Math.Sqrt(retVect.LengthSquared); - retVect.X = retVect.X * scaleFactor; - retVect.Y = retVect.Y * scaleFactor; - retVect.Z = retVect.Z * scaleFactor; + float scaleFactor = min / (float)Math.Sqrt(lenSq); + retVect.X = vector.X * scaleFactor; + retVect.Y = vector.Y * scaleFactor; + retVect.Z = vector.Z * scaleFactor; } return retVect; } From 13cc6eb7b928d43fc5061e1c98c4ac2247525577 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 26 Feb 2021 11:50:05 +0100 Subject: [PATCH 08/19] Cleanup DebugLog internal calls --- Source/Engine/Debug/DebugLog.cpp | 72 +------------------ Source/Engine/Debug/DebugLog.h | 7 -- .../InternalCalls/EngineInternalCalls.cpp | 60 +++++++++++++++- 3 files changed, 60 insertions(+), 79 deletions(-) diff --git a/Source/Engine/Debug/DebugLog.cpp b/Source/Engine/Debug/DebugLog.cpp index bf1da8d7d..55c17b7f0 100644 --- a/Source/Engine/Debug/DebugLog.cpp +++ b/Source/Engine/Debug/DebugLog.cpp @@ -1,12 +1,7 @@ // Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. #include "DebugLog.h" -#include "Engine/Core/Log.h" -#include "Engine/Scripting/InternalCalls.h" -#include "Engine/Scripting/ScriptingObject.h" -#include "Engine/Scripting/MException.h" #include "Engine/Scripting/Scripting.h" -#include "Engine/Scripting/ScriptingType.h" #include "Engine/Scripting/BinaryModule.h" #include "Engine/Scripting/MainThreadManagedInvokeAction.h" #include "Engine/Scripting/ManagedCLR/MDomain.h" @@ -16,70 +11,7 @@ #include #include -namespace DebugLogHandlerInternal -{ - void LogWrite(LogType level, MonoString* msgObj) - { - StringView msg; - MUtils::ToString(msgObj, msg); - Log::Logger::Write(level, msg); - } - - void Log(LogType level, MonoString* msgObj, ScriptingObject* obj, MonoString* stackTrace) - { - if (msgObj == nullptr) - return; - - // Get info - StringView msg; - MUtils::ToString(msgObj, msg); - //const String objName = obj ? obj->ToString() : String::Empty; - - // Send event - // TODO: maybe option for build to threat warnings and errors as fatal errors? - //const String logMessage = String::Format(TEXT("Debug:{1} {2}"), objName, *msg); - Log::Logger::Write(level, msg); - } - - void LogException(MonoException* exception, ScriptingObject* obj) - { - if (exception == nullptr) - return; - - // Get info - MException ex(exception); - String objName = obj ? obj->ToString() : String::Empty; - - // Print exception including inner exceptions - // TODO: maybe option for build to threat warnings and errors as fatal errors? - ex.Log(LogType::Warning, objName.GetText()); - } -} - -namespace FlaxLogWriterInternal -{ - void WriteStringToLog(MonoString* msg) - { - if (msg == nullptr) - return; - - auto msgStr = (Char*)mono_string_to_utf16(msg); - LOG_STR(Info, msgStr); - } -} - -void DebugLog::RegisterInternalCalls() -{ - // DebugLogHandler - ADD_INTERNAL_CALL("FlaxEngine.DebugLogHandler::Internal_LogWrite", &DebugLogHandlerInternal::LogWrite); - ADD_INTERNAL_CALL("FlaxEngine.DebugLogHandler::Internal_Log", &DebugLogHandlerInternal::Log); - ADD_INTERNAL_CALL("FlaxEngine.DebugLogHandler::Internal_LogException", &DebugLogHandlerInternal::LogException); - - // FlaxLogWriter - ADD_INTERNAL_CALL("FlaxEngine.FlaxLogWriter::Internal_WriteStringToLog", &FlaxLogWriterInternal::WriteStringToLog); -} - -namespace DebugLogImpl +namespace Impl { MMethod* Internal_SendLog = nullptr; MMethod* Internal_SendLogException = nullptr; @@ -87,7 +19,7 @@ namespace DebugLogImpl CriticalSection Locker; } -using namespace DebugLogImpl; +using namespace Impl; void ClearMethods(MAssembly*) { diff --git a/Source/Engine/Debug/DebugLog.h b/Source/Engine/Debug/DebugLog.h index 6ef7f8242..fd05bee7c 100644 --- a/Source/Engine/Debug/DebugLog.h +++ b/Source/Engine/Debug/DebugLog.h @@ -10,13 +10,6 @@ /// class FLAXENGINE_API DebugLog { -public: - - /// - /// Registers the internal calls to managed code. - /// - static void RegisterInternalCalls(); - public: /// diff --git a/Source/Engine/Scripting/InternalCalls/EngineInternalCalls.cpp b/Source/Engine/Scripting/InternalCalls/EngineInternalCalls.cpp index 0e06179fa..144eb6c86 100644 --- a/Source/Engine/Scripting/InternalCalls/EngineInternalCalls.cpp +++ b/Source/Engine/Scripting/InternalCalls/EngineInternalCalls.cpp @@ -1,9 +1,10 @@ // Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. #include "Engine/Platform/FileSystem.h" -#include "Engine/Debug/DebugLog.h" #include "Engine/Animations/Graph/AnimGraph.h" #include "Engine/Scripting/InternalCalls.h" +#include "Engine/Scripting/MException.h" +#include "Engine/Scripting/ManagedCLR/MUtils.h" namespace UtilsInternal { @@ -13,9 +14,64 @@ namespace UtilsInternal } } +namespace DebugLogHandlerInternal +{ + void LogWrite(LogType level, MonoString* msgObj) + { + StringView msg; + MUtils::ToString(msgObj, msg); + Log::Logger::Write(level, msg); + } + + void Log(LogType level, MonoString* msgObj, ScriptingObject* obj, MonoString* stackTrace) + { + if (msgObj == nullptr) + return; + + // Get info + StringView msg; + MUtils::ToString(msgObj, msg); + //const String objName = obj ? obj->ToString() : String::Empty; + + // Send event + // TODO: maybe option for build to threat warnings and errors as fatal errors? + //const String logMessage = String::Format(TEXT("Debug:{1} {2}"), objName, *msg); + Log::Logger::Write(level, msg); + } + + void LogException(MonoException* exception, ScriptingObject* obj) + { + if (exception == nullptr) + return; + + // Get info + MException ex(exception); + const String objName = obj ? obj->ToString() : String::Empty; + + // Print exception including inner exceptions + // TODO: maybe option for build to threat warnings and errors as fatal errors? + ex.Log(LogType::Warning, objName.GetText()); + } +} + +namespace FlaxLogWriterInternal +{ + void WriteStringToLog(MonoString* msgObj) + { + if (msgObj == nullptr) + return; + StringView msg; + MUtils::ToString(msgObj, msg); + LOG_STR(Info, msg); + } +} + void registerFlaxEngineInternalCalls() { - DebugLog::RegisterInternalCalls(); AnimGraphExecutor::initRuntime(); ADD_INTERNAL_CALL("FlaxEngine.Utils::MemoryCopy", &UtilsInternal::MemoryCopy); + ADD_INTERNAL_CALL("FlaxEngine.DebugLogHandler::Internal_LogWrite", &DebugLogHandlerInternal::LogWrite); + ADD_INTERNAL_CALL("FlaxEngine.DebugLogHandler::Internal_Log", &DebugLogHandlerInternal::Log); + ADD_INTERNAL_CALL("FlaxEngine.DebugLogHandler::Internal_LogException", &DebugLogHandlerInternal::LogException); + ADD_INTERNAL_CALL("FlaxEngine.FlaxLogWriter::Internal_WriteStringToLog", &FlaxLogWriterInternal::WriteStringToLog); } From e1387e92a3d8f17c839eb2d725b75f1b9d0c6e8e Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 26 Feb 2021 12:49:33 +0100 Subject: [PATCH 09/19] Fix Debug Log stack trace collecting in Editor Fixes #51 --- Source/Editor/Windows/DebugLogWindow.cs | 26 ++++++++++++++++++++----- Source/Engine/Engine/DebugLogHandler.cs | 9 +++++---- Source/Engine/Scripting/Scripting.cs | 6 ++++-- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/Source/Editor/Windows/DebugLogWindow.cs b/Source/Editor/Windows/DebugLogWindow.cs index 7900b55c2..ef47fe241 100644 --- a/Source/Editor/Windows/DebugLogWindow.cs +++ b/Source/Editor/Windows/DebugLogWindow.cs @@ -2,6 +2,8 @@ using System; using System.Collections.Generic; +using System.IO; +using System.Security.Cryptography.X509Certificates; using System.Text; using System.Text.RegularExpressions; using System.Xml; @@ -183,6 +185,11 @@ namespace FlaxEditor.Windows return true; } } + // Enter + else if (key == KeyboardKeys.Return) + { + Open(); + } // Ctrl+C else if (key == KeyboardKeys.C && Root.GetKey(KeyboardKeys.Control)) { @@ -193,6 +200,17 @@ namespace FlaxEditor.Windows return base.OnKeyDown(key); } + /// + /// Opens the entry location. + /// + public void Open() + { + if (!string.IsNullOrEmpty(Desc.LocationFile) && File.Exists(Desc.LocationFile)) + { + Editor.Instance.CodeEditing.OpenFile(Desc.LocationFile, Desc.LocationLine); + } + } + /// /// Copies the entry information to the system clipboard (as text). /// @@ -203,9 +221,7 @@ namespace FlaxEditor.Windows public override bool OnMouseDoubleClick(Vector2 location, MouseButton button) { - // Show the location - Editor.Instance.CodeEditing.OpenFile(Desc.LocationFile, Desc.LocationLine); - + Open(); return true; } @@ -238,6 +254,7 @@ namespace FlaxEditor.Windows var menu = new ContextMenu(); menu.AddButton("Copy", Copy); + menu.AddButton("Open", Open).Enabled = !string.IsNullOrEmpty(Desc.LocationFile) && File.Exists(Desc.LocationFile); menu.Show(this, location); } @@ -337,7 +354,6 @@ namespace FlaxEditor.Windows Editor.Options.OptionsChanged += OnEditorOptionsChanged; Debug.Logger.LogHandler.SendLog += LogHandlerOnSendLog; Debug.Logger.LogHandler.SendExceptionLog += LogHandlerOnSendExceptionLog; - } private void OnEditorOptionsChanged(EditorOptions options) @@ -502,7 +518,7 @@ namespace FlaxEditor.Windows } fineStackTrace.AppendLine(match.Groups[0].Value); } - else if (match.Groups[1].Value.Trim().StartsWith("FlaxEngine.Debug.Info", StringComparison.Ordinal)) + else if (match.Groups[1].Value.Trim().StartsWith("FlaxEngine.Debug.", StringComparison.Ordinal)) { foundStart = true; } diff --git a/Source/Engine/Engine/DebugLogHandler.cs b/Source/Engine/Engine/DebugLogHandler.cs index c1dc9f9dd..986d48a3a 100644 --- a/Source/Engine/Engine/DebugLogHandler.cs +++ b/Source/Engine/Engine/DebugLogHandler.cs @@ -36,13 +36,14 @@ namespace FlaxEngine /// public void Log(LogType logType, Object context, string message) { -#if DEBUG - string stackTrace = Environment.StackTrace; + if (message == null) + return; +#if BUILD_RELEASE + string stackTrace = null; #else - string stackTrace = string.Empty; + string stackTrace = Environment.StackTrace; #endif Internal_Log(logType, message, Object.GetUnmanagedPtr(context), stackTrace); - SendLog?.Invoke(logType, message, context, stackTrace); } diff --git a/Source/Engine/Scripting/Scripting.cs b/Source/Engine/Scripting/Scripting.cs index 522d0a73c..6cb04b813 100644 --- a/Source/Engine/Scripting/Scripting.cs +++ b/Source/Engine/Scripting/Scripting.cs @@ -148,9 +148,11 @@ namespace FlaxEngine /// internal static void Init() { -#if DEBUG +#if BUILD_DEBUG Debug.Logger.LogHandler.LogWrite(LogType.Info, "Using FlaxAPI in Debug"); -#else +#elif BUILD_DEVELOPMENT + Debug.Logger.LogHandler.LogWrite(LogType.Info, "Using FlaxAPI in Development"); +#elif BUILD_RELEASE Debug.Logger.LogHandler.LogWrite(LogType.Info, "Using FlaxAPI in Release"); #endif From a45b71617d794b8f295276f26c64192f13bb3050 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 26 Feb 2021 13:58:02 +0100 Subject: [PATCH 10/19] Add separate `Platform::GetStackTrace` and `Platform::GetStackFrames` --- Source/Engine/Platform/Base/PlatformBase.cpp | 36 +++++++++++++++---- Source/Engine/Platform/Base/PlatformBase.h | 11 +++++- .../Platform/Windows/WindowsPlatform.cpp | 2 +- .../Engine/Platform/Windows/WindowsPlatform.h | 2 +- 4 files changed, 42 insertions(+), 9 deletions(-) diff --git a/Source/Engine/Platform/Base/PlatformBase.cpp b/Source/Engine/Platform/Base/PlatformBase.cpp index ba2d6d5f6..5ffb85a9a 100644 --- a/Source/Engine/Platform/Base/PlatformBase.cpp +++ b/Source/Engine/Platform/Base/PlatformBase.cpp @@ -202,11 +202,11 @@ void PlatformBase::Fatal(const Char* msg, void* context) LOG(Error, ""); // Log stack trace - const auto stackTrace = Platform::GetStackTrace(context ? 0 : 1, 60, context); - if (stackTrace.HasItems()) + const auto stackFrames = Platform::GetStackFrames(context ? 0 : 1, 60, context); + if (stackFrames.HasItems()) { LOG(Error, "Stack trace:"); - for (const auto& frame : stackTrace) + for (const auto& frame : stackFrames) { char chr = 0; int32 num = StringUtils::Length(frame.ModuleName); @@ -217,11 +217,11 @@ void PlatformBase::Fatal(const Char* msg, void* context) if (StringUtils::Length(frame.FileName) != 0) { StringAsUTF16 fileName(frame.FileName); - LOG(Error, " at {0}!{1} in {2}:line {3}", moduleName.Get(), functionName.Get(), fileName.Get(), frame.LineNumber); + LOG(Error, " at {0}!{1}() in {2}:line {3}", moduleName.Get(), functionName.Get(), fileName.Get(), frame.LineNumber); } else if (StringUtils::Length(frame.FunctionName) != 0) { - LOG(Error, " at {0}::{1}", moduleName.Get(), functionName.Get()); + LOG(Error, " at {0}!{1}()", moduleName.Get(), functionName.Get()); } else if (StringUtils::Length(frame.ModuleName) != 0) { @@ -483,11 +483,35 @@ int32 PlatformBase::RunProcess(const StringView& cmdLine, const StringView& work return -1; } -Array PlatformBase::GetStackTrace(int32 skipCount, int32 maxDepth, void* context) +Array PlatformBase::GetStackFrames(int32 skipCount, int32 maxDepth, void* context) { return Array(); } +String PlatformBase::GetStackTrace(int32 skipCount, int32 maxDepth, void* context) +{ + StringBuilder result; + Array stackFrames = Platform::GetStackFrames(skipCount, maxDepth, context); + for (const auto& frame : stackFrames) + { + StringAsUTF16 functionName(frame.FunctionName); + if (StringUtils::Length(frame.FileName) != 0) + { + StringAsUTF16 fileName(frame.FileName); + result.AppendFormat(TEXT(" at {0}() in {1}:line {2}\n"), functionName.Get(), fileName.Get(), frame.LineNumber); + } + else if (StringUtils::Length(frame.FunctionName) != 0) + { + result.AppendFormat(TEXT(" at {0}()\n"), functionName.Get()); + } + else + { + result.AppendFormat(TEXT(" at 0x{0:x}\n"), (uint64)frame.ProgramCounter); + } + } + return result.ToString(); +} + void PlatformBase::CollectCrashData(const String& crashDataFolder, void* context) { } diff --git a/Source/Engine/Platform/Base/PlatformBase.h b/Source/Engine/Platform/Base/PlatformBase.h index e97ce2b34..188bad122 100644 --- a/Source/Engine/Platform/Base/PlatformBase.h +++ b/Source/Engine/Platform/Base/PlatformBase.h @@ -804,7 +804,16 @@ public: /// The maximum depth of the stack to collect. Can be used to prevent too long stack traces in case of stack overflow exception. /// The platform-dependent context for the stack trace collecting (eg. platform exception info). /// The collected stack trace frames. Empty if not supported (eg. platform not implements this feature or not supported in the distributed build). - static Array GetStackTrace(int32 skipCount = 0, int32 maxDepth = 60, void* context = nullptr); + static Array GetStackFrames(int32 skipCount = 0, int32 maxDepth = 60, void* context = nullptr); + + /// + /// Gets current native stack trace information as string. + /// + /// The amount of stack frames to skip from the beginning. Can be used to skip the callee function from the trace (eg. in crash handler). + /// The maximum depth of the stack to collect. Can be used to prevent too long stack traces in case of stack overflow exception. + /// The platform-dependent context for the stack trace collecting (eg. platform exception info). + /// The collected stack trace printed into string. Empty if not supported (eg. platform not implements this feature or not supported in the distributed build). + static String GetStackTrace(int32 skipCount = 0, int32 maxDepth = 60, void* context = nullptr); // Crash dump data handling static void CollectCrashData(const String& crashDataFolder, void* context = nullptr); diff --git a/Source/Engine/Platform/Windows/WindowsPlatform.cpp b/Source/Engine/Platform/Windows/WindowsPlatform.cpp index e01ef7a44..83fafdf3e 100644 --- a/Source/Engine/Platform/Windows/WindowsPlatform.cpp +++ b/Source/Engine/Platform/Windows/WindowsPlatform.cpp @@ -1107,7 +1107,7 @@ void* WindowsPlatform::LoadLibrary(const Char* filename) return handle; } -Array WindowsPlatform::GetStackTrace(int32 skipCount, int32 maxDepth, void* context) +Array WindowsPlatform::GetStackFrames(int32 skipCount, int32 maxDepth, void* context) { Array result; #if CRASH_LOG_ENABLE diff --git a/Source/Engine/Platform/Windows/WindowsPlatform.h b/Source/Engine/Platform/Windows/WindowsPlatform.h index f437b819c..94bab3f50 100644 --- a/Source/Engine/Platform/Windows/WindowsPlatform.h +++ b/Source/Engine/Platform/Windows/WindowsPlatform.h @@ -82,7 +82,7 @@ public: static int32 RunProcess(const StringView& cmdLine, const StringView& workingDir, const Dictionary& environment, bool hiddenWindow = true); static Window* CreateWindow(const CreateWindowSettings& settings); static void* LoadLibrary(const Char* filename); - static Array GetStackTrace(int32 skipCount = 0, int32 maxDepth = 60, void* context = nullptr); + static Array GetStackFrames(int32 skipCount = 0, int32 maxDepth = 60, void* context = nullptr); #if CRASH_LOG_ENABLE static void CollectCrashData(const String& crashDataFolder, void* context = nullptr); #endif From ff70c16051fc6e68288370b09a164d9f6a3d053a Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 26 Feb 2021 13:58:42 +0100 Subject: [PATCH 11/19] Add support for capturing stack trace of called DebugLog from C++ --- Source/Editor/Windows/DebugLogWindow.cs | 23 ++++++++++++------- Source/Engine/Debug/DebugLog.cpp | 15 +++++++----- Source/Engine/Debug/DebugLog.h | 8 +++---- Source/Engine/Engine/DebugLogHandler.cs | 11 +++++++-- .../Scripting/MainThreadManagedInvokeAction.h | 12 ++++++++++ 5 files changed, 49 insertions(+), 20 deletions(-) diff --git a/Source/Editor/Windows/DebugLogWindow.cs b/Source/Editor/Windows/DebugLogWindow.cs index ef47fe241..250c9738b 100644 --- a/Source/Editor/Windows/DebugLogWindow.cs +++ b/Source/Editor/Windows/DebugLogWindow.cs @@ -216,7 +216,7 @@ namespace FlaxEditor.Windows /// public void Copy() { - Clipboard.Text = Info.Replace("\n", Environment.NewLine); + Clipboard.Text = Info.Replace("\r\n", "\n").Replace("\n", Environment.NewLine); } public override bool OnMouseDoubleClick(Vector2 location, MouseButton button) @@ -275,7 +275,7 @@ namespace FlaxEditor.Windows private readonly VerticalPanel _entriesPanel; private LogEntry _selected; private readonly int[] _logCountPerGroup = new int[(int)LogGroup.Max]; - private readonly Regex _logRegex = new Regex("at(.*) in (.*):(\\d*)"); + private readonly Regex _logRegex = new Regex("at (.*) in (.*):(line (\\d*)|(\\d*))"); private InterfaceOptions.TimestampsFormats _timestampsFormats; private readonly object _locker = new object(); @@ -508,20 +508,27 @@ namespace FlaxEditor.Windows for (int i = 0; i < matches.Count; i++) { var match = matches[i]; - if (foundStart) + var matchLocation = match.Groups[1].Value.Trim(); + if (matchLocation.StartsWith("FlaxEngine.Debug.", StringComparison.Ordinal)) + { + // C# start + foundStart = true; + } + else if (matchLocation.StartsWith("DebugLog::", StringComparison.Ordinal)) + { + // C++ start + foundStart = true; + } + else if (foundStart) { if (noLocation) { desc.LocationFile = match.Groups[2].Value; - int.TryParse(match.Groups[3].Value, out desc.LocationLine); + int.TryParse(match.Groups[5].Value, out desc.LocationLine); noLocation = false; } fineStackTrace.AppendLine(match.Groups[0].Value); } - else if (match.Groups[1].Value.Trim().StartsWith("FlaxEngine.Debug.", StringComparison.Ordinal)) - { - foundStart = true; - } } desc.Description = fineStackTrace.ToString(); } diff --git a/Source/Engine/Debug/DebugLog.cpp b/Source/Engine/Debug/DebugLog.cpp index 55c17b7f0..9263651b9 100644 --- a/Source/Engine/Debug/DebugLog.cpp +++ b/Source/Engine/Debug/DebugLog.cpp @@ -43,7 +43,7 @@ bool CacheMethods() if (!debugLogHandlerClass) return false; - Internal_SendLog = debugLogHandlerClass->GetMethod("Internal_SendLog", 2); + Internal_SendLog = debugLogHandlerClass->GetMethod("Internal_SendLog", 3); if (!Internal_SendLog) return false; @@ -60,7 +60,7 @@ bool CacheMethods() return false; } -void DebugLog::Log(LogType type, const String& message) +void DebugLog::Log(LogType type, const StringView& message) { if (CacheMethods()) return; @@ -69,15 +69,18 @@ void DebugLog::Log(LogType type, const String& message) MainThreadManagedInvokeAction::ParamsBuilder params; params.AddParam(type); params.AddParam(message, scriptsDomain->GetNative()); +#if BUILD_RELEASE + params.AddParam(StringView::Empty, scriptsDomain->GetNative()); +#else + const String stackTrace = Platform::GetStackTrace(1); + params.AddParam(stackTrace, scriptsDomain->GetNative()); +#endif MainThreadManagedInvokeAction::Invoke(Internal_SendLog, params); } void DebugLog::LogException(MonoObject* exceptionObject) { - if (exceptionObject == nullptr) - return; - - if (CacheMethods()) + if (exceptionObject == nullptr || CacheMethods()) return; MainThreadManagedInvokeAction::ParamsBuilder params; diff --git a/Source/Engine/Debug/DebugLog.h b/Source/Engine/Debug/DebugLog.h index fd05bee7c..2fd210563 100644 --- a/Source/Engine/Debug/DebugLog.h +++ b/Source/Engine/Debug/DebugLog.h @@ -17,13 +17,13 @@ public: /// /// The message type. /// The message. - static void Log(LogType type, const String& message); + static void Log(LogType type, const StringView& message); /// /// A variant of Debug.Log that logs a warning message to the console. /// /// The text message to display. - FORCE_INLINE static void Log(const String& message) + FORCE_INLINE static void Log(const StringView& message) { Log(LogType::Info, message); } @@ -32,7 +32,7 @@ public: /// A variant of Debug.Log that logs a warning message to the console. /// /// The text message to display. - FORCE_INLINE static void LogWarning(const String& message) + FORCE_INLINE static void LogWarning(const StringView& message) { Log(LogType::Warning, message); } @@ -41,7 +41,7 @@ public: /// A variant of Debug.Log that logs a error message to the console. /// /// The text message to display. - FORCE_INLINE static void LogError(const String& message) + FORCE_INLINE static void LogError(const StringView& message) { Log(LogType::Error, message); } diff --git a/Source/Engine/Engine/DebugLogHandler.cs b/Source/Engine/Engine/DebugLogHandler.cs index 986d48a3a..bf9a3bc02 100644 --- a/Source/Engine/Engine/DebugLogHandler.cs +++ b/Source/Engine/Engine/DebugLogHandler.cs @@ -47,9 +47,16 @@ namespace FlaxEngine SendLog?.Invoke(logType, message, context, stackTrace); } - internal static void Internal_SendLog(LogType type, string message) + internal static void Internal_SendLog(LogType logType, string message, string stackTrace) { - Debug.Logger.Log(type, message); + if (message == null) + return; + var logger = Debug.Logger; + if (logger.IsLogTypeAllowed(logType)) + { + Internal_Log(logType, message, IntPtr.Zero, stackTrace); + ((DebugLogHandler)logger.LogHandler).SendLog?.Invoke(logType, message, null, stackTrace); + } } internal static void Internal_SendLogException(Exception exception) diff --git a/Source/Engine/Scripting/MainThreadManagedInvokeAction.h b/Source/Engine/Scripting/MainThreadManagedInvokeAction.h index 5af5e5f28..71ea24595 100644 --- a/Source/Engine/Scripting/MainThreadManagedInvokeAction.h +++ b/Source/Engine/Scripting/MainThreadManagedInvokeAction.h @@ -77,12 +77,24 @@ public: AddParam(val); } + FORCE_INLINE void AddParam(const StringView& value) + { + MonoString* val = MUtils::ToString(value); + AddParam(val); + } + FORCE_INLINE void AddParam(const String& value, MonoDomain* domain) { MonoString* val = MUtils::ToString(value, domain); AddParam(val); } + FORCE_INLINE void AddParam(const StringView& value, MonoDomain* domain) + { + MonoString* val = MUtils::ToString(value, domain); + AddParam(val); + } + void GetParams(void* params[8]) { for (int32 i = 0; i < Count; i++) From 0a54b9e77e9447dc8fa844f6b2503266eb93b774 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 26 Feb 2021 13:59:06 +0100 Subject: [PATCH 12/19] Add newest `dbghelp.dll` lib --- Source/Platforms/Windows/Binaries/ThirdParty/x64/dbghelp.dll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/dbghelp.dll b/Source/Platforms/Windows/Binaries/ThirdParty/x64/dbghelp.dll index 8193a32a8..91a7ee8d3 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/dbghelp.dll +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/dbghelp.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:159b30d9f1bbe69ae03e0d19669d4fcb565246d81672b7034a69cef9f466dcbe -size 1369936 +oid sha256:cee97bc83e5aa825df059f2f2e4e83c0e65fe4a263aabbec0ac5476e70bc57e4 +size 1199296 From e1497bcfe20e20ce3e3e319ff25c07a88378c513 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 26 Feb 2021 14:08:53 +0100 Subject: [PATCH 13/19] Optimize DebugLog stack trace formatting --- Source/Editor/Windows/DebugLogWindow.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Source/Editor/Windows/DebugLogWindow.cs b/Source/Editor/Windows/DebugLogWindow.cs index 250c9738b..560e507eb 100644 --- a/Source/Editor/Windows/DebugLogWindow.cs +++ b/Source/Editor/Windows/DebugLogWindow.cs @@ -3,9 +3,9 @@ using System; using System.Collections.Generic; using System.IO; -using System.Security.Cryptography.X509Certificates; using System.Text; using System.Text.RegularExpressions; +using System.Threading; using System.Xml; using FlaxEditor.GUI; using FlaxEditor.GUI.ContextMenu; @@ -276,6 +276,7 @@ namespace FlaxEditor.Windows private LogEntry _selected; private readonly int[] _logCountPerGroup = new int[(int)LogGroup.Max]; private readonly Regex _logRegex = new Regex("at (.*) in (.*):(line (\\d*)|(\\d*))"); + private readonly ThreadLocal _stringBuilder = new ThreadLocal(() => new StringBuilder(), false); private InterfaceOptions.TimestampsFormats _timestampsFormats; private readonly object _locker = new object(); @@ -504,7 +505,9 @@ namespace FlaxEditor.Windows // Detect code location and remove leading internal stack trace part var matches = _logRegex.Matches(stackTrace); bool foundStart = false, noLocation = true; - var fineStackTrace = new StringBuilder(stackTrace.Length); + var fineStackTrace = _stringBuilder.Value; + fineStackTrace.Clear(); + fineStackTrace.Capacity = Mathf.Max(fineStackTrace.Capacity, stackTrace.Length); for (int i = 0; i < matches.Count; i++) { var match = matches[i]; From 327fa6718e1c990154aa85e19d8a8c24ddd75a98 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 26 Feb 2021 15:40:44 +0100 Subject: [PATCH 14/19] Refactor AssetsContainer --- Source/Engine/Content/AssetReference.h | 2 +- Source/Engine/Content/Assets/VisualScript.cpp | 1 + Source/Engine/Content/{Utilities => }/AssetsContainer.h | 9 ++------- Source/Engine/Content/WeakAssetReference.h | 2 +- .../Tools/MaterialGenerator/MaterialGenerator.Layer.cpp | 2 +- .../Engine/Tools/MaterialGenerator/MaterialGenerator.h | 2 +- Source/Engine/Visject/ShaderGraph.h | 2 +- Source/Engine/Visject/VisjectGraph.cpp | 2 +- Source/Engine/Visject/VisjectGraph.h | 4 ++-- 9 files changed, 11 insertions(+), 15 deletions(-) rename Source/Engine/Content/{Utilities => }/AssetsContainer.h (87%) diff --git a/Source/Engine/Content/AssetReference.h b/Source/Engine/Content/AssetReference.h index 658545d1a..40f57337d 100644 --- a/Source/Engine/Content/AssetReference.h +++ b/Source/Engine/Content/AssetReference.h @@ -193,7 +193,7 @@ public: FORCE_INLINE AssetReference& operator=(const Guid& id) { - OnSet((T*)LoadAsset(id, T::TypeInitializer)); + OnSet((T*)::LoadAsset(id, T::TypeInitializer)); return *this; } diff --git a/Source/Engine/Content/Assets/VisualScript.cpp b/Source/Engine/Content/Assets/VisualScript.cpp index 414d66870..5fd9d6f3f 100644 --- a/Source/Engine/Content/Assets/VisualScript.cpp +++ b/Source/Engine/Content/Assets/VisualScript.cpp @@ -3,6 +3,7 @@ #include "VisualScript.h" #include "Engine/Core/Log.h" #include "Engine/Core/Types/DataContainer.h" +#include "Engine/Content/Content.h" #include "Engine/Content/Factories/BinaryAssetFactory.h" #include "Engine/Scripting/MException.h" #include "Engine/Scripting/Scripting.h" diff --git a/Source/Engine/Content/Utilities/AssetsContainer.h b/Source/Engine/Content/AssetsContainer.h similarity index 87% rename from Source/Engine/Content/Utilities/AssetsContainer.h rename to Source/Engine/Content/AssetsContainer.h index f2c56d747..aefaec8d8 100644 --- a/Source/Engine/Content/Utilities/AssetsContainer.h +++ b/Source/Engine/Content/AssetsContainer.h @@ -2,10 +2,9 @@ #pragma once -#include "Engine/Content/Content.h" #include "Engine/Core/Collections/Array.h" #include "Engine/Content/AssetReference.h" -#include "../Asset.h" +#include "Asset.h" /// /// Assets Container allows to load collection of assets and keep references to them. @@ -27,13 +26,9 @@ public: if (e.GetID() == id) return (T*)e.Get(); } - - auto asset = Content::LoadAsync(id); + auto asset = (T*)::LoadAsset(id, T::TypeInitializer); if (asset) - { Add(asset); - } - return asset; } diff --git a/Source/Engine/Content/WeakAssetReference.h b/Source/Engine/Content/WeakAssetReference.h index 76f6b1fff..4943fd0b5 100644 --- a/Source/Engine/Content/WeakAssetReference.h +++ b/Source/Engine/Content/WeakAssetReference.h @@ -158,7 +158,7 @@ public: FORCE_INLINE WeakAssetReference& operator=(const Guid& id) { - OnSet((T*)LoadAsset(id, T::TypeInitializer)); + OnSet((T*)::LoadAsset(id, T::TypeInitializer)); return *this; } diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Layer.cpp b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Layer.cpp index 36accc384..8f01ef271 100644 --- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Layer.cpp +++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Layer.cpp @@ -271,7 +271,7 @@ void MaterialGenerator::prepareLayer(MaterialLayer* layer, bool allowVisiblePara mp.Type = MaterialParameterType::Texture; // Special case for Normal Maps - auto asset = Content::LoadAsync((Guid)param->Value); + auto asset = (Texture*)::LoadAsset((Guid)param->Value, Texture::TypeInitializer); if (asset && !asset->WaitForLoaded() && asset->IsNormalMap()) mp.Type = MaterialParameterType::NormalMap; } diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.h b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.h index bee1efca4..157502224 100644 --- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.h +++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.h @@ -6,7 +6,7 @@ #include "Engine/Graphics/Materials/MaterialInfo.h" #include "Engine/Graphics/Materials/MaterialParams.h" -#include "Engine/Content/Utilities/AssetsContainer.h" +#include "Engine/Content/AssetsContainer.h" #include "MaterialLayer.h" #include "Types.h" diff --git a/Source/Engine/Visject/ShaderGraph.h b/Source/Engine/Visject/ShaderGraph.h index 1ed95918a..fe24602cc 100644 --- a/Source/Engine/Visject/ShaderGraph.h +++ b/Source/Engine/Visject/ShaderGraph.h @@ -10,7 +10,7 @@ #include "Engine/Core/Collections/HashSet.h" #include "Engine/Utilities/TextWriter.h" #include "Engine/Graphics/Materials/MaterialParams.h" -#include "Engine/Content/Utilities/AssetsContainer.h" +#include "Engine/Content/AssetsContainer.h" #include "Engine/Animations/Curve.h" #define SHADER_GRAPH_MAX_CALL_STACK 100 diff --git a/Source/Engine/Visject/VisjectGraph.cpp b/Source/Engine/Visject/VisjectGraph.cpp index aafc4e9c9..abe4436dd 100644 --- a/Source/Engine/Visject/VisjectGraph.cpp +++ b/Source/Engine/Visject/VisjectGraph.cpp @@ -723,7 +723,7 @@ void VisjectExecutor::ProcessGroupTools(Box* box, Node* node, Value& value) // Asset Reference case 18: { - value = Content::LoadAsync((Guid)node->Values[0]); + value = ::LoadAsset((Guid)node->Values[0], Asset::TypeInitializer); break; } // To String diff --git a/Source/Engine/Visject/VisjectGraph.h b/Source/Engine/Visject/VisjectGraph.h index 79c923871..7be06566e 100644 --- a/Source/Engine/Visject/VisjectGraph.h +++ b/Source/Engine/Visject/VisjectGraph.h @@ -8,7 +8,7 @@ #include "Engine/Core/Math/Vector4.h" #include "Engine/Content/Asset.h" #include "Engine/Content/AssetReference.h" -#include "Engine/Content/Utilities/AssetsContainer.h" +#include "Engine/Content/AssetsContainer.h" #include "Engine/Animations/Curve.h" #define VISJECT_GRAPH_NODE_MAX_ASSETS 14 @@ -204,7 +204,7 @@ public: // Get Gameplay Global case 16: { - n->Assets[0] = Content::LoadAsync((Guid)n->Values[0]); + n->Assets[0] = ::LoadAsset((Guid)n->Values[0], Asset::TypeInitializer); break; } } From b402232a47cc3f8a3e6687273412d65b4f40b3f7 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 26 Feb 2021 15:41:04 +0100 Subject: [PATCH 15/19] Move IES profile importer into ContentImporters module --- .../ImportIES.cpp} | 16 ++++++++++------ .../IESLoader.h => ContentImporters/ImportIES.h} | 6 +++++- Source/Engine/ContentImporters/ImportTexture.cpp | 4 ++-- 3 files changed, 17 insertions(+), 9 deletions(-) rename Source/Engine/{Content/Utilities/IESLoader.cpp => ContentImporters/ImportIES.cpp} (96%) rename Source/Engine/{Content/Utilities/IESLoader.h => ContentImporters/ImportIES.h} (95%) diff --git a/Source/Engine/Content/Utilities/IESLoader.cpp b/Source/Engine/ContentImporters/ImportIES.cpp similarity index 96% rename from Source/Engine/Content/Utilities/IESLoader.cpp rename to Source/Engine/ContentImporters/ImportIES.cpp index 271ab3d5e..b4c9ea433 100644 --- a/Source/Engine/Content/Utilities/IESLoader.cpp +++ b/Source/Engine/ContentImporters/ImportIES.cpp @@ -1,9 +1,11 @@ // Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. +#if COMPILE_WITH_ASSETS_IMPORTER + +#include "ImportIES.h" #include "Engine/Core/Log.h" #include "Engine/Core/RandomStream.h" #include "Engine/Core/Math/Packed.h" -#include "IESLoader.h" #define MAX_LINE 200 @@ -84,7 +86,7 @@ static bool ReadLine(const uint8*& bufferPos, int32& ret) #define PARSE_FLOAT(x) float x; if (!ReadFloat(bufferPos, x)) { return true; } #define PARSE_INT(x) int32 x; if (!ReadLine(bufferPos, x)) { return true; } -bool IESLoader::Load(const byte* buffer) +bool ImportIES::Load(const byte* buffer) { // Referenced IES file format: // http://www.ltblight.com/English.lproj/LTBLhelp/pages/iesformat.html @@ -214,7 +216,7 @@ bool IESLoader::Load(const byte* buffer) #undef PARSE_FLOAT #undef PARSE_INT -float IESLoader::ExtractInR16(Array& output) +float ImportIES::ExtractInR16(Array& output) { const uint32 width = GetWidth(); const uint32 height = GetHeight(); @@ -263,14 +265,14 @@ float IESLoader::ExtractInR16(Array& output) return maxValue / integral; } -float IESLoader::InterpolatePoint(int32 x, int32 y) const +float ImportIES::InterpolatePoint(int32 x, int32 y) const { x %= _hAngles.Count(); y %= _vAngles.Count(); return _candalaValues[y + _vAngles.Count() * x]; } -float IESLoader::InterpolateBilinear(float x, float y) const +float ImportIES::InterpolateBilinear(float x, float y) const { const int32 xInt = static_cast(x); const int32 yInt = static_cast(y); @@ -289,7 +291,7 @@ float IESLoader::InterpolateBilinear(float x, float y) const return Math::Lerp(p0, p1, xFrac); } -float IESLoader::ComputeFilterPos(float value, const Array& sortedValues) +float ImportIES::ComputeFilterPos(float value, const Array& sortedValues) { ASSERT(sortedValues.HasItems()); @@ -336,3 +338,5 @@ float IESLoader::ComputeFilterPos(float value, const Array& sortedValues) return startPos + fraction; } + +#endif diff --git a/Source/Engine/Content/Utilities/IESLoader.h b/Source/Engine/ContentImporters/ImportIES.h similarity index 95% rename from Source/Engine/Content/Utilities/IESLoader.h rename to Source/Engine/ContentImporters/ImportIES.h index f25a9d7ff..158613958 100644 --- a/Source/Engine/Content/Utilities/IESLoader.h +++ b/Source/Engine/ContentImporters/ImportIES.h @@ -2,13 +2,15 @@ #pragma once +#if COMPILE_WITH_ASSETS_IMPORTER + #include "Engine/Core/Types/BaseTypes.h" #include "Engine/Core/Collections/Array.h" /// /// Utility for loading IES files and extract light emission information. /// -class IESLoader +class ImportIES { private: @@ -56,3 +58,5 @@ private: float InterpolateBilinear(float x, float y) const; static float ComputeFilterPos(float value, const Array& sortedValues); }; + +#endif diff --git a/Source/Engine/ContentImporters/ImportTexture.cpp b/Source/Engine/ContentImporters/ImportTexture.cpp index 4537d496f..7daa62d9d 100644 --- a/Source/Engine/ContentImporters/ImportTexture.cpp +++ b/Source/Engine/ContentImporters/ImportTexture.cpp @@ -13,7 +13,7 @@ #include "Engine/Graphics/Textures/TextureUtils.h" #include "Engine/Graphics/PixelFormatExtensions.h" #include "Engine/Content/Storage/ContentStorageManager.h" -#include "Engine/Content/Utilities/IESLoader.h" +#include "Engine/ContentImporters/ImportIES.h" #include "Engine/Content/Assets/CubeTexture.h" #include "Engine/Content/Assets/IESProfile.h" #include "Engine/Content/Assets/Texture.h" @@ -527,7 +527,7 @@ CreateAssetResult ImportTexture::ImportIES(class CreateAssetContext& context) fileData.Add('\0'); // Load IES profile data - IESLoader loader; + ::ImportIES loader; if (loader.Load(fileData.Get())) { return CreateAssetResult::Error; From 8b4a0016413406eb055047ddc9e4118848fad8ad Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 26 Feb 2021 15:42:46 +0100 Subject: [PATCH 16/19] Move Win32 GetBatteryInfo into Windows and UWP platforms impl --- Source/Engine/Platform/UWP/UWPPlatform.cpp | 16 ++++++++++++++++ Source/Engine/Platform/UWP/UWPPlatform.h | 1 + Source/Engine/Platform/Win32/Win32Platform.cpp | 16 ---------------- Source/Engine/Platform/Win32/Win32Platform.h | 1 - .../Engine/Platform/Windows/WindowsPlatform.cpp | 16 ++++++++++++++++ Source/Engine/Platform/Windows/WindowsPlatform.h | 1 + 6 files changed, 34 insertions(+), 17 deletions(-) diff --git a/Source/Engine/Platform/UWP/UWPPlatform.cpp b/Source/Engine/Platform/UWP/UWPPlatform.cpp index ed01948aa..522d5db15 100644 --- a/Source/Engine/Platform/UWP/UWPPlatform.cpp +++ b/Source/Engine/Platform/UWP/UWPPlatform.cpp @@ -6,6 +6,7 @@ #include "Engine/Engine/Engine.h" #include "Engine/Platform/MessageBox.h" #include "Engine/Profiler/ProfilerCPU.h" +#include "Engine/Platform/BatteryInfo.h" #include "Engine/Input/Input.h" #include "Engine/Core/Log.h" #include "UWPWindow.h" @@ -114,6 +115,21 @@ void UWPPlatform::Exit() Win32Platform::Exit(); } +BatteryInfo UWPPlatform::GetBatteryInfo() +{ + BatteryInfo info; + SYSTEM_POWER_STATUS status; + GetSystemPowerStatus(&status); + info.BatteryLifePercent = (float)status.BatteryLifePercent / 255.0f; + if (status.BatteryFlag & 8) + info.State = BatteryInfo::States::BatteryCharging; + else if (status.BatteryFlag & 1 || status.BatteryFlag & 2 || status.BatteryFlag & 4) + info.State = BatteryInfo::States::BatteryDischarging; + else if (status.ACLineStatus == 1 || status.BatteryFlag & 128) + info.State = BatteryInfo::States::Connected; + return info; +} + int32 UWPPlatform::GetDpi() { return SystemDpi; diff --git a/Source/Engine/Platform/UWP/UWPPlatform.h b/Source/Engine/Platform/UWP/UWPPlatform.h index 6a04ac94c..9a946ce98 100644 --- a/Source/Engine/Platform/UWP/UWPPlatform.h +++ b/Source/Engine/Platform/UWP/UWPPlatform.h @@ -30,6 +30,7 @@ public: static void Tick(); static void BeforeExit(); static void Exit(); + static BatteryInfo GetBatteryInfo(); static int32 GetDpi(); static String GetUserLocaleName(); static String GetComputerName(); diff --git a/Source/Engine/Platform/Win32/Win32Platform.cpp b/Source/Engine/Platform/Win32/Win32Platform.cpp index d2b6163e1..e01a8a8e1 100644 --- a/Source/Engine/Platform/Win32/Win32Platform.cpp +++ b/Source/Engine/Platform/Win32/Win32Platform.cpp @@ -5,7 +5,6 @@ #include "Engine/Platform/Platform.h" #include "Engine/Platform/MemoryStats.h" #include "Engine/Platform/CPUInfo.h" -#include "Engine/Platform/BatteryInfo.h" #include "Engine/Core/Types/Guid.h" #include "Engine/Core/Types/String.h" #include "Engine/Core/Math/Math.h" @@ -341,21 +340,6 @@ bool Win32Platform::Is64BitPlatform() #endif } -BatteryInfo Win32Platform::GetBatteryInfo() -{ - BatteryInfo info; - SYSTEM_POWER_STATUS status; - GetSystemPowerStatus(&status); - info.BatteryLifePercent = (float)status.BatteryLifePercent / 255.0f; - if (status.BatteryFlag & 8) - info.State = BatteryInfo::States::BatteryCharging; - else if (status.BatteryFlag & 1 || status.BatteryFlag & 2 || status.BatteryFlag & 4) - info.State = BatteryInfo::States::BatteryDischarging; - else if (status.ACLineStatus == 1 || status.BatteryFlag & 128) - info.State = BatteryInfo::States::Connected; - return info; -} - CPUInfo Win32Platform::GetCPUInfo() { return CpuInfo; diff --git a/Source/Engine/Platform/Win32/Win32Platform.h b/Source/Engine/Platform/Win32/Win32Platform.h index 0b895ae40..02a7d4045 100644 --- a/Source/Engine/Platform/Win32/Win32Platform.h +++ b/Source/Engine/Platform/Win32/Win32Platform.h @@ -33,7 +33,6 @@ public: static void* AllocatePages(uint64 numPages, uint64 pageSize); static void FreePages(void* ptr); static bool Is64BitPlatform(); - static BatteryInfo GetBatteryInfo(); static CPUInfo GetCPUInfo(); static int32 GetCacheLineSize(); static MemoryStats GetMemoryStats(); diff --git a/Source/Engine/Platform/Windows/WindowsPlatform.cpp b/Source/Engine/Platform/Windows/WindowsPlatform.cpp index 83fafdf3e..7cea15622 100644 --- a/Source/Engine/Platform/Windows/WindowsPlatform.cpp +++ b/Source/Engine/Platform/Windows/WindowsPlatform.cpp @@ -7,6 +7,7 @@ #include "Engine/Platform/CreateWindowSettings.h" #include "Engine/Platform/WindowsManager.h" #include "Engine/Platform/MemoryStats.h" +#include "Engine/Platform/BatteryInfo.h" #include "Engine/Engine/Globals.h" #include "Engine/Core/Log.h" #include "Engine/Core/Collections/Dictionary.h" @@ -680,6 +681,21 @@ void WindowsPlatform::SetHighDpiAwarenessEnabled(bool enable) FreeLibrary(shCoreDll); } +BatteryInfo WindowsPlatform::GetBatteryInfo() +{ + BatteryInfo info; + SYSTEM_POWER_STATUS status; + GetSystemPowerStatus(&status); + info.BatteryLifePercent = (float)status.BatteryLifePercent / 255.0f; + if (status.BatteryFlag & 8) + info.State = BatteryInfo::States::BatteryCharging; + else if (status.BatteryFlag & 1 || status.BatteryFlag & 2 || status.BatteryFlag & 4) + info.State = BatteryInfo::States::BatteryDischarging; + else if (status.ACLineStatus == 1 || status.BatteryFlag & 128) + info.State = BatteryInfo::States::Connected; + return info; +} + int32 WindowsPlatform::GetDpi() { return SystemDpi; diff --git a/Source/Engine/Platform/Windows/WindowsPlatform.h b/Source/Engine/Platform/Windows/WindowsPlatform.h index 94bab3f50..6a50ede5f 100644 --- a/Source/Engine/Platform/Windows/WindowsPlatform.h +++ b/Source/Engine/Platform/Windows/WindowsPlatform.h @@ -64,6 +64,7 @@ public: static bool IsDebuggerPresent(); #endif static void SetHighDpiAwarenessEnabled(bool enable); + static BatteryInfo GetBatteryInfo(); static int32 GetDpi(); static String GetUserLocaleName(); static String GetComputerName(); From 3bc664df371bfe5dcf47232fd88b9509a1056a64 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sat, 27 Feb 2021 00:55:49 +0100 Subject: [PATCH 17/19] Format code --- Source/Engine/Core/Math/Quaternion.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Source/Engine/Core/Math/Quaternion.cs b/Source/Engine/Core/Math/Quaternion.cs index 7dc5b6826..125b5b36c 100644 --- a/Source/Engine/Core/Math/Quaternion.cs +++ b/Source/Engine/Core/Math/Quaternion.cs @@ -967,17 +967,18 @@ namespace FlaxEngine Matrix3x3.LookAt(ref eye, ref target, ref up, out var matrix); RotationMatrix(ref matrix, out result); } - + /// /// Creates a left-handed, look-at quaternion. /// /// The position of the viewer's eye. /// The camera look-at target. /// The created look-at quaternion. - public static Quaternion LookAt(Vector3 eye, Vector3 target){ + public static Quaternion LookAt(Vector3 eye, Vector3 target) + { return LookAt(eye, target, Vector3.Up); } - + /// /// Creates a left-handed, look-at quaternion. /// @@ -1012,7 +1013,7 @@ namespace FlaxEngine { return RotationLookAt(forward, Vector3.Up); } - + /// /// Creates a left-handed, look-at quaternion. /// From 84015f78fced14436c09a3c70b5abb50b394e477 Mon Sep 17 00:00:00 2001 From: Nejcraft Date: Wed, 24 Feb 2021 14:28:46 +0100 Subject: [PATCH 18/19] Ported Vecctor3 ClampLength to others and remade it using refs --- Source/Engine/Core/Math/Vector2.cs | 48 ++++++++++++++++++++++++++- Source/Engine/Core/Math/Vector3.cs | 23 +++++++------ Source/Engine/Core/Math/Vector4.cs | 52 ++++++++++++++++++++++++++++++ 3 files changed, 112 insertions(+), 11 deletions(-) diff --git a/Source/Engine/Core/Math/Vector2.cs b/Source/Engine/Core/Math/Vector2.cs index 768007180..e34ccc2cf 100644 --- a/Source/Engine/Core/Math/Vector2.cs +++ b/Source/Engine/Core/Math/Vector2.cs @@ -834,7 +834,53 @@ namespace FlaxEngine value.Normalize(); return value; } - + + /// + /// Makes sure that Length of the output vector is always below max and above 0. + /// + /// Input Vector. + /// Max Length + public static Vector2 ClampLength(Vector2 vector, float max) + { + return ClampLength(vector, 0, max); + } + /// + /// Makes sure that Length of the output vector is always below max and above min. + /// + /// Input Vector. + /// Min Length + /// Max Length + public static Vector2 ClampLength(Vector2 vector, float min, float max) + { + ClampLength(ref vector, min, max, out Vector2 retVect); + return retVect; + } + /// + /// Makes sure that Length of the output vector is always below max and above min. + /// + /// Input Vector. + /// Min Length + /// Max Length + /// The Return Vector + public static void ClampLength(ref Vector2 vector, float min, float max, out Vector2 retVect) + { + retVect.X = vector.X; + retVect.Y = vector.Y; + + float lenSq = retVect.LengthSquared; + if (lenSq > max * max) + { + float scaleFactor = max / (float)Math.Sqrt(lenSq); + retVect.X = retVect.X * scaleFactor; + retVect.Y = retVect.Y * scaleFactor; + } + if (lenSq < min * min) + { + float scaleFactor = min / (float)Math.Sqrt(lenSq); + retVect.X = retVect.X * scaleFactor; + retVect.Y = retVect.Y * scaleFactor; + } + } /// /// Returns the vector with components rounded to the nearest integer. /// diff --git a/Source/Engine/Core/Math/Vector3.cs b/Source/Engine/Core/Math/Vector3.cs index be885590a..bbd644f98 100644 --- a/Source/Engine/Core/Math/Vector3.cs +++ b/Source/Engine/Core/Math/Vector3.cs @@ -1001,7 +1001,7 @@ namespace FlaxEngine /// Max Length public static Vector3 ClampLength(Vector3 vector, float min, float max) { - ClampLength(vector, min, max, out Vector3 retVect); + ClampLength(ref vector, min, max, out Vector3 retVect); return retVect; } /// @@ -1011,24 +1011,27 @@ namespace FlaxEngine /// Min Length /// Max Length /// The Return Vector - public static void ClampLength(Vector3 vector, float min, float max, out Vector3 retVect) + public static void ClampLength(ref Vector3 vector, float min, float max, out Vector3 retVect) { - float lenSq = vector.LengthSquared; + retVect.X = vector.X; + retVect.Y = vector.Y; + retVect.Z = vector.Z; + + float lenSq = retVect.LengthSquared; if (lenSq > max * max) { float scaleFactor = max / (float)Math.Sqrt(lenSq); - retVect.X = vector.X * scaleFactor; - retVect.Y = vector.Y * scaleFactor; - retVect.Z = vector.Z * scaleFactor; + retVect.X = retVect.X * scaleFactor; + retVect.Y = retVect.Y * scaleFactor; + retVect.Z = retVect.Z * scaleFactor; } if (lenSq < min * min) { float scaleFactor = min / (float)Math.Sqrt(lenSq); - retVect.X = vector.X * scaleFactor; - retVect.Y = vector.Y * scaleFactor; - retVect.Z = vector.Z * scaleFactor; + retVect.X = retVect.X * scaleFactor; + retVect.Y = retVect.Y * scaleFactor; + retVect.Z = retVect.Z * scaleFactor; } - return retVect; } /// /// Performs a linear interpolation between two vectors. diff --git a/Source/Engine/Core/Math/Vector4.cs b/Source/Engine/Core/Math/Vector4.cs index 8fc7ca298..cc86164c4 100644 --- a/Source/Engine/Core/Math/Vector4.cs +++ b/Source/Engine/Core/Math/Vector4.cs @@ -794,6 +794,58 @@ namespace FlaxEngine return value; } + /// + /// Makes sure that Length of the output vector is always below max and above 0. + /// + /// Input Vector. + /// Max Length + public static Vector4 ClampLength(Vector4 vector, float max) + { + return ClampLength(vector, 0, max); + } + /// + /// Makes sure that Length of the output vector is always below max and above min. + /// + /// Input Vector. + /// Min Length + /// Max Length + public static Vector4 ClampLength(Vector4 vector, float min, float max) + { + ClampLength(ref vector, min, max, out Vector4 retVect); + return retVect; + } + /// + /// Makes sure that Length of the output vector is always below max and above min. + /// + /// Input Vector. + /// Min Length + /// Max Length + /// The Return Vector + public static void ClampLength(ref Vector4 vector, float min, float max, out Vector4 retVect) + { + retVect.X = vector.X; + retVect.Y = vector.Y; + retVect.Z = vector.Z; + retVect.W = vector.W; + + float lenSq = retVect.LengthSquared; + if (lenSq > max * max) + { + float scaleFactor = max / (float)Math.Sqrt(lenSq); + retVect.X = retVect.X * scaleFactor; + retVect.Y = retVect.Y * scaleFactor; + retVect.Z = retVect.Z * scaleFactor; + retVect.W = retVect.W * scaleFactor; + } + if (lenSq < min * min) + { + float scaleFactor = min / (float)Math.Sqrt(lenSq); + retVect.X = retVect.X * scaleFactor; + retVect.Y = retVect.Y * scaleFactor; + retVect.Z = retVect.Z * scaleFactor; + retVect.W = retVect.W * scaleFactor; + } + } /// /// Performs a linear interpolation between two vectors. /// From ca3948ad6956fdd20675874ec17a2373ccd72796 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sat, 27 Feb 2021 16:29:30 +0100 Subject: [PATCH 19/19] Format code --- Source/Engine/Core/Math/Vector2.cs | 9 ++++++--- Source/Engine/Core/Math/Vector3.cs | 9 ++++++--- Source/Engine/Core/Math/Vector4.cs | 7 +++++-- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/Source/Engine/Core/Math/Vector2.cs b/Source/Engine/Core/Math/Vector2.cs index efbda7a42..c0b84ca04 100644 --- a/Source/Engine/Core/Math/Vector2.cs +++ b/Source/Engine/Core/Math/Vector2.cs @@ -832,7 +832,7 @@ namespace FlaxEngine value.Normalize(); return value; } - + /// /// Makes sure that Length of the output vector is always below max and above 0. /// @@ -840,8 +840,9 @@ namespace FlaxEngine /// Max Length public static Vector2 ClampLength(Vector2 vector, float max) { - return ClampLength(vector, 0, max); + return ClampLength(vector, 0, max); } + /// /// Makes sure that Length of the output vector is always below max and above min. /// @@ -853,6 +854,7 @@ namespace FlaxEngine ClampLength(ref vector, min, max, out Vector2 retVect); return retVect; } + /// /// Makes sure that Length of the output vector is always below max and above min. /// @@ -864,7 +866,7 @@ namespace FlaxEngine { retVect.X = vector.X; retVect.Y = vector.Y; - + float lenSq = retVect.LengthSquared; if (lenSq > max * max) { @@ -879,6 +881,7 @@ namespace FlaxEngine retVect.Y = retVect.Y * scaleFactor; } } + /// /// Returns the vector with components rounded to the nearest integer. /// diff --git a/Source/Engine/Core/Math/Vector3.cs b/Source/Engine/Core/Math/Vector3.cs index b871c0642..2674b30e6 100644 --- a/Source/Engine/Core/Math/Vector3.cs +++ b/Source/Engine/Core/Math/Vector3.cs @@ -991,7 +991,7 @@ namespace FlaxEngine value.Normalize(); return value; } - + /// /// Makes sure that Length of the output vector is always below max and above 0. /// @@ -999,8 +999,9 @@ namespace FlaxEngine /// Max Length public static Vector3 ClampLength(Vector3 vector, float max) { - return ClampLength(vector, 0, max); + return ClampLength(vector, 0, max); } + /// /// Makes sure that Length of the output vector is always below max and above min. /// @@ -1012,6 +1013,7 @@ namespace FlaxEngine ClampLength(ref vector, min, max, out Vector3 retVect); return retVect; } + /// /// Makes sure that Length of the output vector is always below max and above min. /// @@ -1024,7 +1026,7 @@ namespace FlaxEngine retVect.X = vector.X; retVect.Y = vector.Y; retVect.Z = vector.Z; - + float lenSq = retVect.LengthSquared; if (lenSq > max * max) { @@ -1041,6 +1043,7 @@ namespace FlaxEngine retVect.Z = retVect.Z * scaleFactor; } } + /// /// Performs a linear interpolation between two vectors. /// diff --git a/Source/Engine/Core/Math/Vector4.cs b/Source/Engine/Core/Math/Vector4.cs index d01214de3..99430072d 100644 --- a/Source/Engine/Core/Math/Vector4.cs +++ b/Source/Engine/Core/Math/Vector4.cs @@ -799,8 +799,9 @@ namespace FlaxEngine /// Max Length public static Vector4 ClampLength(Vector4 vector, float max) { - return ClampLength(vector, 0, max); + return ClampLength(vector, 0, max); } + /// /// Makes sure that Length of the output vector is always below max and above min. /// @@ -812,6 +813,7 @@ namespace FlaxEngine ClampLength(ref vector, min, max, out Vector4 retVect); return retVect; } + /// /// Makes sure that Length of the output vector is always below max and above min. /// @@ -825,7 +827,7 @@ namespace FlaxEngine retVect.Y = vector.Y; retVect.Z = vector.Z; retVect.W = vector.W; - + float lenSq = retVect.LengthSquared; if (lenSq > max * max) { @@ -844,6 +846,7 @@ namespace FlaxEngine retVect.W = retVect.W * scaleFactor; } } + /// /// Performs a linear interpolation between two vectors. ///