From 6dcadb5131805fdcf6a8149070539e0ddb9e1a72 Mon Sep 17 00:00:00 2001 From: NoriteSC <53096989+NoriteSC@users.noreply.github.com> Date: Wed, 8 Nov 2023 18:34:17 +0100 Subject: [PATCH 01/31] Compacted UpdateTransform Matrix math --- Source/Engine/UI/GUI/Control.Bounds.cs | 53 +++++++++++++++++++------- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/Source/Engine/UI/GUI/Control.Bounds.cs b/Source/Engine/UI/GUI/Control.Bounds.cs index c6260b648..272b1c5f1 100644 --- a/Source/Engine/UI/GUI/Control.Bounds.cs +++ b/Source/Engine/UI/GUI/Control.Bounds.cs @@ -487,9 +487,12 @@ namespace FlaxEngine.GUI public void UpdateTransform() { // Actual pivot and negative pivot - Float2.Multiply(ref _pivot, ref _bounds.Size, out var v1); - Float2.Negate(ref v1, out var v2); - Float2.Add(ref v1, ref _bounds.Location, out v1); + //Float2.Multiply(ref _pivot, ref _bounds.Size, out var v1); + //Float2.Negate(ref v1, out var v2); + //Float2.Add(ref v1, ref _bounds.Location, out v1); + var v1 = _pivot * _bounds.Size; + var v2 = -v1; + v1 += _bounds.Location; // ------ Matrix3x3 based version: @@ -518,18 +521,42 @@ namespace FlaxEngine.GUI // ------ Matrix2x2 based version: // 2D transformation - Matrix2x2.Scale(ref _scale, out Matrix2x2 m1); - Matrix2x2.Shear(ref _shear, out Matrix2x2 m2); - Matrix2x2.Multiply(ref m1, ref m2, out m1); - Matrix2x2.Rotation(Mathf.DegreesToRadians * _rotation, out m2); - Matrix2x2.Multiply(ref m1, ref m2, out m1); + + //Matrix2x2.Scale(ref _scale, out Matrix2x2 m1); + //Matrix2x2.Shear(ref _shear, out Matrix2x2 m2); + //Matrix2x2.Multiply(ref m1, ref m2, out m1); + + // Scale and Shear + Matrix3x3 m1 = new Matrix3x3 + ( + _scale.X, + _scale.X * (_shear.X == 0 ? 0 : (1.0f / Mathf.Tan(Mathf.DegreesToRadians * (90 - Mathf.Clamp(_shear.X, -89.0f, 89.0f))))), + 0, + _scale.Y * (_shear.Y == 0 ? 0 : (1.0f / Mathf.Tan(Mathf.DegreesToRadians * (90 - Mathf.Clamp(_shear.Y, -89.0f, 89.0f))))), + _scale.Y, + 0, 0, 0, 1 + ); + + + //Matrix2x2.Rotation(Mathf.DegreesToRadians * _rotation, out m2); + float sin = Mathf.Sin(Mathf.DegreesToRadians * _rotation); + float cos = Mathf.Cos(Mathf.DegreesToRadians * _rotation); + + //Matrix2x2.Multiply(ref m1, ref m2, out m1); + m1.M11 = (_scale.X * cos) + (m1.M12 * -sin); + m1.M12 = (_scale.X * sin) + (m1.M12 * cos); + m1.M21 = (m1.M21 * cos) + (_scale.Y * -sin); + m1.M22 = (m1.M21 * sin) + (_scale.Y * cos); // Mix all the stuff - Matrix3x3.Translation2D(ref v2, out Matrix3x3 m3); - Matrix3x3 m4 = (Matrix3x3)m1; - Matrix3x3.Multiply(ref m3, ref m4, out m3); - Matrix3x3.Translation2D(ref v1, out m4); - Matrix3x3.Multiply(ref m3, ref m4, out _cachedTransform); + //Matrix3x3.Translation2D(ref v2, out Matrix3x3 m3); + //Matrix3x3 m4 = (Matrix3x3)m1; + //Matrix3x3.Multiply(ref m3, ref m4, out m3); + //Matrix3x3.Translation2D(ref v1, out Matrix3x3 m4); + //Matrix3x3.Multiply(ref m3, ref m4, out _cachedTransform); + m1.M31 = (v2.X * m1.M11) + (v2.Y * m1.M21) + v1.X; + m1.M32 = (v2.X * m1.M12) + (v2.Y * m1.M22) + v1.Y; + _cachedTransform = m1; // Cache inverted transform Matrix3x3.Invert(ref _cachedTransform, out _cachedTransformInv); From ea3f02f810b04c60becc22b8d6acb7ef3260a690 Mon Sep 17 00:00:00 2001 From: NoriteSC <53096989+NoriteSC@users.noreply.github.com> Date: Thu, 9 Nov 2023 17:34:07 +0100 Subject: [PATCH 02/31] Fix rotacion sheers the UI element --- Source/Engine/UI/GUI/Control.Bounds.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Engine/UI/GUI/Control.Bounds.cs b/Source/Engine/UI/GUI/Control.Bounds.cs index 272b1c5f1..c9d20bfae 100644 --- a/Source/Engine/UI/GUI/Control.Bounds.cs +++ b/Source/Engine/UI/GUI/Control.Bounds.cs @@ -545,14 +545,14 @@ namespace FlaxEngine.GUI //Matrix2x2.Multiply(ref m1, ref m2, out m1); m1.M11 = (_scale.X * cos) + (m1.M12 * -sin); m1.M12 = (_scale.X * sin) + (m1.M12 * cos); - m1.M21 = (m1.M21 * cos) + (_scale.Y * -sin); + float m21 = (m1.M21 * cos) + (_scale.Y * -sin); m1.M22 = (m1.M21 * sin) + (_scale.Y * cos); - + m1.M21 = m21; // Mix all the stuff //Matrix3x3.Translation2D(ref v2, out Matrix3x3 m3); //Matrix3x3 m4 = (Matrix3x3)m1; //Matrix3x3.Multiply(ref m3, ref m4, out m3); - //Matrix3x3.Translation2D(ref v1, out Matrix3x3 m4); + //Matrix3x3.Translation2D(ref v1, out m4); //Matrix3x3.Multiply(ref m3, ref m4, out _cachedTransform); m1.M31 = (v2.X * m1.M11) + (v2.Y * m1.M21) + v1.X; m1.M32 = (v2.X * m1.M12) + (v2.Y * m1.M22) + v1.Y; From d533cf554afc07a7d47cf7ee76b8bd9cd8d24496 Mon Sep 17 00:00:00 2001 From: "Mr. Capybara" Date: Tue, 14 Nov 2023 14:47:35 -0400 Subject: [PATCH 03/31] Avoid crash when try build navmesh with null scene --- Source/Engine/Navigation/NavMeshBuilder.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Source/Engine/Navigation/NavMeshBuilder.cpp b/Source/Engine/Navigation/NavMeshBuilder.cpp index b0959cb34..894dc1e52 100644 --- a/Source/Engine/Navigation/NavMeshBuilder.cpp +++ b/Source/Engine/Navigation/NavMeshBuilder.cpp @@ -1067,6 +1067,12 @@ void NavMeshBuilder::Update() void NavMeshBuilder::Build(Scene* scene, float timeoutMs) { + if (!scene) + { + LOG(Warning, "Could not generate navmesh without scene."); + return; + } + // Early out if scene is not using navigation if (scene->Navigation.Volumes.IsEmpty()) { @@ -1098,6 +1104,17 @@ void NavMeshBuilder::Build(Scene* scene, float timeoutMs) void NavMeshBuilder::Build(Scene* scene, const BoundingBox& dirtyBounds, float timeoutMs) { + if (!scene) + { + LOG(Warning, "Could not generate navmesh without scene."); + return; + } + if (!&dirtyBounds) + { + LOG(Warning, "Could not generate navmesh without dirty bounds."); + return; + } + // Early out if scene is not using navigation if (scene->Navigation.Volumes.IsEmpty()) { From 6aea001e94b37e51a81cd67761a6428424b8fd88 Mon Sep 17 00:00:00 2001 From: "Mr. Capybara" <79365912+RuanLucasGD@users.noreply.github.com> Date: Wed, 15 Nov 2023 12:49:20 -0300 Subject: [PATCH 04/31] Remove unnecessary check --- Source/Engine/Navigation/NavMeshBuilder.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Source/Engine/Navigation/NavMeshBuilder.cpp b/Source/Engine/Navigation/NavMeshBuilder.cpp index 894dc1e52..ccd9bef32 100644 --- a/Source/Engine/Navigation/NavMeshBuilder.cpp +++ b/Source/Engine/Navigation/NavMeshBuilder.cpp @@ -1109,11 +1109,6 @@ void NavMeshBuilder::Build(Scene* scene, const BoundingBox& dirtyBounds, float t LOG(Warning, "Could not generate navmesh without scene."); return; } - if (!&dirtyBounds) - { - LOG(Warning, "Could not generate navmesh without dirty bounds."); - return; - } // Early out if scene is not using navigation if (scene->Navigation.Volumes.IsEmpty()) From 307129b4a185c7838a56567bde0b4bf7c35d0d26 Mon Sep 17 00:00:00 2001 From: NoriteSC <53096989+NoriteSC@users.noreply.github.com> Date: Thu, 16 Nov 2023 11:50:44 +0100 Subject: [PATCH 05/31] added c++ PingPong and flipped sheer --- Source/Engine/Core/Math/Math.h | 11 +++++++++++ Source/Engine/UI/GUI/Control.Bounds.cs | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/Source/Engine/Core/Math/Math.h b/Source/Engine/Core/Math/Math.h index 276f64884..49a052771 100644 --- a/Source/Engine/Core/Math/Math.h +++ b/Source/Engine/Core/Math/Math.h @@ -890,6 +890,17 @@ namespace Math { return Lerp(a, b, alpha < 0.5f ? InterpCircularIn(0.f, 1.f, alpha * 2.f) * 0.5f : InterpCircularOut(0.f, 1.f, alpha * 2.f - 1.f) * 0.5f + 0.5f); } + /// + /// PingPongs the value , so that it is never larger than and never smaller than 0. + /// + /// + /// + /// + template + static FORCE_INLINE T PingPong(const T& t, T length) + { + return length - Abs(Repeat(t, length * 2.0f) - length); + } // Rotates position about the given axis by the given angle, in radians, and returns the offset to position Vector3 FLAXENGINE_API RotateAboutAxis(const Vector3& normalizedRotationAxis, float angle, const Vector3& positionOnAxis, const Vector3& position); diff --git a/Source/Engine/UI/GUI/Control.Bounds.cs b/Source/Engine/UI/GUI/Control.Bounds.cs index c9d20bfae..52a4f78f7 100644 --- a/Source/Engine/UI/GUI/Control.Bounds.cs +++ b/Source/Engine/UI/GUI/Control.Bounds.cs @@ -530,9 +530,9 @@ namespace FlaxEngine.GUI Matrix3x3 m1 = new Matrix3x3 ( _scale.X, - _scale.X * (_shear.X == 0 ? 0 : (1.0f / Mathf.Tan(Mathf.DegreesToRadians * (90 - Mathf.Clamp(_shear.X, -89.0f, 89.0f))))), + _scale.X * (_shear.Y == 0 ? 0 : (1.0f / Mathf.Tan(Mathf.DegreesToRadians * (90 - Mathf.Clamp(_shear.Y, -89.0f, 89.0f))))), 0, - _scale.Y * (_shear.Y == 0 ? 0 : (1.0f / Mathf.Tan(Mathf.DegreesToRadians * (90 - Mathf.Clamp(_shear.Y, -89.0f, 89.0f))))), + _scale.Y * (_shear.X == 0 ? 0 : (1.0f / Mathf.Tan(Mathf.DegreesToRadians * (90 - Mathf.Clamp(_shear.X, -89.0f, 89.0f))))), _scale.Y, 0, 0, 0, 1 ); From d33bf2fa6a31abe7f3020c3cfb8b25faafd0fac8 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 16 Nov 2023 13:55:45 +0100 Subject: [PATCH 06/31] Update docs comments based on https://github.com/FlaxEngine/FlaxDocs/pull/127 --- Source/Engine/Graphics/Enums.h | 14 +++--- Source/Engine/Graphics/PostProcessSettings.h | 46 +++++++++---------- .../Level/Actors/ExponentialHeightFog.h | 6 +-- 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/Source/Engine/Graphics/Enums.h b/Source/Engine/Graphics/Enums.h index 4d1422f96..bbf9c0de8 100644 --- a/Source/Engine/Graphics/Enums.h +++ b/Source/Engine/Graphics/Enums.h @@ -591,37 +591,37 @@ API_ENUM() enum class Quality : byte API_ENUM() enum class MaterialPostFxLocation : byte { /// - /// The 'after' post processing pass using LDR input frame. + /// Render the material after the post processing pass using *LDR* input frame. /// AfterPostProcessingPass = 0, /// - /// The 'before' post processing pass using HDR input frame. + /// Render the material before the post processing pass using *HDR* input frame. /// BeforePostProcessingPass = 1, /// - /// The 'before' forward pass but after GBuffer with HDR input frame. + /// Render the material before the forward pass but after *GBuffer* with *HDR* input frame. /// BeforeForwardPass = 2, /// - /// The 'after' custom post effects. + /// Render the material after custom post effects (scripted). /// AfterCustomPostEffects = 3, /// - /// The 'before' Reflections pass. After the Light pass. Can be used to implement a custom light types that accumulate lighting to the light buffer. + /// Render the material before the reflections pass but after the lighting pass using *HDR* input frame. It can be used to implement a custom light types that accumulate lighting to the light buffer. /// BeforeReflectionsPass = 4, /// - /// The 'after' AA filter pass. Rendering is done to the output backbuffer. + /// Render the material after anti-aliasing into the output backbuffer. /// AfterAntiAliasingPass = 5, /// - /// The 'after' forward pass but before any post processing. + /// Render the material after the forward pass but before any post processing. /// AfterForwardPass = 6, diff --git a/Source/Engine/Graphics/PostProcessSettings.h b/Source/Engine/Graphics/PostProcessSettings.h index d2ace6cea..1d695f353 100644 --- a/Source/Engine/Graphics/PostProcessSettings.h +++ b/Source/Engine/Graphics/PostProcessSettings.h @@ -447,13 +447,13 @@ API_STRUCT() struct FLAXENGINE_API BloomSettings : ISerializable bool Enabled = true; /// - /// Bloom effect strength. Value 0 disabled is, while higher values increase the effect. + /// Bloom effect strength. Set a value of 0 to disabled it, while higher values increase the effect. /// API_FIELD(Attributes="Limit(0, 20.0f, 0.01f), EditorOrder(1), PostProcessSetting((int)BloomSettingsOverride.Intensity)") float Intensity = 1.0f; /// - /// Minimum pixel brightness value to start blowing. Values below the threshold are skipped. + /// Minimum pixel brightness value to start blooming. Values below this threshold are skipped. /// API_FIELD(Attributes="Limit(0, 15.0f, 0.01f), EditorOrder(2), PostProcessSetting((int)BloomSettingsOverride.Threshold)") float Threshold = 3.0f; @@ -987,13 +987,13 @@ API_STRUCT() struct FLAXENGINE_API EyeAdaptationSettings : ISerializable float MaxBrightness = 2.0f; /// - /// The lower bound for the luminance histogram of the scene color. Value is in percent and limits the pixels below this brightness. Use values from range 60-80. Used only in AutomaticHistogram mode. + /// The lower bound for the luminance histogram of the scene color. This value is in percent and limits the pixels below this brightness. Use values in the range of 60-80. Used only in AutomaticHistogram mode. /// API_FIELD(Attributes="Limit(1, 99, 0.001f), EditorOrder(3), PostProcessSetting((int)EyeAdaptationSettingsOverride.HistogramLowPercent)") float HistogramLowPercent = 70.0f; /// - /// The upper bound for the luminance histogram of the scene color. Value is in percent and limits the pixels above this brightness. Use values from range 80-95. Used only in AutomaticHistogram mode. + /// The upper bound for the luminance histogram of the scene color. This value is in percent and limits the pixels above this brightness. Use values in the range of 80-95. Used only in AutomaticHistogram mode. /// API_FIELD(Attributes="Limit(1, 99, 0.001f), EditorOrder(3), PostProcessSetting((int)EyeAdaptationSettingsOverride.HistogramHighPercent)") float HistogramHighPercent = 98.0f; @@ -1091,13 +1091,13 @@ API_STRUCT() struct FLAXENGINE_API CameraArtifactsSettings : ISerializable Float3 VignetteColor = Float3(0, 0, 0.001f); /// - /// Controls shape of the vignette. Values near 0 produce rectangle shape. Higher values result in round shape. The default value is 0.125. + /// Controls the shape of the vignette. Values near 0 produce a rectangular shape. Higher values result in a rounder shape. The default value is 0.125. /// API_FIELD(Attributes="Limit(0.0001f, 2.0f, 0.001f), EditorOrder(2), PostProcessSetting((int)CameraArtifactsSettingsOverride.VignetteShapeFactor)") float VignetteShapeFactor = 0.125f; /// - /// Intensity of the grain filter. Value 0 hides it. The default value is 0.005. + /// Intensity of the grain filter. A value of 0 hides it. The default value is 0.005. /// API_FIELD(Attributes="Limit(0.0f, 2.0f, 0.005f), EditorOrder(3), PostProcessSetting((int)CameraArtifactsSettingsOverride.GrainAmount)") float GrainAmount = 0.006f; @@ -1109,19 +1109,19 @@ API_STRUCT() struct FLAXENGINE_API CameraArtifactsSettings : ISerializable float GrainParticleSize = 1.6f; /// - /// Speed of the grain particles animation. + /// Speed of the grain particle animation. /// API_FIELD(Attributes="Limit(0.0f, 10.0f, 0.01f), EditorOrder(5), PostProcessSetting((int)CameraArtifactsSettingsOverride.GrainSpeed)") float GrainSpeed = 1.0f; /// - /// Controls chromatic aberration effect strength. Value 0 hides it. + /// Controls the chromatic aberration effect strength. A value of 0 hides it. /// API_FIELD(Attributes="Limit(0.0f, 1.0f, 0.01f), EditorOrder(6), PostProcessSetting((int)CameraArtifactsSettingsOverride.ChromaticDistortion)") float ChromaticDistortion = 0.0f; /// - /// Screen tint color (alpha channel defines the blending factor). + /// Screen tint color (the alpha channel defines the blending factor). /// API_FIELD(Attributes="DefaultValue(typeof(Color), \"0,0,0,0\"), EditorOrder(7), PostProcessSetting((int)CameraArtifactsSettingsOverride.ScreenFadeColor)") Color ScreenFadeColor = Color::Transparent; @@ -1227,7 +1227,7 @@ API_STRUCT() struct FLAXENGINE_API LensFlaresSettings : ISerializable LensFlaresSettingsOverride OverrideFlags = Override::None; /// - /// Strength of the effect. Value 0 disabled it. + /// Strength of the effect. A value of 0 disables it. /// API_FIELD(Attributes="Limit(0, 10.0f, 0.01f), EditorOrder(0), PostProcessSetting((int)LensFlaresSettingsOverride.Intensity)") float Intensity = 1.0f; @@ -1281,7 +1281,7 @@ API_STRUCT() struct FLAXENGINE_API LensFlaresSettings : ISerializable SoftAssetReference LensDirt; /// - /// Fullscreen lens dirt intensity parameter. Allows to tune dirt visibility. + /// Fullscreen lens dirt intensity parameter. Allows tuning dirt visibility. /// API_FIELD(Attributes="Limit(0, 100, 0.01f), EditorOrder(9), PostProcessSetting((int)LensFlaresSettingsOverride.LensDirtIntensity)") float LensDirtIntensity = 1.0f; @@ -1419,13 +1419,13 @@ API_STRUCT() struct FLAXENGINE_API DepthOfFieldSettings : ISerializable DepthOfFieldSettingsOverride OverrideFlags = Override::None; /// - /// If checked, depth of field effect will be visible. + /// If checked, the depth of field effect will be visible. /// API_FIELD(Attributes="EditorOrder(0), PostProcessSetting((int)DepthOfFieldSettingsOverride.Enabled)") bool Enabled = false; /// - /// The blur intensity in the out-of-focus areas. Allows reducing blur amount by scaling down the Gaussian Blur radius. Normalized to range 0-1. + /// The blur intensity in the out-of-focus areas. Allows reducing the blur amount by scaling down the Gaussian Blur radius. Normalized to range 0-1. /// API_FIELD(Attributes="Limit(0, 1, 0.01f), EditorOrder(1), PostProcessSetting((int)DepthOfFieldSettingsOverride.BlurStrength)") float BlurStrength = 1.0f; @@ -1479,7 +1479,7 @@ API_STRUCT() struct FLAXENGINE_API DepthOfFieldSettings : ISerializable float BokehBrightness = 1.0f; /// - /// Defines bokeh shapes type. + /// Defines the type of the bokeh shapes. /// API_FIELD(Attributes="EditorOrder(10), PostProcessSetting((int)DepthOfFieldSettingsOverride.BokehShape)") BokehShapeType BokehShape = BokehShapeType::Octagon; @@ -1491,19 +1491,19 @@ API_STRUCT() struct FLAXENGINE_API DepthOfFieldSettings : ISerializable SoftAssetReference BokehShapeCustom; /// - /// The minimum pixel brightness to create bokeh. Pixels with lower brightness will be skipped. + /// The minimum pixel brightness to create the bokeh. Pixels with lower brightness will be skipped. /// API_FIELD(Attributes="Limit(0, 10000.0f, 0.01f), EditorOrder(12), PostProcessSetting((int)DepthOfFieldSettingsOverride.BokehBrightnessThreshold)") float BokehBrightnessThreshold = 3.0f; /// - /// Depth of Field bokeh shapes blur threshold. + /// Depth of Field bokeh shape blur threshold. /// API_FIELD(Attributes="Limit(0, 1.0f, 0.001f), EditorOrder(13), PostProcessSetting((int)DepthOfFieldSettingsOverride.BokehBlurThreshold)") float BokehBlurThreshold = 0.05f; /// - /// Controls bokeh shapes brightness falloff. Higher values reduce bokeh visibility. + /// Controls bokeh shape brightness falloff. Higher values reduce bokeh visibility. /// API_FIELD(Attributes="Limit(0, 2.0f, 0.001f), EditorOrder(14), PostProcessSetting((int)DepthOfFieldSettingsOverride.BokehFalloff)") float BokehFalloff = 0.5f; @@ -1575,25 +1575,25 @@ API_STRUCT() struct FLAXENGINE_API MotionBlurSettings : ISerializable MotionBlurSettingsOverride OverrideFlags = Override::None; /// - /// If checked, motion blur effect will be rendered. + /// If checked, the motion blur effect will be rendered. /// API_FIELD(Attributes="EditorOrder(0), PostProcessSetting((int)MotionBlurSettingsOverride.Enabled)") bool Enabled = true; /// - /// The blur effect strength. Value 0 disabled is, while higher values increase the effect. + /// The blur effect strength. A value of 0 disables it, while higher values increase the effect. /// API_FIELD(Attributes="Limit(0, 5, 0.01f), EditorOrder(1), PostProcessSetting((int)MotionBlurSettingsOverride.Scale)") float Scale = 1.0f; /// - /// The amount of sample points used during motion blur rendering. It affects quality and performance. + /// The amount of sample points used during motion blur rendering. It affects blur quality and performance. /// API_FIELD(Attributes="Limit(4, 32, 0.1f), EditorOrder(2), PostProcessSetting((int)MotionBlurSettingsOverride.SampleCount)") int32 SampleCount = 10; /// - /// The motion vectors texture resolution. Motion blur uses per-pixel motion vectors buffer that contains objects movement information. Use lower resolution to improve performance. + /// The motion vectors texture resolution. Motion blur uses a per-pixel motion vector buffer that contains an objects movement information. Use a lower resolution to improve performance. /// API_FIELD(Attributes="EditorOrder(3), PostProcessSetting((int)MotionBlurSettingsOverride.MotionVectorsResolution)") ResolutionMode MotionVectorsResolution = ResolutionMode::Half; @@ -1898,13 +1898,13 @@ API_STRUCT() struct FLAXENGINE_API AntiAliasingSettings : ISerializable float TAA_Sharpness = 0.0f; /// - /// The blend coefficient for stationary fragments. Controls the percentage of history sample blended into final color for fragments with minimal active motion. + /// The blend coefficient for stationary fragments. Controls the percentage of history samples blended into the final color for fragments with minimal active motion. /// API_FIELD(Attributes="Limit(0, 0.99f, 0.001f), EditorOrder(3), PostProcessSetting((int)AntiAliasingSettingsOverride.TAA_StationaryBlending), EditorDisplay(null, \"TAA Stationary Blending\")") float TAA_StationaryBlending = 0.95f; /// - /// The blending coefficient for moving fragments. Controls the percentage of history sample blended into the final color for fragments with significant active motion. + /// The blending coefficient for moving fragments. Controls the percentage of history samples blended into the final color for fragments with significant active motion. /// API_FIELD(Attributes="Limit(0, 0.99f, 0.001f), EditorOrder(4), PostProcessSetting((int)AntiAliasingSettingsOverride.TAA_MotionBlending), EditorDisplay(null, \"TAA Motion Blending\")") float TAA_MotionBlending = 0.7f; diff --git a/Source/Engine/Level/Actors/ExponentialHeightFog.h b/Source/Engine/Level/Actors/ExponentialHeightFog.h index b0e5751d9..7b400fe4e 100644 --- a/Source/Engine/Level/Actors/ExponentialHeightFog.h +++ b/Source/Engine/Level/Actors/ExponentialHeightFog.h @@ -29,7 +29,7 @@ public: float FogDensity = 0.02f; /// - /// The fog height density factor that controls how the density increases as height decreases. The smaller values produce more visible transition larger. + /// The fog height density factor that controls how the density increases as height decreases. Smaller values produce a more visible transition layer. /// API_FIELD(Attributes="EditorOrder(20), DefaultValue(0.2f), Limit(0.0001f, 10.0f, 0.001f), EditorDisplay(\"Exponential Height Fog\")") float FogHeightFalloff = 0.2f; @@ -55,7 +55,7 @@ public: float StartDistance = 0.0f; /// - /// Scene elements past this distance will not have fog applied. This is useful for excluding skyboxes which already have fog baked in. + /// Scene elements past this distance will not have fog applied. This is useful for excluding skyboxes which already have fog baked in. Setting this value to 0 disables it. /// API_FIELD(Attributes="EditorOrder(60), DefaultValue(0.0f), Limit(0), EditorDisplay(\"Exponential Height Fog\")") float FogCutoffDistance = 0.0f; @@ -111,7 +111,7 @@ public: Color VolumetricFogAlbedo = Color::White; /// - /// Light emitted by height fog. This is a density so more light is emitted the further you are looking through the fog. + /// Light emitted by height fog. This is a density value so more light is emitted the further you are looking through the fog. /// In most cases using a Skylight is a better choice, however, it may be useful in certain scenarios. /// API_FIELD(Attributes="EditorOrder(330), DefaultValue(typeof(Color), \"0,0,0,1\"), EditorDisplay(\"Volumetric Fog\", \"Emissive\")") From 9738fd435437ef6a63fb63ef6e6b02fce943e060 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 16 Nov 2023 14:09:05 +0100 Subject: [PATCH 07/31] Fix crash on hot-reload in Editor due to leftover scripting events in `ScriptingEvents::EventsTable` #1925 --- Source/Engine/Scripting/BinaryModule.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Source/Engine/Scripting/BinaryModule.cpp b/Source/Engine/Scripting/BinaryModule.cpp index 5bbaf8d0b..e9465096f 100644 --- a/Source/Engine/Scripting/BinaryModule.cpp +++ b/Source/Engine/Scripting/BinaryModule.cpp @@ -693,6 +693,14 @@ void BinaryModule::Destroy(bool isReloading) } } + // Remove any scripting events + for (auto i = ScriptingEvents::EventsTable.Begin(); i.IsNotEnd(); ++i) + { + const ScriptingTypeHandle type = i->Key.First; + if (type.Module == this) + ScriptingEvents::EventsTable.Remove(i); + } + // Unregister GetModules().RemoveKeepOrder(this); } From f0865c398933491a1e87f1a57152b626a1e905c4 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 16 Nov 2023 14:18:29 +0100 Subject: [PATCH 08/31] Fix crash in Global Surface Atlas when dirty object is missing --- Source/Engine/Renderer/GI/GlobalSurfaceAtlasPass.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Source/Engine/Renderer/GI/GlobalSurfaceAtlasPass.cpp b/Source/Engine/Renderer/GI/GlobalSurfaceAtlasPass.cpp index 8be3172a6..9d0e065e1 100644 --- a/Source/Engine/Renderer/GI/GlobalSurfaceAtlasPass.cpp +++ b/Source/Engine/Renderer/GI/GlobalSurfaceAtlasPass.cpp @@ -565,7 +565,10 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co _vertexBuffer->Data.EnsureCapacity(_dirtyObjectsBuffer.Count() * 6 * sizeof(AtlasTileVertex)); for (void* actorObject : _dirtyObjectsBuffer) { - const auto& object = ((const Dictionary&)surfaceAtlasData.Objects)[actorObject]; + const GlobalSurfaceAtlasObject* objectPtr = surfaceAtlasData.Objects.TryGet(actorObject); + if (!objectPtr) + continue; + const GlobalSurfaceAtlasObject& object = *objectPtr; for (int32 tileIndex = 0; tileIndex < 6; tileIndex++) { auto* tile = object.Tiles[tileIndex]; @@ -587,7 +590,10 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co int32 tilesDrawn = 0; for (void* actorObject : _dirtyObjectsBuffer) { - const auto& object = ((const Dictionary&)surfaceAtlasData.Objects)[actorObject]; + const GlobalSurfaceAtlasObject* objectPtr = surfaceAtlasData.Objects.TryGet(actorObject); + if (!objectPtr) + continue; + const GlobalSurfaceAtlasObject& object = *objectPtr; // Clear draw calls list renderContextTiles.List->DrawCalls.Clear(); From bec878cc11f33500b2208d189176f5a222c4da53 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 16 Nov 2023 15:47:42 +0100 Subject: [PATCH 09/31] Fix crashes in various dictionary usages caused by duplicated keys #1925 #1924 --- Source/Engine/Level/Prefabs/Prefab.Apply.cpp | 16 +++++++--------- Source/Engine/Level/Prefabs/PrefabManager.cpp | 4 ++-- Source/Engine/Scripting/Scripting.cpp | 12 +++++------- 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/Source/Engine/Level/Prefabs/Prefab.Apply.cpp b/Source/Engine/Level/Prefabs/Prefab.Apply.cpp index 454b68006..c10ea532d 100644 --- a/Source/Engine/Level/Prefabs/Prefab.Apply.cpp +++ b/Source/Engine/Level/Prefabs/Prefab.Apply.cpp @@ -253,7 +253,7 @@ void PrefabInstanceData::SerializePrefabInstances(PrefabInstancesData& prefabIns for (int32 i = 0; i < sceneObjects->Count(); i++) { SceneObject* obj = sceneObjects.Value->At(i); - instance.PrefabInstanceIdToDataIndex.Add(obj->GetSceneObjectId(), i); + instance.PrefabInstanceIdToDataIndex[obj->GetSceneObjectId()] = i; } } tmpBuffer.Clear(); @@ -313,15 +313,13 @@ bool PrefabInstanceData::SynchronizePrefabInstances(PrefabInstancesData& prefabI continue; } - modifier.Value->IdsMapping.Add(obj->GetPrefabObjectID(), obj->GetSceneObjectId()); + modifier.Value->IdsMapping[obj->GetPrefabObjectID()] = obj->GetSceneObjectId(); } } // Generate new IDs for the added objects (objects in prefab has to have a unique Ids, other than the targetActor instance objects to prevent Id collisions) for (int32 i = 0; i < newPrefabObjectIds.Count(); i++) - { - modifier->IdsMapping.Add(newPrefabObjectIds[i], Guid::New()); - } + modifier->IdsMapping[newPrefabObjectIds[i]] = Guid::New(); // Create new objects added to prefab int32 deserializeSceneObjectIndex = sceneObjects->Count(); @@ -786,7 +784,7 @@ bool Prefab::ApplyAllInternal(Actor* targetActor, bool linkTargetActorObjectToPr } // Cache connection for fast lookup - diffPrefabObjectIdToDataIndex.Add(obj->GetPrefabObjectID(), i); + diffPrefabObjectIdToDataIndex[obj->GetPrefabObjectID()] = i; // Strip unwanted data data.RemoveMember("ID"); @@ -796,7 +794,7 @@ bool Prefab::ApplyAllInternal(Actor* targetActor, bool linkTargetActorObjectToPr else { // Object if a new thing - newPrefabInstanceIdToDataIndex.Add(obj->GetSceneObjectId(), i); + newPrefabInstanceIdToDataIndex[obj->GetSceneObjectId()] = i; } } @@ -836,8 +834,8 @@ bool Prefab::ApplyAllInternal(Actor* targetActor, bool linkTargetActorObjectToPr for (auto i = newPrefabInstanceIdToDataIndex.Begin(); i.IsNotEnd(); ++i) { const auto prefabObjectId = Guid::New(); - newPrefabInstanceIdToPrefabObjectId.Add(i->Key, prefabObjectId); - modifier->IdsMapping.Add(i->Key, prefabObjectId); + newPrefabInstanceIdToPrefabObjectId[i->Key] = prefabObjectId; + modifier->IdsMapping[i->Key] = prefabObjectId; } // Add inverse IDs mapping to link added objects and references inside them to the prefab objects diff --git a/Source/Engine/Level/Prefabs/PrefabManager.cpp b/Source/Engine/Level/Prefabs/PrefabManager.cpp index de164343b..c7b42b7d2 100644 --- a/Source/Engine/Level/Prefabs/PrefabManager.cpp +++ b/Source/Engine/Level/Prefabs/PrefabManager.cpp @@ -374,13 +374,13 @@ bool PrefabManager::CreatePrefab(Actor* targetActor, const StringView& outputPat if (targetActor->HasParent()) { // Unlink from parent actor - objectInstanceIdToPrefabObjectId.Add(targetActor->GetParent()->GetID(), Guid::Empty); + objectInstanceIdToPrefabObjectId[targetActor->GetParent()->GetID()] = Guid::Empty; } for (int32 i = 0; i < sceneObjects->Count(); i++) { // Generate new IDs for the prefab objects (other than reference instance used to create prefab) const SceneObject* obj = sceneObjects->At(i); - objectInstanceIdToPrefabObjectId.Add(obj->GetSceneObjectId(), Guid::New()); + objectInstanceIdToPrefabObjectId[obj->GetSceneObjectId()] = Guid::New(); } { // Parse json to DOM document diff --git a/Source/Engine/Scripting/Scripting.cpp b/Source/Engine/Scripting/Scripting.cpp index e9dc0421c..6cabbc0dd 100644 --- a/Source/Engine/Scripting/Scripting.cpp +++ b/Source/Engine/Scripting/Scripting.cpp @@ -1026,30 +1026,28 @@ bool Scripting::IsTypeFromGameScripts(MClass* type) void Scripting::RegisterObject(ScriptingObject* obj) { + const Guid id = obj->GetID(); ScopeLock lock(_objectsLocker); //ASSERT(!_objectsDictionary.ContainsValue(obj)); #if ENABLE_ASSERTION #if USE_OBJECTS_DISPOSE_CRASHES_DEBUGGING ScriptingObjectData other; - if (_objectsDictionary.TryGet(obj->GetID(), other)) + if (_objectsDictionary.TryGet(id, other)) #else ScriptingObject* other; - if (_objectsDictionary.TryGet(obj->GetID(), other)) + if (_objectsDictionary.TryGet(id, other)) #endif { // Something went wrong... - LOG(Error, "Objects registry already contains object with ID={0} (type '{3}')! Trying to register object {1} (type '{2}').", obj->GetID(), obj->ToString(), String(obj->GetClass()->GetFullName()), String(other->GetClass()->GetFullName())); - _objectsDictionary.Remove(obj->GetID()); + LOG(Error, "Objects registry already contains object with ID={0} (type '{3}')! Trying to register object {1} (type '{2}').", id, obj->ToString(), String(obj->GetClass()->GetFullName()), String(other->GetClass()->GetFullName())); } -#else - ASSERT(!_objectsDictionary.ContainsKey(obj->_id)); #endif #if USE_OBJECTS_DISPOSE_CRASHES_DEBUGGING LOG(Info, "[RegisterObject] obj = 0x{0:x}, {1}", (uint64)obj, String(ScriptingObjectData(obj).TypeName)); #endif - _objectsDictionary.Add(obj->GetID(), obj); + _objectsDictionary[id] = obj; } void Scripting::UnregisterObject(ScriptingObject* obj) From e177aec5fadf112232b8f819b88331d86cd6989f Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 17 Nov 2023 12:19:54 +0100 Subject: [PATCH 10/31] Codestyle --- Source/Engine/Core/Math/Math.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Source/Engine/Core/Math/Math.h b/Source/Engine/Core/Math/Math.h index 49a052771..a3c05fce4 100644 --- a/Source/Engine/Core/Math/Math.h +++ b/Source/Engine/Core/Math/Math.h @@ -728,9 +728,7 @@ namespace Math /// /// Returns value based on comparand. The main purpose of this function is to avoid branching based on floating point comparison which can be avoided via compiler intrinsics. /// - /// - /// Please note that this doesn't define what happens in the case of NaNs as there might be platform specific differences. - /// + /// Please note that this doesn't define what happens in the case of NaNs as there might be platform specific differences. /// Comparand the results are based on. /// The result value if comparand >= 0. /// The result value if comparand < 0. @@ -890,8 +888,9 @@ namespace Math { return Lerp(a, b, alpha < 0.5f ? InterpCircularIn(0.f, 1.f, alpha * 2.f) * 0.5f : InterpCircularOut(0.f, 1.f, alpha * 2.f - 1.f) * 0.5f + 0.5f); } + /// - /// PingPongs the value , so that it is never larger than and never smaller than 0. + /// Ping pongs the value , so that it is never larger than and never smaller than 0. /// /// /// From 719498e99bd0468cfd8aeb726b03ce9144480401 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 17 Nov 2023 13:08:37 +0100 Subject: [PATCH 11/31] Adjust `MissingScriptEditor` layout for UI --- .../Dedicated/MissingScriptEditor.cs | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/Source/Editor/CustomEditors/Dedicated/MissingScriptEditor.cs b/Source/Editor/CustomEditors/Dedicated/MissingScriptEditor.cs index 8fb742b5e..7e0c6f38c 100644 --- a/Source/Editor/CustomEditors/Dedicated/MissingScriptEditor.cs +++ b/Source/Editor/CustomEditors/Dedicated/MissingScriptEditor.cs @@ -37,41 +37,32 @@ public class MissingScriptEditor : GenericEditor Parent = _dropPanel, Height = 64, }; - _replaceScriptButton = new Button { Text = "Replace Script", TooltipText = "Replaces the missing script with a given script type", AnchorPreset = AnchorPresets.TopCenter, - Width = 240, - Height = 24, - X = -120, - Y = 0, + Bounds = new Rectangle(-120, 0, 240, 24), Parent = replaceScriptPanel, }; _replaceScriptButton.Clicked += OnReplaceScriptButtonClicked; - var replaceAllLabel = new Label { Text = "Replace all matching missing scripts", TooltipText = "Whether or not to apply this script change to all scripts missing the same type.", AnchorPreset = AnchorPresets.BottomCenter, - Y = -34, + Y = -38, Parent = replaceScriptPanel, }; - replaceAllLabel.X -= FlaxEngine.GUI.Style.Current.FontSmall.MeasureText(replaceAllLabel.Text).X; - _shouldReplaceAllCheckbox = new CheckBox { TooltipText = replaceAllLabel.TooltipText, AnchorPreset = AnchorPresets.BottomCenter, - Y = -34, + Y = -38, Parent = replaceScriptPanel, }; - - float centerDifference = (_shouldReplaceAllCheckbox.Right - replaceAllLabel.Left) / 2; - replaceAllLabel.X += centerDifference; - _shouldReplaceAllCheckbox.X += centerDifference; + _shouldReplaceAllCheckbox.X -= _replaceScriptButton.Width * 0.5f + 0.5f; + replaceAllLabel.X -= 52; base.Initialize(layout); } From d9b90c952028f019bd21ba364a748936ef492bd8 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 17 Nov 2023 13:50:18 +0100 Subject: [PATCH 12/31] Fix crash in `MissingScript` if script is still missing after deserialization #1924 --- .../Engine/Level/Components/MissingScript.h | 19 +--------------- Source/Engine/Level/SceneObjectsFactory.cpp | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/Source/Engine/Level/Components/MissingScript.h b/Source/Engine/Level/Components/MissingScript.h index bfb73498f..7b351bd82 100644 --- a/Source/Engine/Level/Components/MissingScript.h +++ b/Source/Engine/Level/Components/MissingScript.h @@ -42,24 +42,7 @@ public: /// /// Field for assigning new script to transfer data to. /// - API_PROPERTY() void SetReferenceScript(const ScriptingObjectReference