From 6ef65734cd7a1f0bd99d4fc358e76406b16b7f29 Mon Sep 17 00:00:00 2001 From: Richard Date: Mon, 25 Jan 2021 09:35:22 +1100 Subject: [PATCH 01/68] Optimisied Blend Normal Node I've also added a getNormalZero to get a normal that has zeroed out, i.e. it faces directly outwards from the face. This enables the user to not have to input a vector for either the Base or Additional Normal inputs and still get a result that is acceptable. This is handy if you want to "wash out" a normal. --- .../MaterialGenerator/MaterialGenerator.Material.cpp | 12 ++++++++---- .../Tools/MaterialGenerator/MaterialGenerator.cpp | 1 + .../Tools/MaterialGenerator/MaterialGenerator.h | 1 + 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp index c4d7c39e5..e06142d81 100644 --- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp +++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp @@ -342,10 +342,14 @@ void MaterialGenerator::ProcessGroupMaterial(Box* box, Node* node, Value& value) // Blend Normals case 26: { - const auto baseNormal = tryGetValue(node->GetBox(0), Value::Zero).AsVector3(); - const auto additionalNormal = tryGetValue(node->GetBox(1), Value::Zero).AsVector3(); - const String text = String::Format(TEXT("float3((float2({0}.xy) + float2({1}.xy) * 2.0), sqrt(saturate(1.0 - dot((float2({0}.xy) + float2({1}.xy) * 2.0).xy, (float2({0}.xy) + float2({1}.xy) * 2.0).xy))))"), baseNormal.Value, additionalNormal.Value); - value = writeLocal(ValueType::Vector3, text, node); + const auto baseNormal = tryGetValue(node->GetBox(0), getNormalZero).AsVector3(); + const auto additionalNormal = tryGetValue(node->GetBox(1), getNormalZero).AsVector3(); + + const String text1 = String::Format(TEXT("(float2({0}.xy) + float2({1}.xy) * 2.0)"), baseNormal.Value, additionalNormal.Value); + const auto appendXY = writeLocal(ValueType::Vector2, text1, node); + + const String text2 = String::Format(TEXT("float3({0}, sqrt(saturate(1.0 - dot({0}.xy, {0}.xy))))"), appendXY.Value); + value = writeLocal(ValueType::Vector3, text2, node); break; } // Rotator diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp index 7abd29af9..1e71a028d 100644 --- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp +++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp @@ -27,6 +27,7 @@ enum MaterialTemplateInputsMapping MaterialValue MaterialGenerator::getUVs(VariantType::Vector2, TEXT("input.TexCoord")); MaterialValue MaterialGenerator::getTime(VariantType::Float, TEXT("TimeParam")); MaterialValue MaterialGenerator::getNormal(VariantType::Vector3, TEXT("input.TBN[2]")); +MaterialValue MaterialGenerator::getNormalZero(VariantType::Vector3, TEXT("float3(.5, .5, 1)")); MaterialValue MaterialGenerator::getVertexColor(VariantType::Vector4, TEXT("GetVertexColor(input)")); MaterialGenerator::MaterialGenerator() diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.h b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.h index 005b9c58c..804955618 100644 --- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.h +++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.h @@ -205,6 +205,7 @@ public: static MaterialValue getUVs; static MaterialValue getTime; static MaterialValue getNormal; + static MaterialValue getNormalZero; static MaterialValue getVertexColor; static MaterialGraphBoxesMapping MaterialGraphBoxesMappings[]; From c8b0773661414a125f6d9809ed8dd754821da41c Mon Sep 17 00:00:00 2001 From: Richard Date: Wed, 27 Jan 2021 11:07:36 +1100 Subject: [PATCH 02/68] Fixed a bug --- Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp index 1e71a028d..57f669f7f 100644 --- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp +++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp @@ -27,7 +27,7 @@ enum MaterialTemplateInputsMapping MaterialValue MaterialGenerator::getUVs(VariantType::Vector2, TEXT("input.TexCoord")); MaterialValue MaterialGenerator::getTime(VariantType::Float, TEXT("TimeParam")); MaterialValue MaterialGenerator::getNormal(VariantType::Vector3, TEXT("input.TBN[2]")); -MaterialValue MaterialGenerator::getNormalZero(VariantType::Vector3, TEXT("float3(.5, .5, 1)")); +MaterialValue MaterialGenerator::getNormalZero(VariantType::Vector3, TEXT("float3(0, 0, 1)")); MaterialValue MaterialGenerator::getVertexColor(VariantType::Vector4, TEXT("GetVertexColor(input)")); MaterialGenerator::MaterialGenerator() From bd18286fbd781879c796b45ac890829fae404dca Mon Sep 17 00:00:00 2001 From: "W2.Wizard" Date: Thu, 28 Jan 2021 01:26:57 +0100 Subject: [PATCH 03/68] Refactoring and Node implementation Refactored all recently added nodes to maintain consistency. --- Source/Editor/Surface/Archetypes/Material.cs | 62 +++++++++++++++++- .../MaterialGenerator.Material.cpp | 63 ++++++++++++++----- 2 files changed, 106 insertions(+), 19 deletions(-) diff --git a/Source/Editor/Surface/Archetypes/Material.cs b/Source/Editor/Surface/Archetypes/Material.cs index 6e828fca4..f8fc025a8 100644 --- a/Source/Editor/Surface/Archetypes/Material.cs +++ b/Source/Editor/Surface/Archetypes/Material.cs @@ -725,7 +725,7 @@ namespace FlaxEditor.Surface.Archetypes { TypeID = 30, Title = "DDX", - Description = "Returns the partial derivative of the specified value with respect to the screen-space x-coordinate.", + Description = "Returns the partial derivative of the specified value with respect to the screen-space x-coordinate", Flags = NodeFlags.MaterialGraph, Size = new Vector2(90, 25), ConnectionsHints = ConnectionsHint.Numeric, @@ -741,7 +741,7 @@ namespace FlaxEditor.Surface.Archetypes { TypeID = 31, Title = "DDY", - Description = "Returns the partial derivative of the specified value with respect to the screen-space y-coordinate.", + Description = "Returns the partial derivative of the specified value with respect to the screen-space y-coordinate", Flags = NodeFlags.MaterialGraph, Size = new Vector2(90, 25), ConnectionsHints = ConnectionsHint.Numeric, @@ -753,6 +753,64 @@ namespace FlaxEditor.Surface.Archetypes NodeElementArchetype.Factory.Output(0, string.Empty, null, 1), } }, + new NodeArchetype + { + TypeID = 32, + Title = "Sign", + Description = "Returns -1 if value is less than zero; 0 if value equals zero; and 1 if value is greater than zero", + Flags = NodeFlags.MaterialGraph, + Size = new Vector2(90, 25), + ConnectionsHints = ConnectionsHint.Numeric, + IndependentBoxes = new[] { 0 }, + Elements = new[] + { + NodeElementArchetype.Factory.Input(0, "Value", true, null, 0), + NodeElementArchetype.Factory.Output(0, string.Empty, typeof(float), 1), + } + }, + new NodeArchetype + { + TypeID = 33, + Title = "Any", + Description = "True if any components of value are non-zero; otherwise, false", + Flags = NodeFlags.MaterialGraph, + Size = new Vector2(90, 25), + ConnectionsHints = ConnectionsHint.Numeric, + IndependentBoxes = new[] { 0 }, + Elements = new[] + { + NodeElementArchetype.Factory.Input(0, "Value", true, null, 0), + NodeElementArchetype.Factory.Output(0, string.Empty, typeof(bool), 1), + } + }, + new NodeArchetype + { + TypeID = 34, + Title = "All", + Description = "Determines if all components of the specified value are non-zero", + Flags = NodeFlags.MaterialGraph, + Size = new Vector2(90, 25), + ConnectionsHints = ConnectionsHint.Numeric, + IndependentBoxes = new[] { 0 }, + Elements = new[] + { + NodeElementArchetype.Factory.Input(0, "Value", true, null, 0), + NodeElementArchetype.Factory.Output(0, string.Empty, typeof(bool), 1), + } + }, + new NodeArchetype + { + TypeID = 35, + Title = "Black Body", + Description = "Simulates black body radiation via a given temperature in kelvin", + Flags = NodeFlags.MaterialGraph, + Size = new Vector2(120, 25), + Elements = new[] + { + NodeElementArchetype.Factory.Input(0, "Temp", true, typeof(float), 0), + NodeElementArchetype.Factory.Output(0, string.Empty, typeof(Vector3), 1), + } + }, }; } } diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp index 0d8a0e226..d851e4b86 100644 --- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp +++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp @@ -351,15 +351,15 @@ void MaterialGenerator::ProcessGroupMaterial(Box* box, Node* node, Value& value) // Rotator case 27: { - auto uv = tryGetValue(node->GetBox(0), getUVs).AsVector2(); - auto center = tryGetValue(node->GetBox(1), Value::Zero).AsVector2(); - auto rotationAngle = tryGetValue(node->GetBox(2), Value::Zero).AsFloat(); + const auto uv = tryGetValue(node->GetBox(0), getUVs).AsVector2(); + const auto center = tryGetValue(node->GetBox(1), Value::Zero).AsVector2(); + const auto rotationAngle = tryGetValue(node->GetBox(2), Value::Zero).AsFloat(); - const auto x1 = writeLocal(ValueType::Vector2, String::Format(TEXT("({0} * -1) + {1}"), center.Value, uv.Value), node); - const auto raCosSin = writeLocal(ValueType::Vector2, String::Format(TEXT("float2(cos({0}), sin({0}))"), rotationAngle.Value), node); + auto x1 = writeLocal(ValueType::Vector2, String::Format(TEXT("({0} * -1) + {1}"), center.Value, uv.Value), node); + auto raCosSin = writeLocal(ValueType::Vector2, String::Format(TEXT("float2(cos({0}), sin({0}))"), rotationAngle.Value), node); - const auto dotB1 = writeLocal(ValueType::Vector2, String::Format(TEXT("float2({0}.x, {0}.y * -1)"), raCosSin.Value), node); - const auto dotB2 = writeLocal(ValueType::Vector2, String::Format(TEXT("float2({0}.y, {0}.x)"), raCosSin.Value), node); + auto dotB1 = writeLocal(ValueType::Vector2, String::Format(TEXT("float2({0}.x, {0}.y * -1)"), raCosSin.Value), node); + auto dotB2 = writeLocal(ValueType::Vector2, String::Format(TEXT("float2({0}.y, {0}.x)"), raCosSin.Value), node); value = writeLocal(ValueType::Vector2, String::Format(TEXT("{3} + float2(dot({0},{1}), dot({0},{2}))"), x1.Value, dotB1.Value, dotB2.Value, center.Value), node); break; @@ -367,11 +367,11 @@ void MaterialGenerator::ProcessGroupMaterial(Box* box, Node* node, Value& value) // Sphere Mask case 28: { - Value a = tryGetValue(node->GetBox(0), 0, Value::Zero); - Value b = tryGetValue(node->GetBox(1), 1, Value::Zero).Cast(a.Type); - Value radius = tryGetValue(node->GetBox(2), node->Values[0]).AsFloat(); - Value hardness = tryGetValue(node->GetBox(3), node->Values[1]).AsFloat(); - Value invert = tryGetValue(node->GetBox(4), node->Values[2]).AsBool(); + const auto a = tryGetValue(node->GetBox(0), 0, Value::Zero); + const auto b = tryGetValue(node->GetBox(1), 1, Value::Zero).Cast(a.Type); + const auto radius = tryGetValue(node->GetBox(2), node->Values[0]).AsFloat(); + const auto hardness = tryGetValue(node->GetBox(3), node->Values[1]).AsFloat(); + const auto invert = tryGetValue(node->GetBox(4), node->Values[2]).AsBool(); // Get distance and apply radius auto x1 = writeLocal(ValueType::Float, String::Format(TEXT("distance({0},{1}) * (1 / {2})"), a.Value, b.Value, radius.Value), node); @@ -385,9 +385,9 @@ void MaterialGenerator::ProcessGroupMaterial(Box* box, Node* node, Value& value) // Tiling & Offset case 29: { - auto uv = tryGetValue(node->GetBox(0), getUVs).AsVector2(); - auto tiling = tryGetValue(node->GetBox(1), node->Values[0]).AsVector2(); - auto offset = tryGetValue(node->GetBox(2), node->Values[1]).AsVector2(); + const auto uv = tryGetValue(node->GetBox(0), getUVs).AsVector2(); + const auto tiling = tryGetValue(node->GetBox(1), node->Values[0]).AsVector2(); + const auto offset = tryGetValue(node->GetBox(2), node->Values[1]).AsVector2(); value = writeLocal(ValueType::Vector2, String::Format(TEXT("{0} * {1} + {2}"), uv.Value, tiling.Value, offset.Value), node); break; @@ -395,7 +395,7 @@ void MaterialGenerator::ProcessGroupMaterial(Box* box, Node* node, Value& value) // DDX case 30: { - auto inValue = tryGetValue(node->GetBox(0), 0, Value::Zero); + const auto inValue = tryGetValue(node->GetBox(0), 0, Value::Zero); value = writeLocal(inValue.Type, String::Format(TEXT("ddx({0})"), inValue.Value), node); break; @@ -403,10 +403,39 @@ void MaterialGenerator::ProcessGroupMaterial(Box* box, Node* node, Value& value) // DDY case 31: { - auto inValue = tryGetValue(node->GetBox(0), 0, Value::Zero); + const auto inValue = tryGetValue(node->GetBox(0), 0, Value::Zero); value = writeLocal(inValue.Type, String::Format(TEXT("ddy({0})"), inValue.Value), node); break; + } + // Sign + case 32: + { + const auto inValue = tryGetValue(node->GetBox(0), 0, Value::Zero); + + value = writeLocal(ValueType::Float, String::Format(TEXT("sign({0})"), inValue.Value), node); + break; + } + // Any + case 33: + { + const auto inValue = tryGetValue(node->GetBox(0), 0, Value::Zero); + + value = writeLocal(ValueType::Bool, String::Format(TEXT("any({0})"), inValue.Value), node); + break; + } + // All + case 34: + { + const auto inValue = tryGetValue(node->GetBox(0), 0, Value::Zero); + + value = writeLocal(ValueType::Bool, String::Format(TEXT("all({0})"), inValue.Value), node); + break; + } + // Blackbody + case 35: + { + break; } default: break; From e75ca148c0aaa5e5cd9f68b6ed96ecbb104d7806 Mon Sep 17 00:00:00 2001 From: "W2.Wizard" Date: Sat, 30 Jan 2021 23:21:41 +0100 Subject: [PATCH 04/68] Added blackbody --- Source/Editor/Surface/Archetypes/Material.cs | 6 +++++- .../MaterialGenerator.Material.cpp | 17 +++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/Source/Editor/Surface/Archetypes/Material.cs b/Source/Editor/Surface/Archetypes/Material.cs index f8fc025a8..ceb9921cb 100644 --- a/Source/Editor/Surface/Archetypes/Material.cs +++ b/Source/Editor/Surface/Archetypes/Material.cs @@ -805,9 +805,13 @@ namespace FlaxEditor.Surface.Archetypes Description = "Simulates black body radiation via a given temperature in kelvin", Flags = NodeFlags.MaterialGraph, Size = new Vector2(120, 25), + DefaultValues = new object[] + { + 0.0f, + }, Elements = new[] { - NodeElementArchetype.Factory.Input(0, "Temp", true, typeof(float), 0), + NodeElementArchetype.Factory.Input(0, "Temp", true, typeof(float), 0, 0), NodeElementArchetype.Factory.Output(0, string.Empty, typeof(Vector3), 1), } }, diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp index d851e4b86..34ed16d9a 100644 --- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp +++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp @@ -435,6 +435,23 @@ void MaterialGenerator::ProcessGroupMaterial(Box* box, Node* node, Value& value) // Blackbody case 35: { + const auto temperature = tryGetValue(node->GetBox(0), node->Values[0]).AsFloat(); + + // Value X + auto x = writeLocal(ValueType::Float, String::Format(TEXT("56100000.0f * pow({0}, (-3.0f / 2.0f)) + 148.0f"), temperature.Value), node); + + // Value Y + auto y = writeLocal(ValueType::Float, String::Format(TEXT("{0} > 6500.0f ? 35200000.0f * pow({0}, (-3.0f / 2.0f)) + 184.0f : 100.04f * log({0}) - 623.6f"), temperature.Value), node); + + // Value Z + auto z = writeLocal(ValueType::Float, String::Format(TEXT("194.18f * log({0}) - 1448.6f"), temperature.Value), node); + + // Final color + auto color = writeLocal(ValueType::Vector3, String::Format(TEXT("float3({0}, {1}, {2})"), x.Value, y.Value, z.Value), node); + color = writeLocal(ValueType::Vector3, String::Format(TEXT("clamp({0}, 0.0f, 255.0f) / 255.0f"), color.Value), node); + color = writeLocal(ValueType::Vector3, String::Format(TEXT("{1} < 1000.0f ? {0} * {1}/1000.0f : {0}"), color.Value, temperature.Value), node); + + value = color; break; } default: From bc6de6932b9f2b4fc7c23ebc688ac8717035a01b Mon Sep 17 00:00:00 2001 From: "W2.Wizard" Date: Sat, 30 Jan 2021 23:28:53 +0100 Subject: [PATCH 05/68] Update MaterialGenerator.Material.cpp Already evaluate calculation instead --- .../Tools/MaterialGenerator/MaterialGenerator.Material.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp index 34ed16d9a..31d2ba36c 100644 --- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp +++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp @@ -438,10 +438,10 @@ void MaterialGenerator::ProcessGroupMaterial(Box* box, Node* node, Value& value) const auto temperature = tryGetValue(node->GetBox(0), node->Values[0]).AsFloat(); // Value X - auto x = writeLocal(ValueType::Float, String::Format(TEXT("56100000.0f * pow({0}, (-3.0f / 2.0f)) + 148.0f"), temperature.Value), node); + auto x = writeLocal(ValueType::Float, String::Format(TEXT("56100000.0f * pow({0}, -1) + 148.0f"), temperature.Value), node); // Value Y - auto y = writeLocal(ValueType::Float, String::Format(TEXT("{0} > 6500.0f ? 35200000.0f * pow({0}, (-3.0f / 2.0f)) + 184.0f : 100.04f * log({0}) - 623.6f"), temperature.Value), node); + auto y = writeLocal(ValueType::Float, String::Format(TEXT("{0} > 6500.0f ? 35200000.0f * pow({0}, -1) + 184.0f : 100.04f * log({0}) - 623.6f"), temperature.Value), node); // Value Z auto z = writeLocal(ValueType::Float, String::Format(TEXT("194.18f * log({0}) - 1448.6f"), temperature.Value), node); From 28d16fd620aec1864ad1208a053b02cda2b18cc7 Mon Sep 17 00:00:00 2001 From: "W2.Wizard" Date: Sat, 30 Jan 2021 23:32:35 +0100 Subject: [PATCH 06/68] Add notice --- .../Tools/MaterialGenerator/MaterialGenerator.Material.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp index 31d2ba36c..83251089f 100644 --- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp +++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp @@ -435,6 +435,8 @@ void MaterialGenerator::ProcessGroupMaterial(Box* box, Node* node, Value& value) // Blackbody case 35: { + // Based on unity's implementation by using data gathered by Mitchell Charity. + const auto temperature = tryGetValue(node->GetBox(0), node->Values[0]).AsFloat(); // Value X From 62f2ccb9426fa1e394d3cd1395e31cf172c1e1eb Mon Sep 17 00:00:00 2001 From: stefnotch Date: Mon, 1 Feb 2021 22:40:19 +0100 Subject: [PATCH 07/68] Fix conversion to degrees in Vector3.Angle --- Source/Engine/Core/Math/Vector3.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Engine/Core/Math/Vector3.cs b/Source/Engine/Core/Math/Vector3.cs index db27cf8ed..a57fcb224 100644 --- a/Source/Engine/Core/Math/Vector3.cs +++ b/Source/Engine/Core/Math/Vector3.cs @@ -1221,7 +1221,7 @@ namespace FlaxEngine float dot = Mathf.Clamp(Dot(from.Normalized, to.Normalized), -1F, 1F); if (Mathf.Abs(dot) > (1F - Mathf.Epsilon)) return dot > 0F ? 0F : 180F; - return Mathf.Acos(dot) * Mathf.DegreesToRadians; + return Mathf.Acos(dot) * Mathf.RadiansToDegrees; } /// From fb74aef541c18a0a55deee1b761ed0506d3cba31 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Tue, 2 Feb 2021 23:14:21 +0100 Subject: [PATCH 08/68] Add check for C++ bindings generator for property getter and setter method value types to match --- .../Bindings/BindingsGenerator.Parsing.cs | 22 +++++++++++++++++++ Source/Tools/Flax.Build/Bindings/TypeInfo.cs | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs index b39f2f066..42c0e73b2 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs @@ -691,6 +691,28 @@ namespace Flax.Build.Bindings else propertyInfo.Setter = functionInfo; + if (propertyInfo.Getter != null && propertyInfo.Setter != null) + { + // Check if getter and setter types are matching (const and ref specifiers are skipped) + var getterType = propertyInfo.Getter.ReturnType; + var setterType = propertyInfo.Setter.Parameters[0].Type; + if (!string.Equals(getterType.Type, setterType.Type) || + getterType.IsPtr != setterType.IsPtr || + getterType.IsArray != setterType.IsArray || + getterType.IsBitField != setterType.IsBitField || + getterType.ArraySize != setterType.ArraySize || + getterType.BitSize != setterType.BitSize || + !TypeInfo.Equals(getterType.GenericArgs, setterType.GenericArgs)) + { + // Skip compatible types + if (getterType.Type == "String" && setterType.Type == "StringView") + return propertyInfo; + if (getterType.Type == "Array" && setterType.Type == "Span" && getterType.GenericArgs?.Count == 1 && setterType.GenericArgs?.Count == 1 && getterType.GenericArgs[0].Equals(setterType.GenericArgs[0])) + return propertyInfo; + throw new Exception($"Property {propertyName} in class {classInfo.Name} (line {context.Tokenizer.CurrentLine}) has mismatching getter return type ({getterType}) and setter parameter type ({setterType}). Both getter and setter methods must use the same value type used for property."); + } + } + return propertyInfo; } diff --git a/Source/Tools/Flax.Build/Bindings/TypeInfo.cs b/Source/Tools/Flax.Build/Bindings/TypeInfo.cs index 8af061200..962aa9523 100644 --- a/Source/Tools/Flax.Build/Bindings/TypeInfo.cs +++ b/Source/Tools/Flax.Build/Bindings/TypeInfo.cs @@ -83,7 +83,7 @@ namespace Flax.Build.Bindings return sb.ToString(); } - private static bool Equals(List a, List b) + public static bool Equals(List a, List b) { if (a == null && b == null) return true; From 28f53339e77acaaed0c1a61c5c6a114a034fb2b2 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Tue, 2 Feb 2021 23:33:42 +0100 Subject: [PATCH 09/68] Fix crash when loading string property in json that is not a string Fixes #178 --- Source/ThirdParty/rapidjson/document.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Source/ThirdParty/rapidjson/document.h b/Source/ThirdParty/rapidjson/document.h index d9472ec1e..2691a6386 100644 --- a/Source/ThirdParty/rapidjson/document.h +++ b/Source/ThirdParty/rapidjson/document.h @@ -1679,7 +1679,18 @@ public: //@{ const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return (data_.f.flags & kInlineStrFlag) ? data_.ss.str : GetStringPointer(); } - ::String GetText() const { RAPIDJSON_ASSERT(IsString()); return ::String(GetString(), GetStringLength()); } + ::String GetText() const + { + ::String result; + if (IsString()) + { + if (data_.f.flags & kInlineStrFlag) + result.Set(data_.ss.str, data_.ss.GetLength()); + else + result.Set(GetStringPointer(), data_.s.length); + } + return result; + } //! Get the length of string. /*! Since rapidjson permits "\\u0000" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength(). From 8e4a0e9e97dacb964438392e44dc5c6f741cc60b Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Wed, 3 Feb 2021 19:09:41 +0100 Subject: [PATCH 10/68] Fix drawing UI Control outline in Game Window (#194) --- Source/Editor/Windows/GameWindow.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Source/Editor/Windows/GameWindow.cs b/Source/Editor/Windows/GameWindow.cs index 2f9be0254..858f0e0ba 100644 --- a/Source/Editor/Windows/GameWindow.cs +++ b/Source/Editor/Windows/GameWindow.cs @@ -294,7 +294,9 @@ namespace FlaxEditor.Windows { if (Editor.Instance.SceneEditing.Selection[i].EditableObject is UIControl controlActor && controlActor.Control != null) { - Render2D.DrawRectangle(controlActor.Control.Bounds, Editor.Instance.Options.Options.Visual.SelectionOutlineColor0, Editor.Instance.Options.Options.Visual.UISelectionOutlineSize); + var control = controlActor.Control; + var bounds = Rectangle.FromPoints(control.PointToParent(_viewport, Vector2.Zero), control.PointToParent(_viewport, control.Size)); + Render2D.DrawRectangle(bounds, Editor.Instance.Options.Options.Visual.SelectionOutlineColor0, Editor.Instance.Options.Options.Visual.UISelectionOutlineSize); } } From c3b36062edb2edeb3c34ccb3620be203fb42fc17 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Wed, 3 Feb 2021 19:24:47 +0100 Subject: [PATCH 11/68] Fix error --- Source/Engine/UI/GUI/Control.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Source/Engine/UI/GUI/Control.cs b/Source/Engine/UI/GUI/Control.cs index 1c4eda965..c2ba34f05 100644 --- a/Source/Engine/UI/GUI/Control.cs +++ b/Source/Engine/UI/GUI/Control.cs @@ -1006,10 +1006,9 @@ namespace FlaxEngine.GUI c = c.Parent; if (c == parent) - return location; + break; } - - throw new ArgumentException(); + return location; } /// From a572e581e5614da8a2a58a6c59ef2c8222b2daa9 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Wed, 3 Feb 2021 21:30:33 +0100 Subject: [PATCH 12/68] Fix HorizontalPanel children layout Fixes 191 --- Source/Engine/UI/GUI/Panels/HorizontalPanel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Engine/UI/GUI/Panels/HorizontalPanel.cs b/Source/Engine/UI/GUI/Panels/HorizontalPanel.cs index 8f8e7f994..53e435f91 100644 --- a/Source/Engine/UI/GUI/Panels/HorizontalPanel.cs +++ b/Source/Engine/UI/GUI/Panels/HorizontalPanel.cs @@ -45,7 +45,7 @@ namespace FlaxEngine.GUI if (c.Visible) { var w = c.Width; - c.Bounds = new Rectangle(x + _offset.X, _margin.Top + _offset.Y, h, w); + c.Bounds = new Rectangle(x + _offset.X, _margin.Top + _offset.Y, w, h); x = c.Right + _spacing; hasAnyItem = true; } From ba0f07b57ece91052e517d18ab920779f5cab897 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Wed, 3 Feb 2021 21:52:29 +0100 Subject: [PATCH 13/68] Fix BlurPanel rendering Fixes #192 --- Source/Engine/Render2D/Render2D.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Engine/Render2D/Render2D.cpp b/Source/Engine/Render2D/Render2D.cpp index 2413686aa..154dbe636 100644 --- a/Source/Engine/Render2D/Render2D.cpp +++ b/Source/Engine/Render2D/Render2D.cpp @@ -967,7 +967,7 @@ void DrawBatch(int32 startIndex, int32 count) // Downscale (or not) and extract the background image for the blurring Context->ResetRenderTarget(); Context->SetRenderTarget(blurA->View()); - Context->SetViewport((float)renderTargetWidth, (float)renderTargetHeight); + Context->SetViewportAndScissors((float)renderTargetWidth, (float)renderTargetHeight); Context->BindSR(0, Output); Context->SetState(CurrentPso->PS_Downscale); Context->DrawFullscreenTriangle(); From 6ffa497c0a0d31d34c4b46e91591ad1239cffe74 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Wed, 3 Feb 2021 21:52:49 +0100 Subject: [PATCH 14/68] Fixes for Render2D --- Source/Engine/Render2D/Render2D.cpp | 74 ++++++++++++++--------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/Source/Engine/Render2D/Render2D.cpp b/Source/Engine/Render2D/Render2D.cpp index 154dbe636..c956566ca 100644 --- a/Source/Engine/Render2D/Render2D.cpp +++ b/Source/Engine/Render2D/Render2D.cpp @@ -182,41 +182,44 @@ struct ClipMask Render2D::RenderingFeatures Render2D::Features = RenderingFeatures::VertexSnapping; -// Private Stuff -GPUContext* Context = nullptr; -GPUTextureView* Output = nullptr; -GPUTextureView* DepthBuffer = nullptr; -Viewport View; -Matrix ViewProjection; +namespace +{ + // Private Stuff + GPUContext* Context = nullptr; + GPUTextureView* Output = nullptr; + GPUTextureView* DepthBuffer = nullptr; + Viewport View; + Matrix ViewProjection; -// Drawing -Array DrawCalls; -Array Lines; -Array Lines2; -bool IsScissorsRectEmpty; -bool IsScissorsRectEnabled; + // Drawing + Array DrawCalls; + Array Lines; + Array Lines2; + bool IsScissorsRectEmpty; + bool IsScissorsRectEnabled; -// Transform -// Note: we use Matrix3x3 instead of Matrix because we use only 2D transformations on CPU side -// Matrix layout: -// [ m1, m2, 0 ] -// [ m3, m4, 0 ] -// [ t1, t2, 1 ] -// where 'm' is 2D transformation (scale, shear and rotate), 't' is translation -Array> TransformLayersStack; -Matrix3x3 TransformCached; + // Transform + // Note: we use Matrix3x3 instead of Matrix because we use only 2D transformations on CPU side + // Matrix layout: + // [ m1, m2, 0 ] + // [ m3, m4, 0 ] + // [ t1, t2, 1 ] + // where 'm' is 2D transformation (scale, shear and rotate), 't' is translation + Array> TransformLayersStack; + Matrix3x3 TransformCached; -Array> ClipLayersStack; + Array> ClipLayersStack; -// Shader -AssetReference GUIShader; -CachedPSO PsoDepth; -CachedPSO PsoNoDepth; -CachedPSO* CurrentPso = nullptr; -DynamicVertexBuffer VB(RENDER2D_INITIAL_VB_CAPACITY, (uint32)sizeof(Render2DVertex), TEXT("Render2D.VB")); -DynamicIndexBuffer IB(RENDER2D_INITIAL_IB_CAPACITY, sizeof(uint32), TEXT("Render2D.IB")); -uint32 VBIndex = 0; -uint32 IBIndex = 0; + // Shader + AssetReference GUIShader; + CachedPSO PsoDepth; + CachedPSO PsoNoDepth; + CachedPSO* CurrentPso = nullptr; + DynamicVertexBuffer VB(RENDER2D_INITIAL_VB_CAPACITY, (uint32)sizeof(Render2DVertex), TEXT("Render2D.VB")); + DynamicIndexBuffer IB(RENDER2D_INITIAL_IB_CAPACITY, sizeof(uint32), TEXT("Render2D.IB")); + uint32 VBIndex = 0; + uint32 IBIndex = 0; +} #define RENDER2D_WRITE_IB_QUAD(indices) \ indices[0] = VBIndex + 0; \ @@ -957,8 +960,8 @@ void DrawBatch(int32 startIndex, int32 count) data.Bounds.Y = bounds.Y; data.Bounds.Z = bounds.Z - bounds.X; data.Bounds.W = bounds.W - bounds.Y; - data.InvBufferSize.X = 1.0f / renderTargetWidth; - data.InvBufferSize.Y = 1.0f / renderTargetHeight; + data.InvBufferSize.X = 1.0f / (float)renderTargetWidth; + data.InvBufferSize.Y = 1.0f / (float)renderTargetHeight; data.SampleCount = ComputeBlurWeights(kernelSize, blurStrength, data.WeightAndOffsets); const auto cb = GUIShader->GetShader()->GetCB(1); Context->UpdateCB(cb, &data); @@ -1003,11 +1006,8 @@ void DrawBatch(int32 startIndex, int32 count) break; } case DrawCallType::ClipScissors: - { - Rectangle* scissorsRect = (Rectangle*)&d.AsClipScissors.X; - Context->SetScissor(*scissorsRect); + Context->SetScissor(*(Rectangle*)&d.AsClipScissors.X); return; - } case DrawCallType::LineAA: Context->SetState(CurrentPso->PS_LineAA); break; From 85c219369d3194b10c4aa52524dcbb86990daeb2 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Wed, 3 Feb 2021 21:59:21 +0100 Subject: [PATCH 15/68] Fix updating UI layout when adding control Fixes #190 --- Source/Engine/UI/UIControl.cs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/Source/Engine/UI/UIControl.cs b/Source/Engine/UI/UIControl.cs index e0f15a106..e4a6b4e33 100644 --- a/Source/Engine/UI/UIControl.cs +++ b/Source/Engine/UI/UIControl.cs @@ -30,10 +30,11 @@ namespace FlaxEngine return; // Cleanup previous - if (_control != null) + var prevControl = _control; + if (prevControl != null) { - _control.LocationChanged -= OnControlLocationChanged; - _control.Dispose(); + prevControl.LocationChanged -= OnControlLocationChanged; + prevControl.Dispose(); } // Set value @@ -42,16 +43,17 @@ namespace FlaxEngine // Link the new one (events and parent) if (_control != null) { + // Setup control var containerControl = _control as ContainerControl; if (containerControl != null) containerControl.UnlockChildrenRecursive(); - _control.Parent = GetParent(); _control.IndexInParent = OrderInParent; _control.Location = new Vector2(LocalPosition); // TODO: sync control order in parent with actor order in parent (think about special cases like Panel with scroll bars used as internal controls) _control.LocationChanged += OnControlLocationChanged; + // Link children UI controls if (containerControl != null && IsActiveInHierarchy) { var children = ChildrenCount; @@ -64,6 +66,12 @@ namespace FlaxEngine } } } + + // Refresh + if (prevControl == null && _control.Parent != null) + _control.Parent.PerformLayout(); + else + _control.PerformLayout(); } } } From 9c348b284fe38c33942155afe871f8e235a6d5a4 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Wed, 3 Feb 2021 22:00:12 +0100 Subject: [PATCH 16/68] Fixes for UI control sync --- Source/Engine/UI/UIControl.cs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/Source/Engine/UI/UIControl.cs b/Source/Engine/UI/UIControl.cs index e4a6b4e33..b31d9cab0 100644 --- a/Source/Engine/UI/UIControl.cs +++ b/Source/Engine/UI/UIControl.cs @@ -13,6 +13,7 @@ namespace FlaxEngine partial class UIControl { private Control _control; + private static bool _blockEvents; // Used to ignore internal events from C++ UIControl impl when performing state sync with C# UI /// /// Gets or sets the GUI control used by this actor. @@ -44,6 +45,7 @@ namespace FlaxEngine if (_control != null) { // Setup control + _blockEvents = true; var containerControl = _control as ContainerControl; if (containerControl != null) containerControl.UnlockChildrenRecursive(); @@ -68,6 +70,7 @@ namespace FlaxEngine } // Refresh + _blockEvents = false; if (prevControl == null && _control.Parent != null) _control.Parent.PerformLayout(); else @@ -178,7 +181,9 @@ namespace FlaxEngine private void OnControlLocationChanged(Control control) { + _blockEvents = true; LocalPosition = new Vector3(control.Location, LocalPosition.Z); + _blockEvents = false; } /// @@ -293,7 +298,7 @@ namespace FlaxEngine internal void ParentChanged() { - if (_control != null) + if (_control != null && !_blockEvents) { _control.Parent = GetParent(); _control.IndexInParent = OrderInParent; @@ -302,13 +307,15 @@ namespace FlaxEngine internal void TransformChanged() { - if (_control != null) + if (_control != null && !_blockEvents) + { _control.Location = new Vector2(LocalPosition); + } } internal void ActiveInTreeChanged() { - if (_control != null) + if (_control != null && !_blockEvents) { // Link or unlink control (won't modify Enable/Visible state) _control.Parent = GetParent(); @@ -318,8 +325,10 @@ namespace FlaxEngine internal void OrderInParentChanged() { - if (_control != null) + if (_control != null && !_blockEvents) + { _control.IndexInParent = OrderInParent; + } } internal void BeginPlay() From 4949ea4b3b48283c6585a3bb7194104f903256e9 Mon Sep 17 00:00:00 2001 From: "W2.Wizard" Date: Wed, 3 Feb 2021 22:24:08 +0100 Subject: [PATCH 17/68] Applied review changes --- .../Tools/MaterialGenerator/MaterialGenerator.Material.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp index 83251089f..16d9623ec 100644 --- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp +++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp @@ -435,7 +435,7 @@ void MaterialGenerator::ProcessGroupMaterial(Box* box, Node* node, Value& value) // Blackbody case 35: { - // Based on unity's implementation by using data gathered by Mitchell Charity. + // Reference: Mitchell Charity, http://www.vendian.org/mncharity/dir3/blackbody/ const auto temperature = tryGetValue(node->GetBox(0), node->Values[0]).AsFloat(); @@ -451,9 +451,7 @@ void MaterialGenerator::ProcessGroupMaterial(Box* box, Node* node, Value& value) // Final color auto color = writeLocal(ValueType::Vector3, String::Format(TEXT("float3({0}, {1}, {2})"), x.Value, y.Value, z.Value), node); color = writeLocal(ValueType::Vector3, String::Format(TEXT("clamp({0}, 0.0f, 255.0f) / 255.0f"), color.Value), node); - color = writeLocal(ValueType::Vector3, String::Format(TEXT("{1} < 1000.0f ? {0} * {1}/1000.0f : {0}"), color.Value, temperature.Value), node); - - value = color; + value = writeLocal(ValueType::Vector3, String::Format(TEXT("{1} < 1000.0f ? {0} * {1}/1000.0f : {0}"), color.Value, temperature.Value), node); break; } default: From e3142e640853b5c6cbd269c604946da000f45efb Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Wed, 3 Feb 2021 22:34:11 +0100 Subject: [PATCH 18/68] Fix updating input fields on editing end without changes Fixes #197 --- Source/Editor/GUI/Input/ValueBox.cs | 21 +++++++++++++++++++-- Source/Engine/UI/GUI/Common/TextBoxBase.cs | 2 ++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/Source/Editor/GUI/Input/ValueBox.cs b/Source/Editor/GUI/Input/ValueBox.cs index 8ee1c3887..d34acd17b 100644 --- a/Source/Editor/GUI/Input/ValueBox.cs +++ b/Source/Editor/GUI/Input/ValueBox.cs @@ -49,6 +49,11 @@ namespace FlaxEditor.GUI.Input /// protected T _startSlideValue; + /// + /// The text cached on editing start. Used to compare with the end result to detect changes. + /// + protected string _startEditText; + private Vector2 _startSlideLocation; /// @@ -257,11 +262,23 @@ namespace FlaxEditor.GUI.Input return base.OnMouseUp(location, button); } + /// + protected override void OnEditBegin() + { + base.OnEditBegin(); + + _startEditText = _text; + } + /// protected override void OnEditEnd() { - // Update value - TryGetValue(); + if (_startEditText != _text) + { + // Update value + TryGetValue(); + } + _startEditText = null; base.OnEditEnd(); } diff --git a/Source/Engine/UI/GUI/Common/TextBoxBase.cs b/Source/Engine/UI/GUI/Common/TextBoxBase.cs index 107da6f40..ccf346ed6 100644 --- a/Source/Engine/UI/GUI/Common/TextBoxBase.cs +++ b/Source/Engine/UI/GUI/Common/TextBoxBase.cs @@ -942,6 +942,8 @@ namespace FlaxEngine.GUI { base.OnLostFocus(); + if (IsReadOnly) + return; OnEditEnd(); } From 880a8c9f58044f0a6cee99638ac6074e53c84da8 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Wed, 3 Feb 2021 23:10:36 +0100 Subject: [PATCH 19/68] Add support for parsing exponential (scientific) notation numbers in input fields --- Source/Editor/Utilities/ShuntingYardParser.cs | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/Source/Editor/Utilities/ShuntingYardParser.cs b/Source/Editor/Utilities/ShuntingYardParser.cs index 100c5c3d7..a07026d1c 100644 --- a/Source/Editor/Utilities/ShuntingYardParser.cs +++ b/Source/Editor/Utilities/ShuntingYardParser.cs @@ -193,6 +193,7 @@ namespace FlaxEditor.Utilities { case 'x': case 'X': + { // Hexadecimal value i++; token.Clear(); @@ -200,22 +201,35 @@ namespace FlaxEditor.Utilities throw new ParsingException("invalid hexadecimal number"); while (i + 1 < text.Length && StringUtils.IsHexDigit(text[i + 1])) { - i++; - token.Append(text[i]); + token.Append(text[++i]); } var value = ulong.Parse(token.ToString(), NumberStyles.HexNumber); token.Clear(); token.Append(value.ToString()); break; + } default: + { // Decimal value while (i + 1 < text.Length && DetermineType(text[i + 1]) == TokenType.Number) { - i++; - token.Append(text[i]); + token.Append(text[++i]); + } + + // Exponential notation + if (i + 2 < text.Length && (text[i + 1] == 'e' || text[i + 1] == 'E')) + { + token.Append(text[++i]); + if (text[i + 1] == '-' || text[i + 1] == '+') + token.Append(text[++i]); + while (i + 1 < text.Length && DetermineType(text[i + 1]) == TokenType.Number) + { + token.Append(text[++i]); + } } break; } + } } // Discard solo '-' From 7868c6505d84cc450ceb9fb7e3ba03d7ae3fe46f Mon Sep 17 00:00:00 2001 From: SilentCLD Date: Thu, 4 Feb 2021 17:49:54 +0000 Subject: [PATCH 20/68] [Editor/Docking] Bring window to front on focus --- Source/Editor/GUI/Docking/DockWindow.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Source/Editor/GUI/Docking/DockWindow.cs b/Source/Editor/GUI/Docking/DockWindow.cs index aa6d94ca8..56c78efed 100644 --- a/Source/Editor/GUI/Docking/DockWindow.cs +++ b/Source/Editor/GUI/Docking/DockWindow.cs @@ -307,6 +307,14 @@ namespace FlaxEditor.GUI.Docking _dockedTo?.SelectTab(this, autoFocus); } + /// + /// Brings the window to the front of the Z order. + /// + public void BringToFront() + { + _dockedTo?.RootWindow?.BringToFront(); + } + internal void OnUnlinkInternal() { OnUnlink(); @@ -412,6 +420,7 @@ namespace FlaxEditor.GUI.Docking base.Focus(); SelectTab(); + BringToFront(); } /// From ae785267c2426444bde9fa60e823e46f0ba58c50 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 4 Feb 2021 22:32:37 +0100 Subject: [PATCH 21/68] Fix scaling rotated objects in world space Fixes #200 --- Source/Editor/Gizmo/TransformGizmoBase.cs | 63 ++++++++++++----------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/Source/Editor/Gizmo/TransformGizmoBase.cs b/Source/Editor/Gizmo/TransformGizmoBase.cs index 93dbeddaa..014143685 100644 --- a/Source/Editor/Gizmo/TransformGizmoBase.cs +++ b/Source/Editor/Gizmo/TransformGizmoBase.cs @@ -196,12 +196,10 @@ namespace FlaxEditor.Gizmo private void UpdateTranslateScale() { bool isScaling = _activeMode == Mode.Scale; - Vector3 delta = Vector3.Zero; Ray ray = Owner.MouseRay; - Matrix invRotationMatrix; - Matrix.Invert(ref _rotationMatrix, out invRotationMatrix); + Matrix.Invert(ref _rotationMatrix, out var invRotationMatrix); ray.Position = Vector3.Transform(ray.Position, invRotationMatrix); Vector3.TransformNormal(ref ray.Direction, ref invRotationMatrix, out ray.Direction); @@ -211,9 +209,7 @@ namespace FlaxEditor.Gizmo case Axis.X: { var plane = new Plane(Vector3.Backward, Vector3.Transform(Position, invRotationMatrix).Z); - - float intersection; - if (ray.Intersects(ref plane, out intersection)) + if (ray.Intersects(ref plane, out float intersection)) { _intersectPosition = ray.Position + ray.Direction * intersection; if (_lastIntersectionPosition != Vector3.Zero) @@ -222,18 +218,14 @@ namespace FlaxEditor.Gizmo ? new Vector3(_tDelta.X, 0, 0) : new Vector3(_tDelta.X, _tDelta.Y, 0); } - break; } - case Axis.Z: case Axis.YZ: case Axis.Y: { var plane = new Plane(Vector3.Left, Vector3.Transform(Position, invRotationMatrix).X); - - float intersection; - if (ray.Intersects(ref plane, out intersection)) + if (ray.Intersects(ref plane, out float intersection)) { _intersectPosition = ray.Position + ray.Direction * intersection; if (_lastIntersectionPosition != Vector3.Zero) @@ -251,41 +243,31 @@ namespace FlaxEditor.Gizmo break; } } - break; } - case Axis.ZX: { var plane = new Plane(Vector3.Down, Vector3.Transform(Position, invRotationMatrix).Y); - - float intersection; - if (ray.Intersects(ref plane, out intersection)) + if (ray.Intersects(ref plane, out float intersection)) { _intersectPosition = ray.Position + ray.Direction * intersection; if (_lastIntersectionPosition != Vector3.Zero) _tDelta = _intersectPosition - _lastIntersectionPosition; delta = new Vector3(_tDelta.X, 0, _tDelta.Z); } - break; } - case Axis.Center: { - Vector3 gizmoToView = Position - Owner.ViewPosition; + var gizmoToView = Position - Owner.ViewPosition; var plane = new Plane(-Vector3.Normalize(gizmoToView), gizmoToView.Length); - - float intersection; - if (ray.Intersects(ref plane, out intersection)) + if (ray.Intersects(ref plane, out float intersection)) { _intersectPosition = ray.Position + ray.Direction * intersection; if (_lastIntersectionPosition != Vector3.Zero) _tDelta = _intersectPosition - _lastIntersectionPosition; } - delta = _tDelta; - break; } } @@ -299,14 +281,11 @@ namespace FlaxEditor.Gizmo if ((isScaling ? ScaleSnapEnabled : TranslationSnapEnable) || Owner.UseSnapping) { float snapValue = isScaling ? ScaleSnapValue : TranslationSnapValue; - _translationScaleSnapDelta += delta; - delta = new Vector3( (int)(_translationScaleSnapDelta.X / snapValue) * snapValue, (int)(_translationScaleSnapDelta.Y / snapValue) * snapValue, (int)(_translationScaleSnapDelta.Z / snapValue) * snapValue); - _translationScaleSnapDelta -= delta; } @@ -318,7 +297,30 @@ namespace FlaxEditor.Gizmo } else if (_activeMode == Mode.Scale) { - // Apply scale + // Scale + if (_activeTransformSpace == TransformSpace.World && _activeAxis != Axis.Center) + { + var deltaLocal = delta; + Quaternion orientation = GetSelectedObject(0).Orientation; + delta = Vector3.Transform(delta, orientation); + + // Fix axis sign of delta movement for rotated object in some cases (eg. rotated object by 90 deg on Y axis and scale in world space with Red/X axis) + switch (_activeAxis) + { + case Axis.X: + if (deltaLocal.X < 0) + delta *= -1; + break; + case Axis.Y: + if (deltaLocal.Y < 0) + delta *= -1; + break; + case Axis.Z: + if (deltaLocal.Z < 0) + delta *= -1; + break; + } + } _scaleDelta = delta; } } @@ -382,7 +384,7 @@ namespace FlaxEditor.Gizmo // Snap to ground if (_activeAxis == Axis.None && SelectionCount != 0 && Owner.SnapToGround) { - if (Physics.RayCast(Position, Vector3.Down, out var hit, float.MaxValue, int.MaxValue, false)) + if (Physics.RayCast(Position, Vector3.Down, out var hit, float.MaxValue, uint.MaxValue, false)) { StartTransforming(); var translationDelta = hit.Point - Position; @@ -408,7 +410,6 @@ namespace FlaxEditor.Gizmo case Mode.Translate: UpdateTranslateScale(); break; - case Mode.Rotate: UpdateRotate(dt); break; @@ -437,7 +438,7 @@ namespace FlaxEditor.Gizmo translationDelta = _translationDelta; _translationDelta = Vector3.Zero; - // Prevent from moving objects too far away, like to different galaxy or sth + // Prevent from moving objects too far away, like to a different galaxy or sth Vector3 prevMoveDelta = _accMoveDelta; _accMoveDelta += _translationDelta; if (_accMoveDelta.Length > Owner.ViewFarPlane * 0.7f) From db55f5ea3f838aed0767568480377b8581f66149 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 4 Feb 2021 22:59:13 +0100 Subject: [PATCH 22/68] Fix crash when changing prefab root object --- .../Editor/Viewport/Previews/PrefabPreview.cs | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/Source/Editor/Viewport/Previews/PrefabPreview.cs b/Source/Editor/Viewport/Previews/PrefabPreview.cs index d0ed8a0c2..a9f5a7d22 100644 --- a/Source/Editor/Viewport/Previews/PrefabPreview.cs +++ b/Source/Editor/Viewport/Previews/PrefabPreview.cs @@ -72,7 +72,28 @@ namespace FlaxEditor.Viewport.Previews public Actor Instance { get => _instance; - internal set => _instance = value; + internal set + { + if (_instance == value) + return; + + if (_instance) + { + if (customControlLinked != null) + { + customControlLinked.Parent = null; + customControlLinked = null; + } + Task.RemoveCustomActor(_instance); + } + + _instance = value; + + if (_instance) + { + Task.AddCustomActor(_instance); + } + } } /// From 3661b19d6ccd0fb52156c9bce187a1789a986f33 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 4 Feb 2021 23:34:44 +0100 Subject: [PATCH 23/68] Fix some prefabs issues --- Source/Editor/Editor.cs | 2 +- .../Editor/Viewport/Previews/PrefabPreview.cs | 73 +++++++++++-------- .../Windows/Assets/PrefabWindow.Hierarchy.cs | 5 +- 3 files changed, 45 insertions(+), 35 deletions(-) diff --git a/Source/Editor/Editor.cs b/Source/Editor/Editor.cs index 59810043d..f81f81ddd 100644 --- a/Source/Editor/Editor.cs +++ b/Source/Editor/Editor.cs @@ -254,7 +254,7 @@ namespace FlaxEditor if (loadingPreview != null) { // Link it to the prefab preview to see it in the editor - loadingPreview.customControlLinked = control.Control; + loadingPreview.customControlLinked = control; return loadingPreview; } return null; diff --git a/Source/Editor/Viewport/Previews/PrefabPreview.cs b/Source/Editor/Viewport/Previews/PrefabPreview.cs index a9f5a7d22..aa04a41fd 100644 --- a/Source/Editor/Viewport/Previews/PrefabPreview.cs +++ b/Source/Editor/Viewport/Previews/PrefabPreview.cs @@ -1,7 +1,6 @@ // Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. using FlaxEngine; -using FlaxEngine.GUI; using Object = FlaxEngine.Object; namespace FlaxEditor.Viewport.Previews @@ -19,7 +18,7 @@ namespace FlaxEditor.Viewport.Previews private Prefab _prefab; private Actor _instance; - internal Control customControlLinked; + internal UIControl customControlLinked; /// /// Gets or sets the prefab asset to preview. @@ -29,39 +28,47 @@ namespace FlaxEditor.Viewport.Previews get => _prefab; set { - if (_prefab != value) + if (_prefab == value) + return; + + if (_instance) { - if (_instance) + // Unlink UI control + if (customControlLinked) { - if (customControlLinked != null) - { - customControlLinked.Parent = null; - customControlLinked = null; - } - Task.RemoveCustomActor(_instance); - Object.Destroy(_instance); + if (customControlLinked.Control?.Parent == this) + customControlLinked.Control.Parent = null; + customControlLinked = null; } - _prefab = value; + // Remove for preview + Task.RemoveCustomActor(_instance); - if (_prefab) + // Delete + Object.Destroy(_instance); + } + + _prefab = value; + + if (_prefab) + { + _prefab.WaitForLoaded(); + + var prevPreview = LoadingPreview; + LoadingPreview = this; + + _instance = PrefabManager.SpawnPrefab(_prefab, null); + + LoadingPreview = prevPreview; + + if (_instance == null) { - _prefab.WaitForLoaded(); // TODO: use lazy prefab spawning to reduce stalls - - var prevPreview = LoadingPreview; - LoadingPreview = this; - - _instance = PrefabManager.SpawnPrefab(_prefab, null); - - LoadingPreview = prevPreview; - - if (_instance == null) - { - _prefab = null; - throw new FlaxException("Failed to spawn a prefab for the preview."); - } - Task.AddCustomActor(_instance); + _prefab = null; + throw new FlaxException("Failed to spawn a prefab for the preview."); } + + // Add to preview + Task.AddCustomActor(_instance); } } } @@ -79,11 +86,15 @@ namespace FlaxEditor.Viewport.Previews if (_instance) { - if (customControlLinked != null) + // Unlink UI control + if (customControlLinked) { - customControlLinked.Parent = null; + if (customControlLinked.Control?.Parent == this) + customControlLinked.Control.Parent = null; customControlLinked = null; } + + // Remove for preview Task.RemoveCustomActor(_instance); } @@ -91,6 +102,7 @@ namespace FlaxEditor.Viewport.Previews if (_instance) { + // Add to preview Task.AddCustomActor(_instance); } } @@ -108,7 +120,6 @@ namespace FlaxEditor.Viewport.Previews /// public override void OnDestroy() { - // Cleanup Prefab = null; base.OnDestroy(); diff --git a/Source/Editor/Windows/Assets/PrefabWindow.Hierarchy.cs b/Source/Editor/Windows/Assets/PrefabWindow.Hierarchy.cs index 08621f2ec..bded7e147 100644 --- a/Source/Editor/Windows/Assets/PrefabWindow.Hierarchy.cs +++ b/Source/Editor/Windows/Assets/PrefabWindow.Hierarchy.cs @@ -69,6 +69,7 @@ namespace FlaxEditor.Windows.Assets bool hasSthSelected = Selection.Count > 0; bool isSingleActorSelected = Selection.Count == 1 && Selection[0] is ActorNode; bool isRootSelected = isSingleActorSelected && Selection[0] == Graph.Main; + bool hasPrefabLink = isSingleActorSelected && (Selection[0] as ActorNode).HasPrefabLink; // Create popup @@ -97,7 +98,7 @@ namespace FlaxEditor.Windows.Assets b.Enabled = hasSthSelected && !isRootSelected; b = contextMenu.AddButton("Set Root", SetRoot); - b.Enabled = isSingleActorSelected && !isRootSelected; + b.Enabled = isSingleActorSelected && !isRootSelected && hasPrefabLink; // Prefab options @@ -108,8 +109,6 @@ namespace FlaxEditor.Windows.Assets (Selection[0] as ActorNode).CanCreatePrefab && Editor.Windows.ContentWin.CurrentViewFolder.CanHaveAssets; - bool hasPrefabLink = isSingleActorSelected && (Selection[0] as ActorNode).HasPrefabLink; - b = contextMenu.AddButton("Select Prefab", Editor.Prefabs.SelectPrefab); b.Enabled = hasPrefabLink; From 0e57b32082846e52c81bc72047d22c85b9606d34 Mon Sep 17 00:00:00 2001 From: "W2.Wizard" Date: Fri, 5 Feb 2021 15:49:01 +0100 Subject: [PATCH 24/68] Fixed issue #210 This will fix the issue described in #210. Co-Authored-By: VNC <52937757+VNNCC@users.noreply.github.com> --- Source/Editor/Content/Tree/ContentTreeNode.cs | 6 ++- Source/Editor/Windows/ContentWindow.cs | 38 +++++-------------- 2 files changed, 14 insertions(+), 30 deletions(-) diff --git a/Source/Editor/Content/Tree/ContentTreeNode.cs b/Source/Editor/Content/Tree/ContentTreeNode.cs index 7df407e08..07ce7f803 100644 --- a/Source/Editor/Content/Tree/ContentTreeNode.cs +++ b/Source/Editor/Content/Tree/ContentTreeNode.cs @@ -295,7 +295,8 @@ namespace FlaxEditor.Content StartRenaming(); return true; case KeyboardKeys.Delete: - Editor.Instance.Windows.ContentWin.Delete(Folder); + if(Folder.Exists) + Editor.Instance.Windows.ContentWin.Delete(Folder); return true; } if (RootWindow.GetKey(KeyboardKeys.Control)) @@ -303,7 +304,8 @@ namespace FlaxEditor.Content switch (key) { case KeyboardKeys.D: - Editor.Instance.Windows.ContentWin.Duplicate(Folder); + if(Folder.Exists) + Editor.Instance.Windows.ContentWin.Duplicate(Folder); return true; } } diff --git a/Source/Editor/Windows/ContentWindow.cs b/Source/Editor/Windows/ContentWindow.cs index 66ed50daf..a09bc1c6e 100644 --- a/Source/Editor/Windows/ContentWindow.cs +++ b/Source/Editor/Windows/ContentWindow.cs @@ -396,7 +396,7 @@ namespace FlaxEditor.Windows /// The item to delete. public void Delete(ContentItem item) { - Delete(new List { item }); + Delete(new List(1) { item }); } /// @@ -405,42 +405,24 @@ namespace FlaxEditor.Windows /// The items to delete. public void Delete(List items) { + if (items.Count == 0) return; + // TODO: remove items that depend on different items in the list: use wants to remove `folderA` and `folderA/asset.x`, we should just remove `folderA` var toDelete = new List(items); + string msg = toDelete.Count == 1 ? + string.Format("Are you sure to delete \'{0}\'?\nThis action cannot be undone. Files will be deleted permanently.", items[0].Path) + : string.Format("Are you sure to delete {0} selected items?\nThis action cannot be undone. Files will be deleted permanently.", items.Count); + // Ask user - if (toDelete.Count == 1) - { - // Single item - if (MessageBox.Show(string.Format("Are you sure to delete \'{0}\'?\nThis action cannot be undone. Files will be deleted permanently.", items[0].Path), - "Delete asset(s)", - MessageBoxButtons.OKCancel, - MessageBoxIcon.Question) - != DialogResult.OK) - { - // Break - return; - } - } - else - { - // Many items - if (MessageBox.Show(string.Format("Are you sure to delete {0} selected items?\nThis action cannot be undone. Files will be deleted permanently.", items.Count), - "Delete asset(s)", - MessageBoxButtons.OKCancel, - MessageBoxIcon.Question) - != DialogResult.OK) - { - // Break - return; - } - } + if (MessageBox.Show(msg, "Delete asset(s)", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) != DialogResult.OK) + return; // Clear navigation // TODO: just remove invalid locations from the history (those are removed) NavigationClearHistory(); - // Delete items + // Delete for (int i = 0; i < toDelete.Count; i++) Editor.ContentDatabase.Delete(toDelete[i]); From 2fbfe61f2c230884fed0c1042152e08b6caf0a53 Mon Sep 17 00:00:00 2001 From: "W2.Wizard" Date: Fri, 5 Feb 2021 15:59:35 +0100 Subject: [PATCH 25/68] Restore comment Co-Authored-By: VNC <52937757+VNNCC@users.noreply.github.com> --- Source/Editor/Windows/ContentWindow.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Editor/Windows/ContentWindow.cs b/Source/Editor/Windows/ContentWindow.cs index a09bc1c6e..145c0d972 100644 --- a/Source/Editor/Windows/ContentWindow.cs +++ b/Source/Editor/Windows/ContentWindow.cs @@ -422,7 +422,7 @@ namespace FlaxEditor.Windows // TODO: just remove invalid locations from the history (those are removed) NavigationClearHistory(); - // Delete + // Delete items for (int i = 0; i < toDelete.Count; i++) Editor.ContentDatabase.Delete(toDelete[i]); From 78e4ba2f1711a5bc2f10735e0ca890fd08ee9b53 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 5 Feb 2021 21:11:35 +0100 Subject: [PATCH 26/68] Add support for UICanvas preview in Prefab Viewport Fixes #157 --- .../Editor/Viewport/Previews/PrefabPreview.cs | 48 ++++----- Source/Engine/UI/UICanvas.cs | 97 +++++++++++++++++-- 2 files changed, 116 insertions(+), 29 deletions(-) diff --git a/Source/Editor/Viewport/Previews/PrefabPreview.cs b/Source/Editor/Viewport/Previews/PrefabPreview.cs index aa04a41fd..066e98456 100644 --- a/Source/Editor/Viewport/Previews/PrefabPreview.cs +++ b/Source/Editor/Viewport/Previews/PrefabPreview.cs @@ -31,44 +31,34 @@ namespace FlaxEditor.Viewport.Previews if (_prefab == value) return; + // Unset and cleanup spawned instance if (_instance) { - // Unlink UI control - if (customControlLinked) - { - if (customControlLinked.Control?.Parent == this) - customControlLinked.Control.Parent = null; - customControlLinked = null; - } - - // Remove for preview - Task.RemoveCustomActor(_instance); - - // Delete - Object.Destroy(_instance); + var instance = _instance; + Instance = null; + Object.Destroy(instance); } _prefab = value; if (_prefab) { + // Load prefab _prefab.WaitForLoaded(); + // Spawn prefab var prevPreview = LoadingPreview; LoadingPreview = this; - - _instance = PrefabManager.SpawnPrefab(_prefab, null); - + var instance = PrefabManager.SpawnPrefab(_prefab, null); LoadingPreview = prevPreview; - - if (_instance == null) + if (instance == null) { _prefab = null; throw new FlaxException("Failed to spawn a prefab for the preview."); } - // Add to preview - Task.AddCustomActor(_instance); + // Set instance + Instance = instance; } } } @@ -94,7 +84,7 @@ namespace FlaxEditor.Viewport.Previews customControlLinked = null; } - // Remove for preview + // Remove for the preview Task.RemoveCustomActor(_instance); } @@ -102,12 +92,26 @@ namespace FlaxEditor.Viewport.Previews if (_instance) { - // Add to preview + // Add to the preview Task.AddCustomActor(_instance); + + // Link UI canvases to the preview + LinkCanvas(_instance); } } } + private void LinkCanvas(Actor actor) + { + if (actor is UICanvas uiCanvas) + uiCanvas.EditorOverride(Task, this); + var children = actor.ChildrenCount; + for (int i = 0; i < children; i++) + { + LinkCanvas(actor.GetChild(i)); + } + } + /// /// Initializes a new instance of the class. /// diff --git a/Source/Engine/UI/UICanvas.cs b/Source/Engine/UI/UICanvas.cs index e0b6425de..65956293b 100644 --- a/Source/Engine/UI/UICanvas.cs +++ b/Source/Engine/UI/UICanvas.cs @@ -1,5 +1,6 @@ // Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. +using System; using System.Globalization; using System.IO; using System.Text; @@ -279,16 +280,41 @@ namespace FlaxEngine else if (_renderMode == CanvasRenderMode.CameraSpace) { Matrix tmp1, tmp2; + Vector3 viewPos, viewUp, viewForward, pos; + Quaternion viewRot; // Use default camera is not specified var camera = RenderCamera ?? Camera.MainCamera; +#if FLAX_EDITOR + if (_editorTask) + { + // Use editor viewport task to override Camera Space placement + var view = _editorTask.View; + var frustum = view.Frustum; + if (!frustum.IsOrthographic) + _guiRoot.Size = new Vector2(frustum.GetWidthAtDepth(Distance), frustum.GetHeightAtDepth(Distance)); + else + _guiRoot.Size = _editorTask.Viewport.Size; + Matrix.Translation(_guiRoot.Width / -2.0f, _guiRoot.Height / -2.0f, 0, out world); + Matrix.RotationYawPitchRoll(Mathf.Pi, Mathf.Pi, 0, out tmp2); + Matrix.Multiply(ref world, ref tmp2, out tmp1); + viewPos = view.Position; + viewRot = view.Direction != Vector3.Up ? Quaternion.LookRotation(view.Direction, Vector3.Up) : Quaternion.LookRotation(view.Direction, Vector3.Right); + viewUp = Vector3.Up * viewRot; + viewForward = view.Direction; + pos = view.Position + view.Direction * Distance; + Matrix.Billboard(ref pos, ref viewPos, ref viewUp, ref viewForward, out tmp2); + Matrix.Multiply(ref tmp1, ref tmp2, out world); + return; + } +#endif + // Adjust GUI size to the viewport size at the given distance form the camera var viewport = camera.Viewport; if (camera.UsePerspective) { - Matrix tmp3; - camera.GetMatrices(out tmp1, out tmp3, ref viewport); + camera.GetMatrices(out tmp1, out var tmp3, ref viewport); Matrix.Multiply(ref tmp1, ref tmp3, out tmp2); var frustum = new BoundingFrustum(tmp2); _guiRoot.Size = new Vector2(frustum.GetWidthAtDepth(Distance), frustum.GetHeightAtDepth(Distance)); @@ -304,11 +330,11 @@ namespace FlaxEngine Matrix.Multiply(ref world, ref tmp2, out tmp1); // In front of the camera - var viewPos = camera.Position; - var viewRot = camera.Orientation; - var viewUp = Vector3.Up * viewRot; - var viewForward = Vector3.Forward * viewRot; - var pos = viewPos + viewForward * Distance; + viewPos = camera.Position; + viewRot = camera.Orientation; + viewUp = Vector3.Up * viewRot; + viewForward = Vector3.Forward * viewRot; + pos = viewPos + viewForward * Distance; Matrix.Billboard(ref pos, ref viewPos, ref viewUp, ref viewForward, out tmp2); Matrix.Multiply(ref tmp1, ref tmp2, out world); @@ -334,11 +360,18 @@ namespace FlaxEngine _guiRoot.Offsets = Margin.Zero; if (_renderer) { +#if FLAX_EDITOR + _editorTask?.CustomPostFx.Remove(_renderer); +#endif SceneRenderTask.GlobalCustomPostFx.Remove(_renderer); _renderer.Canvas = null; Destroy(_renderer); _renderer = null; } +#if FLAX_EDITOR + if (_editorRoot) + _guiRoot.Parent = _editorRoot; +#endif break; } case CanvasRenderMode.CameraSpace: @@ -346,12 +379,31 @@ namespace FlaxEngine { // Render canvas manually _guiRoot.AnchorPreset = AnchorPresets.TopLeft; +#if FLAX_EDITOR + if (_editorRoot != null && _guiRoot != null) + _guiRoot.Parent = null; +#endif if (_renderer == null) { _renderer = New(); _renderer.Canvas = this; if (IsActiveInHierarchy && Scene) + { +#if FLAX_EDITOR + if (_editorTask != null) + { + _editorTask.CustomPostFx.Add(_renderer); + break; + } +#endif SceneRenderTask.GlobalCustomPostFx.Add(_renderer); + } +#if FLAX_EDITOR + else if (_editorTask != null && IsActiveInHierarchy) + { + _editorTask.CustomPostFx.Add(_renderer); + } +#endif } break; } @@ -490,10 +542,21 @@ namespace FlaxEngine internal void OnEnable() { +#if FLAX_EDITOR + _guiRoot.Parent = _editorRoot ?? RootControl.CanvasRoot; +#else _guiRoot.Parent = RootControl.CanvasRoot; +#endif if (_renderer) { +#if FLAX_EDITOR + if (_editorTask != null) + { + _editorTask.CustomPostFx.Add(_renderer); + return; + } +#endif SceneRenderTask.GlobalCustomPostFx.Add(_renderer); } } @@ -518,5 +581,25 @@ namespace FlaxEngine _renderer = null; } } + +#if FLAX_EDITOR + private SceneRenderTask _editorTask; + private ContainerControl _editorRoot; + + internal void EditorOverride(SceneRenderTask task, ContainerControl root) + { + if (_editorTask != null && _renderer != null) + _editorTask.CustomPostFx.Remove(_renderer); + if (_editorRoot != null && _guiRoot != null) + _guiRoot.Parent = null; + + _editorTask = task; + _editorRoot = root; + Setup(); + + if (RenderMode == CanvasRenderMode.ScreenSpace && _editorRoot != null && _guiRoot != null) + _guiRoot.Parent = _editorRoot; + } +#endif } } From 43692f514ac0ad4153ab6401728055348f24c75b Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 5 Feb 2021 21:11:41 +0100 Subject: [PATCH 27/68] Fix --- Source/Engine/UI/UICanvas.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Engine/UI/UICanvas.cs b/Source/Engine/UI/UICanvas.cs index 65956293b..426441493 100644 --- a/Source/Engine/UI/UICanvas.cs +++ b/Source/Engine/UI/UICanvas.cs @@ -369,7 +369,7 @@ namespace FlaxEngine _renderer = null; } #if FLAX_EDITOR - if (_editorRoot) + if (_editorRoot != null) _guiRoot.Parent = _editorRoot; #endif break; From 6b660c846b70c08112523169a518423258333633 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 5 Feb 2021 21:12:14 +0100 Subject: [PATCH 28/68] Fix updating prefab object reference values after apply in prefab editor --- Source/Editor/Windows/Assets/PrefabWindow.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Source/Editor/Windows/Assets/PrefabWindow.cs b/Source/Editor/Windows/Assets/PrefabWindow.cs index a8b3e24a4..4cc7898ee 100644 --- a/Source/Editor/Windows/Assets/PrefabWindow.cs +++ b/Source/Editor/Windows/Assets/PrefabWindow.cs @@ -284,6 +284,9 @@ namespace FlaxEditor.Windows.Assets { // Simply update changes Editor.Prefabs.ApplyAll(_viewport.Instance); + + // Refresh properties panel to sync new prefab default values + _propertiesEditor.BuildLayout(); } catch (Exception) { From d27edbf5a901c0ddea1458dd0e788c335a9a9dc4 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 5 Feb 2021 21:18:21 +0100 Subject: [PATCH 29/68] Format code --- Source/Editor/Content/Tree/ContentTreeNode.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Editor/Content/Tree/ContentTreeNode.cs b/Source/Editor/Content/Tree/ContentTreeNode.cs index 07ce7f803..4370bc8e7 100644 --- a/Source/Editor/Content/Tree/ContentTreeNode.cs +++ b/Source/Editor/Content/Tree/ContentTreeNode.cs @@ -295,7 +295,7 @@ namespace FlaxEditor.Content StartRenaming(); return true; case KeyboardKeys.Delete: - if(Folder.Exists) + if (Folder.Exists) Editor.Instance.Windows.ContentWin.Delete(Folder); return true; } @@ -304,7 +304,7 @@ namespace FlaxEditor.Content switch (key) { case KeyboardKeys.D: - if(Folder.Exists) + if (Folder.Exists) Editor.Instance.Windows.ContentWin.Duplicate(Folder); return true; } From 8a567f084950930dffde32fcb8de692471c4961c Mon Sep 17 00:00:00 2001 From: "W2.Wizard" Date: Sat, 6 Feb 2021 11:29:48 +0100 Subject: [PATCH 30/68] Fix issue #214 --- Source/Engine/Debug/DebugDraw.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Source/Engine/Debug/DebugDraw.cpp b/Source/Engine/Debug/DebugDraw.cpp index 457c90411..cdf1f412a 100644 --- a/Source/Engine/Debug/DebugDraw.cpp +++ b/Source/Engine/Debug/DebugDraw.cpp @@ -629,7 +629,11 @@ void DebugDraw::DrawLine(const Vector3& start, const Vector3& end, const Color& void DebugDraw::DrawLines(const Span& lines, const Matrix& transform, const Color& color, float duration, bool depthTest) { - ASSERT(lines.Length() % 2 == 0); + if (lines.Length() % 2 == 0) + { + LOG(Error, "Cannot draw debug lines with uneven amount of items in array"); + return; + } // Create draw call entry DebugLine l = { Vector3::Zero, Vector3::Zero, Color32(color), duration }; @@ -637,10 +641,12 @@ void DebugDraw::DrawLines(const Span& lines, const Matrix& transform, c // Add lines const Vector3* p = lines.Get(); Array* list; - if (depthTest) + + if (depthTest) list = duration > 0 ? &DebugDrawDepthTest.DefaultLines : &DebugDrawDepthTest.OneFrameLines; - else + else list = duration > 0 ? &DebugDrawDefault.DefaultLines : &DebugDrawDefault.OneFrameLines; + list->EnsureCapacity(list->Count() + lines.Length()); for (int32 i = 0; i < lines.Length(); i += 2) { From 5b3275653654120f294defeb20f995d7d303f73e Mon Sep 17 00:00:00 2001 From: "W2.Wizard" Date: Sat, 6 Feb 2021 11:32:58 +0100 Subject: [PATCH 31/68] Remove empty space Just noticed it, so bye bye. --- Source/Engine/Debug/DebugDraw.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Engine/Debug/DebugDraw.cpp b/Source/Engine/Debug/DebugDraw.cpp index cdf1f412a..f8b4a35ef 100644 --- a/Source/Engine/Debug/DebugDraw.cpp +++ b/Source/Engine/Debug/DebugDraw.cpp @@ -644,7 +644,7 @@ void DebugDraw::DrawLines(const Span& lines, const Matrix& transform, c if (depthTest) list = duration > 0 ? &DebugDrawDepthTest.DefaultLines : &DebugDrawDepthTest.OneFrameLines; - else + else list = duration > 0 ? &DebugDrawDefault.DefaultLines : &DebugDrawDefault.OneFrameLines; list->EnsureCapacity(list->Count() + lines.Length()); From f5d1ad5a9b2737b6d7412e67c007a2d1d7146715 Mon Sep 17 00:00:00 2001 From: "W2.Wizard" Date: Sat, 6 Feb 2021 13:32:04 +0100 Subject: [PATCH 32/68] Use ThrowException instead --- Source/Engine/Debug/DebugDraw.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/Engine/Debug/DebugDraw.cpp b/Source/Engine/Debug/DebugDraw.cpp index f8b4a35ef..c197a0d0d 100644 --- a/Source/Engine/Debug/DebugDraw.cpp +++ b/Source/Engine/Debug/DebugDraw.cpp @@ -19,6 +19,7 @@ #include "Engine/Graphics/RenderBuffers.h" #include "Engine/Animations/AnimationUtils.h" #include "Engine/Profiler/Profiler.h" +#include "Engine/Debug/DebugLog.h" // Debug draw service configuration #define DEBUG_DRAW_INITIAL_VB_CAPACITY (4 * 1024) @@ -631,7 +632,7 @@ void DebugDraw::DrawLines(const Span& lines, const Matrix& transform, c { if (lines.Length() % 2 == 0) { - LOG(Error, "Cannot draw debug lines with uneven amount of items in array"); + DebugLog::ThrowException("Cannot draw debug lines with uneven amount of items in array"); return; } From 25f35b22be9e757dbf95e653ff76cf5b470ff021 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sat, 6 Feb 2021 15:58:12 +0100 Subject: [PATCH 33/68] Add safety checks for particles data to prevent division by 0 --- ...rticleEmitterGraph.CPU.ParticleModules.cpp | 22 +++++++++---------- .../ParticleEmitterGraph.CPU.Particles.cpp | 2 +- ...rticleEmitterGraph.GPU.ParticleModules.cpp | 22 +++++++++---------- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/Source/Engine/Particles/Graph/CPU/ParticleEmitterGraph.CPU.ParticleModules.cpp b/Source/Engine/Particles/Graph/CPU/ParticleEmitterGraph.CPU.ParticleModules.cpp index bebe80479..7aa68e32e 100644 --- a/Source/Engine/Particles/Graph/CPU/ParticleEmitterGraph.CPU.ParticleModules.cpp +++ b/Source/Engine/Particles/Graph/CPU/ParticleEmitterGraph.CPU.ParticleModules.cpp @@ -69,7 +69,7 @@ namespace scale *= 1.72531f; } - return noise / weight; + return noise / Math::Max(weight, ZeroTolerance); } VariantType::Types GetVariantType(ParticleAttribute::ValueTypes type) @@ -486,7 +486,7 @@ void ParticleEmitterGraphCPUExecutor::ProcessModule(ParticleEmitterGraphCPUNode* float particleDrag = drag; \ if (useSpriteSize) \ particleDrag *= ((Vector2*)spriteSizePtr)->MulValues(); \ - *((Vector3*)velocityPtr) *= Math::Max(0.0f, 1.0f - (particleDrag * _deltaTime) / *(float*)massPtr); \ + *((Vector3*)velocityPtr) *= Math::Max(0.0f, 1.0f - (particleDrag * _deltaTime) / Math::Max(*(float*)massPtr, ZeroTolerance)); \ velocityPtr += stride; \ massPtr += stride; \ spriteSizePtr += stride @@ -545,7 +545,7 @@ void ParticleEmitterGraphCPUExecutor::ProcessModule(ParticleEmitterGraphCPUNode* Vector3 vectorFieldUVW = Vector3::Transform(*((Vector3*)positionPtr), invFieldTransformMatrix); \ Vector3 force = Noise3D(vectorFieldUVW + 0.5f, octavesCount, roughness); \ force = Vector3::Transform(force, fieldTransformMatrix) * intensity; \ - *((Vector3*)velocityPtr) += force * (_deltaTime / *(float*)massPtr); \ + *((Vector3*)velocityPtr) += force * (_deltaTime / Math::Max(*(float*)massPtr, ZeroTolerance)); \ positionPtr += stride; \ velocityPtr += stride; \ massPtr += stride @@ -1009,7 +1009,7 @@ void ParticleEmitterGraphCPUExecutor::ProcessModule(ParticleEmitterGraphCPUNode* #define INPUTS_FETCH() \ const Vector3 center = (Vector3)GetValue(centerBox, 2); \ - const float radius = (float)GetValue(radiusBox, 3); \ + const float radius = Math::Max((float)GetValue(radiusBox, 3), ZeroTolerance); \ const float thickness = (float)GetValue(thicknessBox, 4); \ const float arc = (float)GetValue(arcBox, 5) * DegreesToRadians #define LOGIC() \ @@ -1017,20 +1017,20 @@ void ParticleEmitterGraphCPUExecutor::ProcessModule(ParticleEmitterGraphCPUNode* float sinTheta, cosTheta; \ Math::SinCos(u.X * TWO_PI, sinTheta, cosTheta); \ float r = Math::Saturate(thickness / radius); \ - Vector2 s1_1 = r * Vector2(cosTheta, sinTheta) + Vector2(1, 0); \ - Vector2 s1_2 = r * Vector2(-cosTheta, sinTheta) + Vector2(1, 0); \ - float w = s1_1.X / (s1_1.X + s1_2.X); \ + Vector2 s11 = r * Vector2(cosTheta, sinTheta) + Vector2(1, 0); \ + Vector2 s12 = r * Vector2(-cosTheta, sinTheta) + Vector2(1, 0); \ + float w = s11.X / (s11.X + s12.X); \ Vector3 t; \ float phi; \ if (u.Y < w) \ { \ phi = arc * u.Y / w; \ - t = Vector3(s1_1.X, 0, s1_1.Y); \ + t = Vector3(s11.X, 0, s11.Y); \ } \ else \ { \ phi = arc * (u.Y - w) / (1.0f - w); \ - t = Vector3(s1_2.X, 0, s1_2.Y); \ + t = Vector3(s12.X, 0, s12.Y); \ } \ float s, c; \ Math::SinCos(phi, c, s); \ @@ -1262,7 +1262,7 @@ void ParticleEmitterGraphCPUExecutor::ProcessModule(ParticleEmitterGraphCPUNode* if (sign * sqrLength <= sign * totalRadius * totalRadius) \ { \ float dist = Math::Sqrt(sqrLength); \ - Vector3 n = sign * dir / dist; \ + Vector3 n = sign * dir / Math::Max(dist, ZeroTolerance); \ *(Vector3*)positionPtr = position - n * (dist - totalRadius) * sign; \ COLLISION_LOGIC() @@ -1374,7 +1374,7 @@ void ParticleEmitterGraphCPUExecutor::ProcessModule(ParticleEmitterGraphCPUNode* collision = Math::Abs(dir.Y) > halfHeight || sqrLength > cylinderRadiusT * cylinderRadiusT; \ if (collision) \ { \ - float dist = Math::Sqrt(sqrLength); \ + float dist = Math::Max(Math::Sqrt(sqrLength), ZeroTolerance); \ float distToCap = sign * (halfHeight - Math::Abs(dir.Y)); \ float distToSide = sign * (cylinderRadiusT - dist); \ Vector3 n = Vector3(dir.X / dist, Math::Sign(dir.Y), dir.Z / dist) * sign; \ diff --git a/Source/Engine/Particles/Graph/CPU/ParticleEmitterGraph.CPU.Particles.cpp b/Source/Engine/Particles/Graph/CPU/ParticleEmitterGraph.CPU.Particles.cpp index 08db1c0d3..d56bf6d5c 100644 --- a/Source/Engine/Particles/Graph/CPU/ParticleEmitterGraph.CPU.Particles.cpp +++ b/Source/Engine/Particles/Graph/CPU/ParticleEmitterGraph.CPU.Particles.cpp @@ -284,7 +284,7 @@ void ParticleEmitterGraphCPUExecutor::ProcessGroupParticles(Box* box, Node* node { const float age = GET_PARTICLE_ATTRIBUTE(0, float); const float lifetime = GET_PARTICLE_ATTRIBUTE(1, float); - value = age / lifetime; + value = age / Math::Max(lifetime, ZeroTolerance); break; } // Effect Position diff --git a/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.ParticleModules.cpp b/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.ParticleModules.cpp index 23dac1622..57d4ededc 100644 --- a/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.ParticleModules.cpp +++ b/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.ParticleModules.cpp @@ -177,7 +177,7 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node) " {{\n" " // Linear Drag\n" " float drag = {2} * {3}.x * {3}.y;\n" - " {0} *= max(0.0f, 1.0f - (drag * DeltaTime) / {1});\n" + " {0} *= max(0.0f, 1.0f - (drag * DeltaTime) / max({1}, PARTICLE_THRESHOLD));\n" " }}\n" ), velocity.Value, mass.Value, drag.Value, spriteSize.Value); } @@ -188,7 +188,7 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node) " {{\n" " // Linear Drag\n" " float drag = {2};\n" - " {0} *= max(0.0f, 1.0f - (drag * DeltaTime) / {1});\n" + " {0} *= max(0.0f, 1.0f - (drag * DeltaTime) / max({1}, PARTICLE_THRESHOLD));\n" " }}\n" ), velocity.Value, mass.Value, drag.Value); } @@ -219,7 +219,7 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node) " float3 vectorFieldUVW = mul(invFieldTransformMatrix, float4({0}, 1.0f)).xyz;\n" " float3 force = Noise3D(vectorFieldUVW + 0.5f, {8}, {6});\n" " force = mul(fieldTransformMatrix, float4(force, 0.0f)).xyz * {7};\n" - " {1} += force * (DeltaTime / {2});\n" + " {1} += force * (DeltaTime / max({2}, PARTICLE_THRESHOLD));\n" " }}\n" ), position.Value, velocity.Value, mass.Value, fieldPosition.Value, fieldRotation.Value, fieldScale.Value, roughness.Value, intensity.Value, octavesCount.Value); break; @@ -486,21 +486,21 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node) " float3 u = RAND3;\n" " float sinTheta, cosTheta;\n" " sincos(u.x * PI * 2.0f, sinTheta, cosTheta);\n" - " float r = saturate((float){4} / {3});\n" - " float2 s1_1 = r * float2( cosTheta, sinTheta) + float2(1, 0);\n" - " float2 s1_2 = r * float2(-cosTheta, sinTheta) + float2(1, 0);\n" - " float w = s1_1.x / (s1_1.x + s1_2.x);\n" + " float r = saturate((float){4} / max({3}, PARTICLE_THRESHOLD));\n" + " float2 s11 = r * float2( cosTheta, sinTheta) + float2(1, 0);\n" + " float2 s12 = r * float2(-cosTheta, sinTheta) + float2(1, 0);\n" + " float w = s11.x / (s11.x + s12.x);\n" " float3 t;\n" " float phi;\n" " if (u.y < w)\n" " {{\n" " phi = radians({5}) * u.y / w;\n" - " t = float3(s1_1.x, 0, s1_1.y);\n" + " t = float3(s11.x, 0, s11.y);\n" " }}\n" " else\n" " {{\n" " phi = radians({5}) * (u.y - w) / (1.0f - w);\n" - " t = float3(s1_2.x, 0, s1_2.y);\n" + " t = float3(s12.x, 0, s12.y);\n" " }}\n" " float s, c;\n" " sincos(phi, c, s);\n" @@ -693,7 +693,7 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node) " if ({4} * sqrLength <= {4} * totalRadius * totalRadius)\n" " {{\n" " float dist = sqrt(sqrLength);\n" - " float3 n = {4} * dir / dist;\n" + " float3 n = {4} * dir / max(dist, PARTICLE_THRESHOLD);\n" " {0} -= n * (dist - totalRadius) * {4};\n" COLLISION_LOGIC() " }}\n" @@ -787,7 +787,7 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node) " collision = abs(dir.y) > halfHeight || sqrLength > cylinderRadiusT * cylinderRadiusT;\n" " if (collision)\n" " {{\n" - " float dist = sqrt(sqrLength);\n" + " float dist = max(sqrt(sqrLength), PARTICLE_THRESHOLD);\n" " float distToCap = {4} * (halfHeight - abs(dir.y));\n" " float distToSide = {4} * (cylinderRadiusT - dist);\n" " float3 n = float3(dir.x / dist, sign(dir.y), dir.z / dist) * {4};\n" From 5cb0da3340ecd119a8a612bec306a35ddb1b039c Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sat, 6 Feb 2021 15:58:33 +0100 Subject: [PATCH 34/68] Move GPU particles generator code to be more compact --- .../ParticleEmitterGraph.GPU.Parameters.cpp | 98 -------------- .../ParticleEmitterGraph.GPU.Particles.cpp | 125 ++++++++++++++++++ .../GPU/ParticleEmitterGraph.GPU.Textures.cpp | 2 - .../GPU/ParticleEmitterGraph.GPU.Tools.cpp | 43 ------ 4 files changed, 125 insertions(+), 143 deletions(-) delete mode 100644 Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.Parameters.cpp delete mode 100644 Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.Tools.cpp diff --git a/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.Parameters.cpp b/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.Parameters.cpp deleted file mode 100644 index bcb672eb3..000000000 --- a/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.Parameters.cpp +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. - -#if COMPILE_WITH_PARTICLE_GPU_GRAPH - -#include "ParticleEmitterGraph.GPU.h" - -void ParticleEmitterGPUGenerator::ProcessGroupParameters(Box* box, Node* node, Value& value) -{ - switch (node->TypeID) - { - // Get - case 1: - case 2: - { - // Get parameter - const auto param = findParam((Guid)node->Values[0]); - if (param) - { - switch (param->Type) - { - case MaterialParameterType::Bool: - value = Value(VariantType::Bool, param->ShaderName); - break; - case MaterialParameterType::Integer: - case MaterialParameterType::SceneTexture: - value = Value(VariantType::Int, param->ShaderName); - break; - case MaterialParameterType::Float: - value = Value(VariantType::Float, param->ShaderName); - break; - case MaterialParameterType::Vector2: - case MaterialParameterType::Vector3: - case MaterialParameterType::Vector4: - case MaterialParameterType::Color: - { - // Set result values based on box ID - const Value sample(box->Type.Type, param->ShaderName); - switch (box->ID) - { - case 0: - value = sample; - break; - case 1: - value.Value = sample.Value + _subs[0]; - break; - case 2: - value.Value = sample.Value + _subs[1]; - break; - case 3: - value.Value = sample.Value + _subs[2]; - break; - case 4: - value.Value = sample.Value + _subs[3]; - break; - default: CRASH; - break; - } - value.Type = box->Type.Type; - break; - } - - case MaterialParameterType::Matrix: - { - value = Value(box->Type.Type, String::Format(TEXT("{0}[{1}]"), param->ShaderName, box->ID)); - break; - } - case MaterialParameterType::ChannelMask: - { - const auto input = tryGetValue(node->GetBox(0), Value::Zero); - value = writeLocal(VariantType::Float, String::Format(TEXT("dot({0}, {1})"), input.Value, param->ShaderName), node); - break; - } - case MaterialParameterType::CubeTexture: - case MaterialParameterType::Texture: - case MaterialParameterType::GPUTextureArray: - case MaterialParameterType::GPUTextureCube: - case MaterialParameterType::GPUTextureVolume: - case MaterialParameterType::GPUTexture: - value = Value(VariantType::Object, param->ShaderName); - break; - default: - CRASH; - break; - } - } - else - { - OnError(node, box, String::Format(TEXT("Missing graph parameter {0}."), node->Values[0])); - value = Value::Zero; - } - break; - } - default: - break; - } -} - -#endif diff --git a/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.Particles.cpp b/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.Particles.cpp index 4839d0415..08e7b24ca 100644 --- a/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.Particles.cpp +++ b/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.Particles.cpp @@ -113,6 +113,131 @@ ParticleEmitterGPUGenerator::Value ParticleEmitterGPUGenerator::AccessParticleAt return value.Variable; } +void ParticleEmitterGPUGenerator::ProcessGroupParameters(Box* box, Node* node, Value& value) +{ + switch (node->TypeID) + { + // Get + case 1: + case 2: + { + // Get parameter + const auto param = findParam((Guid)node->Values[0]); + if (param) + { + switch (param->Type) + { + case MaterialParameterType::Bool: + value = Value(VariantType::Bool, param->ShaderName); + break; + case MaterialParameterType::Integer: + case MaterialParameterType::SceneTexture: + value = Value(VariantType::Int, param->ShaderName); + break; + case MaterialParameterType::Float: + value = Value(VariantType::Float, param->ShaderName); + break; + case MaterialParameterType::Vector2: + case MaterialParameterType::Vector3: + case MaterialParameterType::Vector4: + case MaterialParameterType::Color: + { + // Set result values based on box ID + const Value sample(box->Type.Type, param->ShaderName); + switch (box->ID) + { + case 0: + value = sample; + break; + case 1: + value.Value = sample.Value + _subs[0]; + break; + case 2: + value.Value = sample.Value + _subs[1]; + break; + case 3: + value.Value = sample.Value + _subs[2]; + break; + case 4: + value.Value = sample.Value + _subs[3]; + break; + default: CRASH; + break; + } + value.Type = box->Type.Type; + break; + } + + case MaterialParameterType::Matrix: + { + value = Value(box->Type.Type, String::Format(TEXT("{0}[{1}]"), param->ShaderName, box->ID)); + break; + } + case MaterialParameterType::ChannelMask: + { + const auto input = tryGetValue(node->GetBox(0), Value::Zero); + value = writeLocal(VariantType::Float, String::Format(TEXT("dot({0}, {1})"), input.Value, param->ShaderName), node); + break; + } + case MaterialParameterType::CubeTexture: + case MaterialParameterType::Texture: + case MaterialParameterType::GPUTextureArray: + case MaterialParameterType::GPUTextureCube: + case MaterialParameterType::GPUTextureVolume: + case MaterialParameterType::GPUTexture: + value = Value(VariantType::Object, param->ShaderName); + break; + default: + CRASH; + break; + } + } + else + { + OnError(node, box, String::Format(TEXT("Missing graph parameter {0}."), node->Values[0])); + value = Value::Zero; + } + break; + } + default: + break; + } +} + +void ParticleEmitterGPUGenerator::ProcessGroupTools(Box* box, Node* node, Value& value) +{ + switch (node->TypeID) + { + // Linearize Depth + case 7: + { + // Get input + const Value depth = tryGetValue(node->GetBox(0), Value::Zero).AsFloat(); + + // Linearize raw device depth + linearizeSceneDepth(node, depth, value); + break; + } + // Time + case 8: + value = box->ID == 0 ? Value(VariantType::Float, TEXT("Time")) : Value(VariantType::Float, TEXT("DeltaTime")); + break; + // Transform Position To Screen UV + case 9: + { + const Value position = tryGetValue(node->GetBox(0), Value::Zero).AsVector3(); + const Value projPos = writeLocal(VariantType::Vector4, String::Format(TEXT("mul(float4({0}, 1.0f), ViewProjectionMatrix)"), position.Value), node); + _writer.Write(TEXT("\t{0}.xy /= {0}.w;\n"), projPos.Value); + _writer.Write(TEXT("\t{0}.xy = {0}.xy * 0.5f + 0.5f;\n"), projPos.Value); + value = Value(VariantType::Vector2, projPos.Value + TEXT(".xy")); + break; + } + default: + ShaderGenerator::ProcessGroupTools(box, node, value); + break; + } +} + void ParticleEmitterGPUGenerator::ProcessGroupParticles(Box* box, Node* node, Value& value) { switch (node->TypeID) diff --git a/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.Textures.cpp b/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.Textures.cpp index 61273b3a1..e1d864b4e 100644 --- a/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.Textures.cpp +++ b/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.Textures.cpp @@ -256,10 +256,8 @@ void ParticleEmitterGPUGenerator::ProcessGroupTextures(Box* box, Node* node, Val } // Scene Depth case 8: - { sampleSceneDepth(node, value, box); break; - } // Texture case 11: { diff --git a/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.Tools.cpp b/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.Tools.cpp deleted file mode 100644 index 299e1a422..000000000 --- a/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.Tools.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. - -#if COMPILE_WITH_PARTICLE_GPU_GRAPH - -#include "ParticleEmitterGraph.GPU.h" - -void ParticleEmitterGPUGenerator::ProcessGroupTools(Box* box, Node* node, Value& value) -{ - switch (node->TypeID) - { - // Linearize Depth - case 7: - { - // Get input - const Value depth = tryGetValue(node->GetBox(0), Value::Zero).AsFloat(); - - // Linearize raw device depth - linearizeSceneDepth(node, depth, value); - break; - } - // Time - case 8: - { - value = box->ID == 0 ? Value(VariantType::Float, TEXT("Time")) : Value(VariantType::Float, TEXT("DeltaTime")); - break; - } - // Transform Position To Screen UV - case 9: - { - const Value position = tryGetValue(node->GetBox(0), Value::Zero).AsVector3(); - const Value projPos = writeLocal(VariantType::Vector4, String::Format(TEXT("mul(float4({0}, 1.0f), ViewProjectionMatrix)"), position.Value), node); - _writer.Write(TEXT("\t{0}.xy /= {0}.w;\n"), projPos.Value); - _writer.Write(TEXT("\t{0}.xy = {0}.xy * 0.5f + 0.5f;\n"), projPos.Value); - value = Value(VariantType::Vector2, projPos.Value + TEXT(".xy")); - break; - } - default: - ShaderGenerator::ProcessGroupTools(box, node, value); - break; - } -} - -#endif From 633357cc9bc493233abdf13a64aef0b5a6b3697a Mon Sep 17 00:00:00 2001 From: intolerantape Date: Sat, 6 Feb 2021 09:52:30 -0800 Subject: [PATCH 35/68] Added FLAXENGINE_API macro to class JsonAsset. --- Source/Engine/Content/JsonAsset.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Engine/Content/JsonAsset.h b/Source/Engine/Content/JsonAsset.h index ce617938d..c74c4a045 100644 --- a/Source/Engine/Content/JsonAsset.h +++ b/Source/Engine/Content/JsonAsset.h @@ -75,7 +75,7 @@ protected: /// Generic type of Json-format asset. It provides the managed representation of this resource data so it can be accessed via C# API. /// /// -API_CLASS(NoSpawn) class JsonAsset : public JsonAssetBase +API_CLASS(NoSpawn) class FLAXENGINE_API JsonAsset : public JsonAssetBase { DECLARE_ASSET_HEADER(JsonAsset); From 522e1eb76974e3d04d516a68db7ecad6b588dc8a Mon Sep 17 00:00:00 2001 From: "W2.Wizard" Date: Sat, 6 Feb 2021 20:10:22 +0100 Subject: [PATCH 36/68] Inverted condition --- Source/Engine/Debug/DebugDraw.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Engine/Debug/DebugDraw.cpp b/Source/Engine/Debug/DebugDraw.cpp index c197a0d0d..f954cd7cb 100644 --- a/Source/Engine/Debug/DebugDraw.cpp +++ b/Source/Engine/Debug/DebugDraw.cpp @@ -630,7 +630,7 @@ void DebugDraw::DrawLine(const Vector3& start, const Vector3& end, const Color& void DebugDraw::DrawLines(const Span& lines, const Matrix& transform, const Color& color, float duration, bool depthTest) { - if (lines.Length() % 2 == 0) + if (lines.Length() % 2 != 0) { DebugLog::ThrowException("Cannot draw debug lines with uneven amount of items in array"); return; From 6e5a13111a0b5c81fba2743e84b0e5f6db07b9b5 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sun, 7 Feb 2021 12:49:14 +0100 Subject: [PATCH 37/68] Fix auto-importing materials and textures from model file with invalid path characters used in name Fixes #208 --- Source/Editor/Utilities/EditorUtilities.cpp | 53 +++++++++++++++++++ Source/Editor/Utilities/EditorUtilities.h | 7 +++ .../AssetsImportingManager.cpp | 2 +- Source/Engine/Tools/ModelTool/ModelTool.cpp | 13 ++++- 4 files changed, 73 insertions(+), 2 deletions(-) diff --git a/Source/Editor/Utilities/EditorUtilities.cpp b/Source/Editor/Utilities/EditorUtilities.cpp index fc266ec13..538b78173 100644 --- a/Source/Editor/Utilities/EditorUtilities.cpp +++ b/Source/Editor/Utilities/EditorUtilities.cpp @@ -741,6 +741,59 @@ bool EditorUtilities::GenerateCertificate(const String& name, const String& outp return false; } +bool EditorUtilities::IsInvalidPathChar(Char c) +{ + char illegalChars[] = + { + '?', + '\\', + '/', + '\"', + '<', + '>', + '|', + ':', + '*', + '\u0001', + '\u0002', + '\u0003', + '\u0004', + '\u0005', + '\u0006', + '\a', + '\b', + '\t', + '\n', + '\v', + '\f', + '\r', + '\u000E', + '\u000F', + '\u0010', + '\u0011', + '\u0012', + '\u0013', + '\u0014', + '\u0015', + '\u0016', + '\u0017', + '\u0018', + '\u0019', + '\u001A', + '\u001B', + '\u001C', + '\u001D', + '\u001E', + '\u001F' + }; + for (auto i : illegalChars) + { + if (c == i) + return true; + } + return false; +} + bool EditorUtilities::ReplaceInFiles(const String& folderPath, const Char* searchPattern, DirectorySearchOption searchOption, const String& findWhat, const String& replaceWith) { Array files; diff --git a/Source/Editor/Utilities/EditorUtilities.h b/Source/Editor/Utilities/EditorUtilities.h index 236d10e6f..a5f129c1b 100644 --- a/Source/Editor/Utilities/EditorUtilities.h +++ b/Source/Editor/Utilities/EditorUtilities.h @@ -42,6 +42,13 @@ public: public: + /// + /// Determines whether the specified path character is invalid. + /// + /// The path character. + /// true if the given character cannot be used as a path because it is illegal character; otherwise, false. + static bool IsInvalidPathChar(Char c); + /// /// Replaces the given text with other one in the files. /// diff --git a/Source/Engine/ContentImporters/AssetsImportingManager.cpp b/Source/Engine/ContentImporters/AssetsImportingManager.cpp index 3a39bd64b..f1d048ca5 100644 --- a/Source/Engine/ContentImporters/AssetsImportingManager.cpp +++ b/Source/Engine/ContentImporters/AssetsImportingManager.cpp @@ -178,7 +178,7 @@ void CreateAssetContext::ApplyChanges() // Move file if (FileSystem::MoveFile(TargetAssetPath, OutputPath, true)) { - LOG(Warning, "Cannot move imported file to the destination path."); + LOG(Warning, "Cannot move imported file {0} to the destination path {1}.", OutputPath, TargetAssetPath); _applyChangesResult = CreateAssetResult::CannotSaveFile; return; } diff --git a/Source/Engine/Tools/ModelTool/ModelTool.cpp b/Source/Engine/Tools/ModelTool/ModelTool.cpp index 35cb3860b..05a69141f 100644 --- a/Source/Engine/Tools/ModelTool/ModelTool.cpp +++ b/Source/Engine/Tools/ModelTool/ModelTool.cpp @@ -15,7 +15,8 @@ #include "Engine/Tools/TextureTool/TextureTool.h" #include "Engine/ContentImporters/AssetsImportingManager.h" #include "Engine/ContentImporters/CreateMaterial.h" -#include "ThirdParty/meshoptimizer/meshoptimizer.h" +#include "Editor/Utilities/EditorUtilities.h" +#include void RemoveNamespace(String& name) { @@ -486,6 +487,11 @@ bool ModelTool::ImportModel(const String& path, ModelData& meshData, Options opt if (autoImportOutput.IsEmpty() || (data.Types & ImportDataTypes::Textures) == 0 || texture.FilePath.IsEmpty()) continue; auto filename = StringUtils::GetFileNameWithoutExtension(texture.FilePath); + for (int32 j = filename.Length() - 1; j >= 0; j--) + { + if (EditorUtilities::IsInvalidPathChar(filename[j])) + filename[j] = ' '; + } if (importedFileNames.Contains(filename)) { int32 counter = 1; @@ -526,6 +532,11 @@ bool ModelTool::ImportModel(const String& path, ModelData& meshData, Options opt if (autoImportOutput.IsEmpty() || (data.Types & ImportDataTypes::Materials) == 0 || !material.UsesProperties()) continue; auto filename = material.Name; + for (int32 j = filename.Length() - 1; j >= 0; j--) + { + if (EditorUtilities::IsInvalidPathChar(filename[j])) + filename[j] = ' '; + } if (importedFileNames.Contains(filename)) { int32 counter = 1; From 0242e29873ee5917c9015bbb9cf5830062cfbeee Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sun, 7 Feb 2021 13:06:33 +0100 Subject: [PATCH 38/68] Fix painting foliage on inactive objects Fixes #209 --- Source/Editor/Tools/Foliage/FoliageTools.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Editor/Tools/Foliage/FoliageTools.cpp b/Source/Editor/Tools/Foliage/FoliageTools.cpp index a0cbf8e14..3354be0b3 100644 --- a/Source/Editor/Tools/Foliage/FoliageTools.cpp +++ b/Source/Editor/Tools/Foliage/FoliageTools.cpp @@ -67,7 +67,7 @@ struct GeometryLookup static bool Search(Actor* actor, GeometryLookup& lookup) { // Early out if object is not intersecting with the foliage brush bounds - if (!actor->GetBox().Intersects(lookup.Brush)) + if (!actor->GetIsActive() || !actor->GetBox().Intersects(lookup.Brush)) return true; const auto brush = lookup.Brush; From 08abc798cc2339fa7b9e312a55600513a239615f Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sun, 7 Feb 2021 16:31:30 +0100 Subject: [PATCH 39/68] Fix FindActor and FindScript in Level --- Source/Engine/Level/Level.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Engine/Level/Level.h b/Source/Engine/Level/Level.h index b1ee090f4..0a10b58d2 100644 --- a/Source/Engine/Level/Level.h +++ b/Source/Engine/Level/Level.h @@ -355,7 +355,7 @@ public: /// /// Actor instance if found, null otherwise. template - FORCE_INLINE T* FindActor() const + FORCE_INLINE static T* FindActor() { return (T*)FindActor(T::GetStaticClass()); } @@ -372,7 +372,7 @@ public: /// /// Script instance if found, null otherwise. template - FORCE_INLINE T* FindScript() const + FORCE_INLINE static T* FindScript() { return (T*)FindScript(T::GetStaticClass()); } From ca6afc0c2d4406c5a0146f0e648c8011b67f89de Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sun, 7 Feb 2021 16:49:44 +0100 Subject: [PATCH 40/68] Fix HorizontalPanel and VerticalPanel auto-sizing if child control is using anchors Fixes #203 --- Source/Engine/UI/GUI/Panels/HorizontalPanel.cs | 2 +- Source/Engine/UI/GUI/Panels/VerticalPanel.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Engine/UI/GUI/Panels/HorizontalPanel.cs b/Source/Engine/UI/GUI/Panels/HorizontalPanel.cs index 53e435f91..d7b54a835 100644 --- a/Source/Engine/UI/GUI/Panels/HorizontalPanel.cs +++ b/Source/Engine/UI/GUI/Panels/HorizontalPanel.cs @@ -42,7 +42,7 @@ namespace FlaxEngine.GUI for (int i = 0; i < _children.Count; i++) { Control c = _children[i]; - if (c.Visible) + if (c.Visible && Mathf.IsZero(c.AnchorMax.X)) { var w = c.Width; c.Bounds = new Rectangle(x + _offset.X, _margin.Top + _offset.Y, w, h); diff --git a/Source/Engine/UI/GUI/Panels/VerticalPanel.cs b/Source/Engine/UI/GUI/Panels/VerticalPanel.cs index f811755ef..2c821bd3f 100644 --- a/Source/Engine/UI/GUI/Panels/VerticalPanel.cs +++ b/Source/Engine/UI/GUI/Panels/VerticalPanel.cs @@ -42,7 +42,7 @@ namespace FlaxEngine.GUI for (int i = 0; i < _children.Count; i++) { Control c = _children[i]; - if (c.Visible) + if (c.Visible && Mathf.IsZero(c.AnchorMax.Y)) { var h = c.Height; c.Bounds = new Rectangle(_margin.Left + _offset.X, y + _offset.Y, w, h); From 6ea897b0f5aa4ebc94d65641a26433fdd6763f18 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sun, 7 Feb 2021 19:27:54 +0100 Subject: [PATCH 41/68] Update Mono for Windows --- Source/Platforms/Windows/Binaries/ThirdParty/x64/eglib.pdb | 4 ++-- .../Windows/Binaries/ThirdParty/x64/libgcmonosgen.pdb | 4 ++-- Source/Platforms/Windows/Binaries/ThirdParty/x64/libmini.pdb | 4 ++-- .../Windows/Binaries/ThirdParty/x64/libmono-static.lib | 4 ++-- .../Windows/Binaries/ThirdParty/x64/libmonoruntime.pdb | 4 ++-- .../Windows/Binaries/ThirdParty/x64/libmonoutils.pdb | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/eglib.pdb b/Source/Platforms/Windows/Binaries/ThirdParty/x64/eglib.pdb index a79f59aac..1cb5d5f43 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/eglib.pdb +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/eglib.pdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1ff34e923a27392a70eb465df1ecc03372aadac6f2753832cce3d82cd5ae1b75 -size 159744 +oid sha256:86d71f01f6ba35e763467eb5b2be703831065ae7c9438fde4a32e1cd40d68880 +size 151552 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/libgcmonosgen.pdb b/Source/Platforms/Windows/Binaries/ThirdParty/x64/libgcmonosgen.pdb index 1a80321ba..2c08c3457 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/libgcmonosgen.pdb +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/libgcmonosgen.pdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8bd411ac3aa425db683905a5fa2445d7d770e5d04821757fcdcaa42e0d0ac986 -size 348160 +oid sha256:e7a6731228669866ebfb450bdd14bdb6e54eef8dcc10c36640016630ded6ef73 +size 290816 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/libmini.pdb b/Source/Platforms/Windows/Binaries/ThirdParty/x64/libmini.pdb index 7c24a2502..a06e2ddf2 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/libmini.pdb +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/libmini.pdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:184d1b18bb84c35fa43d878cedb60f53f203207208882ce6518a2d7a35308332 -size 864256 +oid sha256:6e12dfaf49963f4b736d9fbd7bbe16ccbf79045d64df71edc5209ffb25e0d1e0 +size 667648 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/libmono-static.lib b/Source/Platforms/Windows/Binaries/ThirdParty/x64/libmono-static.lib index 366a28594..ab2d5015d 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/libmono-static.lib +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/libmono-static.lib @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f633de4fbae8e4d65aec49eaaa06f37745bfc28328f4193020434dab398235cc -size 28245086 +oid sha256:b90fdbcfab9d89be16789604edbab46ee8ed0159846be60714ef27ac4444baf2 +size 28391654 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/libmonoruntime.pdb b/Source/Platforms/Windows/Binaries/ThirdParty/x64/libmonoruntime.pdb index c60e7dbe4..e2e07cc4a 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/libmonoruntime.pdb +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/libmonoruntime.pdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:188ebd527b432f33f8bfccb4fbada27b029f362918ab5c4b6f82584f9d30b6f3 -size 1249280 +oid sha256:db47e63ec05d2c50d661f89c062931787be1722e0387f0076b910a9092fbe962 +size 995328 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/libmonoutils.pdb b/Source/Platforms/Windows/Binaries/ThirdParty/x64/libmonoutils.pdb index 30be1562b..87d823d36 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/libmonoutils.pdb +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/libmonoutils.pdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:289966b7d9ff6255e38a6e45d2b9a5179c42e0f1add6abb70f7fa5501dfc59bc -size 356352 +oid sha256:3846908f7e00e2ef725c4c770dc69c277491c7e83df6047871fc9cd672d47a6d +size 299008 From 9f3be80f9c10e33ebb96d6575f494d420456ca20 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sun, 7 Feb 2021 19:28:23 +0100 Subject: [PATCH 42/68] Fix VS debugger config for Dictionary and HashSet to show only Occupied buckets --- Source/flax.natvis | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/flax.natvis b/Source/flax.natvis index fb3ef1228..15ccaa7e6 100644 --- a/Source/flax.natvis +++ b/Source/flax.natvis @@ -52,7 +52,7 @@ _elementsCount - + _table[i] i++ @@ -72,7 +72,7 @@ _elementsCount - + _table[i] i++ From 8c1f56b7db86fc7c6aa98cd3b39d1d31cb19f91a Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sun, 7 Feb 2021 19:28:57 +0100 Subject: [PATCH 43/68] Fixes for scripting objects --- Source/Engine/Scripting/Scripting.cpp | 95 +++++++++++++++++---- Source/Engine/Scripting/ScriptingObject.cpp | 11 ++- 2 files changed, 85 insertions(+), 21 deletions(-) diff --git a/Source/Engine/Scripting/Scripting.cpp b/Source/Engine/Scripting/Scripting.cpp index 6f32f8fd1..ee2922754 100644 --- a/Source/Engine/Scripting/Scripting.cpp +++ b/Source/Engine/Scripting/Scripting.cpp @@ -56,7 +56,45 @@ namespace MDomain* _monoRootDomain = nullptr; MDomain* _monoScriptsDomain = nullptr; CriticalSection _objectsLocker; +#define USE_OBJECTS_DISPOSE_CRASHES_DEBUGGING 0 +#if USE_OBJECTS_DISPOSE_CRASHES_DEBUGGING + struct ScriptingObjectData + { + ScriptingObject* Ptr; + StringAnsi TypeName; + + ScriptingObjectData() + { + Ptr = nullptr; + } + + ScriptingObjectData(ScriptingObject* ptr) + { + Ptr = ptr; + if (ptr && ptr->GetTypeHandle() && ptr->GetTypeHandle().TypeIndex < ptr->GetTypeHandle().Module->Types.Count()) + TypeName = ptr->GetType().Fullname; + } + + ScriptingObject* operator->() const + { + return Ptr; + } + + explicit operator ScriptingObject*() + { + return Ptr; + } + + operator ScriptingObject*() const + { + return Ptr; + } + }; + + Dictionary _objectsDictionary(1024 * 16); +#else Dictionary _objectsDictionary(1024 * 16); +#endif bool _isEngineAssemblyLoaded = false; bool _hasGameModulesLoaded = false; MMethod* _method_Update = nullptr; @@ -456,6 +494,9 @@ void Scripting::Release() for (auto i = _objectsDictionary.Begin(); i.IsNotEnd(); ++i) { auto obj = i->Value; +#if USE_OBJECTS_DISPOSE_CRASHES_DEBUGGING + LOG(Info, "[OnScriptingDispose] obj = 0x{0:x}, {1}", (uint32)obj.Ptr, String(obj.TypeName)); +#endif obj->OnScriptingDispose(); } } @@ -498,7 +539,9 @@ void Scripting::Release() } } +#if !USE_SINGLE_DOMAIN MCore::Instance()->UnloadDomain("Scripts Domain"); +#endif } #if USE_EDITOR @@ -683,10 +726,18 @@ ScriptingObject* Scripting::FindObject(Guid id, MClass* type) } // Try to find it +#if USE_OBJECTS_DISPOSE_CRASHES_DEBUGGING + ScriptingObjectData data; + _objectsLocker.Lock(); + _objectsDictionary.TryGet(id, data); + _objectsLocker.Unlock(); + auto result = data.Ptr; +#else ScriptingObject* result = nullptr; _objectsLocker.Lock(); _objectsDictionary.TryGet(id, result); _objectsLocker.Unlock(); +#endif if (result) { // Check type @@ -718,11 +769,20 @@ ScriptingObject* Scripting::TryFindObject(Guid id, MClass* type) } // Try to find it +#if USE_OBJECTS_DISPOSE_CRASHES_DEBUGGING + ScriptingObjectData data; + _objectsLocker.Lock(); + _objectsDictionary.TryGet(id, data); + _objectsLocker.Unlock(); + auto result = data.Ptr; +#else ScriptingObject* result = nullptr; _objectsLocker.Lock(); _objectsDictionary.TryGet(id, result); _objectsLocker.Unlock(); +#endif + // Check type if (result && !result->Is(type)) { result = nullptr; @@ -753,28 +813,23 @@ ScriptingObject* Scripting::FindObject(const MonoObject* managedInstance) void Scripting::OnManagedInstanceDeleted(ScriptingObject* obj) { + PROFILE_CPU_NAMED("OnManagedInstanceDeleted"); ASSERT(obj); - PROFILE_CPU_NAMED("OnManagedInstanceDeleted"); - - // This is sometimes crashing, probably rawPtr field is not cleared in some cases - // TODO: use faster callback without crashing - //obj->OnManagedInstanceDeleted(); - // Validate if object still exists - bool isValid; - { - ScopeLock lock(_objectsLocker); - isValid = _objectsDictionary.ContainsValue(obj); - } - if (isValid) + _objectsLocker.Lock(); + if (_objectsDictionary.ContainsValue(obj)) { +#if USE_OBJECTS_DISPOSE_CRASHES_DEBUGGING + LOG(Info, "[OnManagedInstanceDeleted] obj = 0x{0:x}, {1}", (uint32)obj, String(ScriptingObjectData(obj).TypeName)); +#endif obj->OnManagedInstanceDeleted(); } else { //LOG(Warning, "Object finalization called for already removed object (address={0:x})", (uint64)obj); } + _objectsLocker.Unlock(); } bool Scripting::HasGameModulesLoaded() @@ -805,18 +860,25 @@ void Scripting::RegisterObject(ScriptingObject* obj) //ASSERT(!_objectsDictionary.ContainsValue(obj)); #if ENABLE_ASSERTION - ScriptingObject* other = nullptr; +#if USE_OBJECTS_DISPOSE_CRASHES_DEBUGGING + ScriptingObjectData other; if (_objectsDictionary.TryGet(obj->GetID(), other)) +#else + ScriptingObject* other; + if (_objectsDictionary.TryGet(obj->GetID(), other)) +#endif { // Something went wrong... - LOG(Error, "Objects registry already contains object with ID={0}! Trying to register object {1} (type '{2}').", obj->GetID(), obj->ToString(), String(obj->GetClass()->GetFullName())); - + 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()); } #else ASSERT(!_objectsDictionary.ContainsKey(obj->_id)); #endif +#if USE_OBJECTS_DISPOSE_CRASHES_DEBUGGING + LOG(Info, "[RegisterObject] obj = 0x{0:x}, {1}", (uint32)obj, String(ScriptingObjectData(obj).TypeName)); +#endif _objectsDictionary.Add(obj->GetID(), obj); } @@ -826,6 +888,9 @@ void Scripting::UnregisterObject(ScriptingObject* obj) //ASSERT(!obj->_id.IsValid() || _objectsDictionary.ContainsValue(obj)); +#if USE_OBJECTS_DISPOSE_CRASHES_DEBUGGING + LOG(Info, "[UnregisterObject] obj = 0x{0:x}, {1}", (uint32)obj, String(ScriptingObjectData(obj).TypeName)); +#endif _objectsDictionary.Remove(obj->GetID()); } diff --git a/Source/Engine/Scripting/ScriptingObject.cpp b/Source/Engine/Scripting/ScriptingObject.cpp index 11d6e43e0..9d2320d7f 100644 --- a/Source/Engine/Scripting/ScriptingObject.cpp +++ b/Source/Engine/Scripting/ScriptingObject.cpp @@ -276,6 +276,10 @@ void PersistentScriptingObject::OnManagedInstanceDeleted() _gcHandle = 0; } + // Unregister object + if (IsRegistered()) + UnregisterObject(); + // But do not delete itself } @@ -501,11 +505,6 @@ public: obj->RegisterObject(); } - static void ManagedInstanceDeleted(ScriptingObject* obj) - { - Scripting::OnManagedInstanceDeleted(obj); - } - static void Destroy(ManagedScriptingObject* obj, float timeLeft) { // Use scaled game time for removing actors/scripts by the user (maybe expose it to the api?) @@ -544,7 +543,7 @@ public: ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_Create1", &Create1); ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_Create2", &Create2); ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_ManagedInstanceCreated", &ManagedInstanceCreated); - ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_ManagedInstanceDeleted", &ManagedInstanceDeleted); + ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_ManagedInstanceDeleted", &Scripting::OnManagedInstanceDeleted); ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_Destroy", &Destroy); ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_GetTypeName", &GetTypeName); ADD_INTERNAL_CALL("FlaxEngine.Object::Internal_FindObject", &FindObject); From 5768eefe49c7332f014749d132d50f7c847be770 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sun, 7 Feb 2021 20:06:44 +0100 Subject: [PATCH 44/68] Optimize `Texture::DownloadData` for staging textures --- .../Engine/Graphics/Textures/GPUTexture.cpp | 97 +++++++++++-------- 1 file changed, 56 insertions(+), 41 deletions(-) diff --git a/Source/Engine/Graphics/Textures/GPUTexture.cpp b/Source/Engine/Graphics/Textures/GPUTexture.cpp index e51d2e510..29268e721 100644 --- a/Source/Engine/Graphics/Textures/GPUTexture.cpp +++ b/Source/Engine/Graphics/Textures/GPUTexture.cpp @@ -458,43 +458,13 @@ protected: // [ThreadPoolTask] bool Run() override { - // Check resources auto texture = _texture.Get(); if (texture == nullptr || _staging == nullptr || _data == nullptr) { LOG(Warning, "Cannot download texture data. Missing objects."); return true; } - - const auto arraySize = texture->ArraySize(); - const auto mipLevels = texture->MipLevels(); - - // Get all mip maps for each array slice - auto& rawResultData = _data->Items; - rawResultData.Resize(arraySize, false); - for (int32 arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) - { - auto& arraySlice = rawResultData[arrayIndex]; - arraySlice.Mips.Resize(mipLevels); - - for (int32 mipMapIndex = 0; mipMapIndex < mipLevels; mipMapIndex++) - { - auto& mip = arraySlice.Mips[mipMapIndex]; - const int32 mipWidth = _data->Width >> mipMapIndex; - const int32 mipHeight = _data->Height >> mipMapIndex; - uint32 mipRowPitch, mipSlicePitch; - RenderTools::ComputePitch(_data->Format, mipWidth, mipHeight, mipRowPitch, mipSlicePitch); - - // Gather data - if (_staging->GetData(arrayIndex, mipMapIndex, mip, mipRowPitch)) - { - LOG(Warning, "Staging resource of \'{0}\' get data failed.", texture->ToString()); - return true; - } - } - } - - return false; + return _staging->DownloadData(*_data); } void OnEnd() override @@ -508,6 +478,57 @@ protected: bool GPUTexture::DownloadData(TextureData& result) { + // Skip for empty ones + if (MipLevels() == 0) + { + LOG(Warning, "Cannot download GPU texture data from an empty texture."); + return true; + } + if (Depth() != 1) + { + MISSING_CODE("support volume texture data downloading."); + } + + // Use faster path for staging resources + if (IsStaging()) + { + const auto arraySize = ArraySize(); + const auto mipLevels = MipLevels(); + + // Set texture info + result.Width = Width(); + result.Height = Height(); + result.Depth = Depth(); + result.Format = Format(); + + // Get all mip maps for each array slice + auto& rawResultData = result.Items; + rawResultData.Resize(arraySize, false); + for (int32 arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) + { + auto& arraySlice = rawResultData[arrayIndex]; + arraySlice.Mips.Resize(mipLevels); + + for (int32 mipMapIndex = 0; mipMapIndex < mipLevels; mipMapIndex++) + { + auto& mip = arraySlice.Mips[mipMapIndex]; + const int32 mipWidth = result.Width >> mipMapIndex; + const int32 mipHeight = result.Height >> mipMapIndex; + uint32 mipRowPitch, mipSlicePitch; + RenderTools::ComputePitch(result.Format, mipWidth, mipHeight, mipRowPitch, mipSlicePitch); + + // Gather data + if (GetData(arrayIndex, mipMapIndex, mip, mipRowPitch)) + { + LOG(Warning, "Staging resource of \'{0}\' get data failed.", ToString()); + return true; + } + } + } + + return false; + } + const auto name = ToString(); // Ensure not running on main thread - we support DownloadData from textures only on a worker threads (Thread Pool Workers or Content Loaders) @@ -538,7 +559,8 @@ bool GPUTexture::DownloadData(TextureData& result) Task* GPUTexture::DownloadDataAsync(TextureData& result) { - if (!IsAllocated()) + // Skip for empty ones + if (MipLevels() == 0) { LOG(Warning, "Cannot download texture data. It has not ben created yet."); return nullptr; @@ -548,19 +570,12 @@ Task* GPUTexture::DownloadDataAsync(TextureData& result) MISSING_CODE("support volume texture data downloading."); } - // Set texture info - result.Width = Width(); - result.Height = Height(); - result.Depth = Depth(); - result.Format = Format(); - - // Quicker path if texture is already readback - if (_desc.Usage == GPUResourceUsage::StagingReadback) + // Use faster path for staging resources + if (IsStaging()) { // Create task to copy downloaded data to TextureData container auto getDataTask = ::New(this, this, result); ASSERT(getDataTask->HasReference(this)); - return getDataTask; } From 04bb83fe31aa2155c5b26538bac359bca98f7498 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sun, 7 Feb 2021 20:19:10 +0100 Subject: [PATCH 45/68] Fixes --- Source/Editor/Content/Proxy/PrefabProxy.cs | 4 ++-- Source/Engine/UI/UICanvas.cpp | 18 +++++++++++------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/Source/Editor/Content/Proxy/PrefabProxy.cs b/Source/Editor/Content/Proxy/PrefabProxy.cs index 39d77f25c..276bc0d30 100644 --- a/Source/Editor/Content/Proxy/PrefabProxy.cs +++ b/Source/Editor/Content/Proxy/PrefabProxy.cs @@ -162,8 +162,7 @@ namespace FlaxEditor.Content // Auto fit actor to camera float targetSize = 30.0f; - BoundingBox bounds; - Editor.GetActorEditorBox(_preview.Instance, out bounds); + Editor.GetActorEditorBox(_preview.Instance, out var bounds); float maxSize = Mathf.Max(0.001f, bounds.Size.MaxValue); _preview.Instance.Scale = new Vector3(targetSize / maxSize); _preview.Instance.Position = Vector3.Zero; @@ -175,6 +174,7 @@ namespace FlaxEditor.Content /// public override void OnThumbnailDrawEnd(ThumbnailRequest request, ContainerControl guiRoot) { + _preview.RemoveChildren(); _preview.Prefab = null; _preview.Parent = null; } diff --git a/Source/Engine/UI/UICanvas.cpp b/Source/Engine/UI/UICanvas.cpp index 67dbaaa5e..49d6ac420 100644 --- a/Source/Engine/UI/UICanvas.cpp +++ b/Source/Engine/UI/UICanvas.cpp @@ -17,13 +17,17 @@ MMethod* UICanvas_OnDisable = nullptr; MMethod* UICanvas_EndPlay = nullptr; #define UICANVAS_INVOKE(event) \ - MonoObject* exception = nullptr; \ - UICanvas_##event->Invoke(GetManagedInstance(), nullptr, &exception); \ - if (exception) \ - { \ - MException ex(exception); \ - ex.Log(LogType::Error, TEXT("UICanvas::" #event)); \ - } + auto instance = GetManagedInstance(); \ + if (instance) \ + { \ + MonoObject* exception = nullptr; \ + UICanvas_##event->Invoke(instance, nullptr, &exception); \ + if (exception) \ + { \ + MException ex(exception); \ + ex.Log(LogType::Error, TEXT("UICanvas::" #event)); \ + } \ + } UICanvas::UICanvas(const SpawnParams& params) : Actor(params) From 96f1d9e82061f05028a161592d7231acf0671e59 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sun, 7 Feb 2021 20:19:21 +0100 Subject: [PATCH 46/68] Add UIControl outlines drawing in Prefab window --- Source/Editor/Viewport/PrefabWindowViewport.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Source/Editor/Viewport/PrefabWindowViewport.cs b/Source/Editor/Viewport/PrefabWindowViewport.cs index 94b994ac8..dd6f8fce3 100644 --- a/Source/Editor/Viewport/PrefabWindowViewport.cs +++ b/Source/Editor/Viewport/PrefabWindowViewport.cs @@ -485,6 +485,23 @@ namespace FlaxEditor.Viewport } } + /// + public override void Draw() + { + base.Draw(); + + // Selected UI controls outline + for (var i = 0; i < _window.Selection.Count; i++) + { + if (_window.Selection[i].EditableObject is UIControl controlActor && controlActor.Control != null) + { + var control = controlActor.Control; + var bounds = Rectangle.FromPoints(control.PointToParent(this, Vector2.Zero), control.PointToParent(this, control.Size)); + Render2D.DrawRectangle(bounds, Editor.Instance.Options.Options.Visual.SelectionOutlineColor0, Editor.Instance.Options.Options.Visual.UISelectionOutlineSize); + } + } + } + /// protected override void OnLeftMouseButtonUp() { From 2325de3ddcd18e956ad4ceb0d02d4ccd64c5ac8a Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sun, 7 Feb 2021 21:11:04 +0100 Subject: [PATCH 47/68] Fix missing terrain bounds update after modifying terrain Fixes #5 --- Source/Engine/Terrain/Terrain.cpp | 2 ++ Source/Engine/Terrain/TerrainChunk.cpp | 2 +- Source/Engine/Terrain/TerrainPatch.cpp | 7 +++---- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Source/Engine/Terrain/Terrain.cpp b/Source/Engine/Terrain/Terrain.cpp index 38d1865bb..3b00818c2 100644 --- a/Source/Engine/Terrain/Terrain.cpp +++ b/Source/Engine/Terrain/Terrain.cpp @@ -36,6 +36,7 @@ Terrain::~Terrain() void Terrain::UpdateBounds() { + PROFILE_CPU(); _box = BoundingBox(_transform.Translation, _transform.Translation); for (int32 i = 0; i < _patches.Count(); i++) { @@ -48,6 +49,7 @@ void Terrain::UpdateBounds() void Terrain::CacheNeighbors() { + PROFILE_CPU(); for (int32 pathIndex = 0; pathIndex < _patches.Count(); pathIndex++) { const auto patch = _patches[pathIndex]; diff --git a/Source/Engine/Terrain/TerrainChunk.cpp b/Source/Engine/Terrain/TerrainChunk.cpp index 1241935e5..fbb80c27d 100644 --- a/Source/Engine/Terrain/TerrainChunk.cpp +++ b/Source/Engine/Terrain/TerrainChunk.cpp @@ -192,7 +192,7 @@ bool TerrainChunk::Intersects(const Ray& ray, float& distance) void TerrainChunk::UpdateBounds() { const Vector3 boundsExtent = _patch->_terrain->_boundsExtent; - const float size = _patch->_terrain->_chunkSize * TERRAIN_UNITS_PER_VERTEX; + const float size = (float)_patch->_terrain->_chunkSize * TERRAIN_UNITS_PER_VERTEX; Transform terrainTransform = _patch->_terrain->_transform; Transform localTransform; diff --git a/Source/Engine/Terrain/TerrainPatch.cpp b/Source/Engine/Terrain/TerrainPatch.cpp index 791e93c7f..552238e9e 100644 --- a/Source/Engine/Terrain/TerrainPatch.cpp +++ b/Source/Engine/Terrain/TerrainPatch.cpp @@ -951,7 +951,7 @@ bool TerrainPatch::SetupHeightMap(int32 heightMapLength, const float* heightMap, chunk._yHeight = chunkHeights[chunkIndex]; chunk.UpdateTransform(); } - UpdateBounds(); + _terrain->UpdateBounds(); UpdateCollision(); #if TERRAIN_UPDATING @@ -1431,7 +1431,7 @@ bool TerrainPatch::ModifyHeightMap(const float* samples, const Int2& modifiedOff chunk._yHeight = chunkHeights[chunkIndex]; chunk.UpdateTransform(); } - UpdateBounds(); + _terrain->UpdateBounds(); return UpdateHeightData(info, modifiedOffset, modifiedSize, wasHeightRangeChanged); } @@ -2108,9 +2108,8 @@ void TerrainPatch::UpdatePostManualDeserialization() { auto& chunk = Chunks[chunkIndex]; chunk.UpdateTransform(); - chunk.UpdateBounds(); } - UpdateBounds(); + _terrain->UpdateBounds(); ScopeLock lock(_collisionLocker); From 103d630d80009bcf59167bcb9163d532032572c7 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sun, 7 Feb 2021 21:41:17 +0100 Subject: [PATCH 48/68] Fix tooltips generation for native properties to reflect getter and setter docsa --- Source/Engine/Level/Actor.h | 8 ++++---- .../Bindings/BindingsGenerator.CSharp.cs | 20 +++---------------- .../Bindings/BindingsGenerator.Parsing.cs | 7 +++++++ 3 files changed, 14 insertions(+), 21 deletions(-) diff --git a/Source/Engine/Level/Actor.h b/Source/Engine/Level/Actor.h index 334021c28..7621e4a2a 100644 --- a/Source/Engine/Level/Actor.h +++ b/Source/Engine/Level/Actor.h @@ -437,13 +437,13 @@ public: } /// - /// Sets actor orientation in 3D space + /// Sets actor orientation in 3D space. /// /// The value to set. API_PROPERTY() void SetOrientation(const Quaternion& value); /// - /// Gets actor scale in 3D space + /// Gets actor scale in 3D space. /// API_PROPERTY(Attributes="HideInEditor, NoSerialize") FORCE_INLINE Vector3 GetScale() const @@ -458,13 +458,13 @@ public: API_PROPERTY() void SetScale(const Vector3& value); /// - /// Gets actor rotation matrix + /// Gets actor rotation matrix. /// API_PROPERTY(Attributes="HideInEditor, NoSerialize") Matrix GetRotation() const; /// - /// Sets actor rotation matrix + /// Sets actor rotation matrix. /// /// The value to set. API_PROPERTY() void SetRotation(const Matrix& value); diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs index d51d7b754..15d8825a8 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs @@ -488,10 +488,7 @@ namespace Flax.Build.Bindings { if (comment.Contains("/// ")) continue; - var c = comment.Replace("::", "."); - contents.Append(indent); - contents.Append(c); - contents.AppendLine(); + contents.Append(indent).Append(comment.Replace("::", ".")).AppendLine(); } GenerateCSharpAttributes(buildData, contents, indent, eventInfo, true); @@ -586,11 +583,7 @@ namespace Flax.Build.Bindings { if (comment.Contains("/// ")) continue; - - var c = comment.Replace("::", "."); - contents.Append(indent); - contents.Append(c); - contents.AppendLine(); + contents.Append(indent).Append(comment.Replace("::", ".")).AppendLine(); } GenerateCSharpAttributes(buildData, contents, indent, fieldInfo, true); @@ -636,14 +629,7 @@ namespace Flax.Build.Bindings { if (comment.Contains("/// ") || comment.Contains(" Date: Sun, 7 Feb 2021 21:41:46 +0100 Subject: [PATCH 49/68] Fix Editor timeline editor controls API visible in Visual Scripting --- Source/Editor/GUI/Timeline/Track.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/Editor/GUI/Timeline/Track.cs b/Source/Editor/GUI/Timeline/Track.cs index 4f5278251..6ba8191d6 100644 --- a/Source/Editor/GUI/Timeline/Track.cs +++ b/Source/Editor/GUI/Timeline/Track.cs @@ -16,6 +16,7 @@ namespace FlaxEditor.GUI.Timeline /// The Timeline track that contains a header and custom timeline events/media. /// /// + [HideInEditor] public class Track : ContainerControl { /// From c9860f21ec3bb4a25dfa35483533da496a3f8fb8 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 8 Feb 2021 19:42:04 +0100 Subject: [PATCH 50/68] Fix scripting object issue --- Source/Engine/Scripting/Scripting.cpp | 26 +++++++++++++++++---- Source/Engine/Scripting/ScriptingObject.cpp | 4 ---- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/Source/Engine/Scripting/Scripting.cpp b/Source/Engine/Scripting/Scripting.cpp index ee2922754..c8c8184bd 100644 --- a/Source/Engine/Scripting/Scripting.cpp +++ b/Source/Engine/Scripting/Scripting.cpp @@ -495,7 +495,7 @@ void Scripting::Release() { auto obj = i->Value; #if USE_OBJECTS_DISPOSE_CRASHES_DEBUGGING - LOG(Info, "[OnScriptingDispose] obj = 0x{0:x}, {1}", (uint32)obj.Ptr, String(obj.TypeName)); + LOG(Info, "[OnScriptingDispose] obj = 0x{0:x}, {1}", (uint64)obj.Ptr, String(obj.TypeName)); #endif obj->OnScriptingDispose(); } @@ -589,6 +589,24 @@ void Scripting::Reload(bool canTriggerSceneReload) MCore::GC::Collect(); MCore::GC::WaitForPendingFinalizers(); + // Destroy objects from game assemblies (eg. not released objects that might crash if persist in memory after reload) + _objectsLocker.Lock(); + { + const auto flaxModule = GetBinaryModuleFlaxEngine(); + for (auto i = _objectsDictionary.Begin(); i.IsNotEnd(); ++i) + { + auto obj = i->Value; + if (obj->GetTypeHandle().Module == flaxModule) + continue; + +#if USE_OBJECTS_DISPOSE_CRASHES_DEBUGGING + LOG(Info, "[OnScriptingDispose] obj = 0x{0:x}, {1}", (uint64)obj.Ptr, String(obj.TypeName)); +#endif + obj->OnScriptingDispose(); + } + } + _objectsLocker.Unlock(); + // Unload all game modules LOG(Info, "Unloading game binary modules"); auto modules = BinaryModule::GetModules(); @@ -821,7 +839,7 @@ void Scripting::OnManagedInstanceDeleted(ScriptingObject* obj) if (_objectsDictionary.ContainsValue(obj)) { #if USE_OBJECTS_DISPOSE_CRASHES_DEBUGGING - LOG(Info, "[OnManagedInstanceDeleted] obj = 0x{0:x}, {1}", (uint32)obj, String(ScriptingObjectData(obj).TypeName)); + LOG(Info, "[OnManagedInstanceDeleted] obj = 0x{0:x}, {1}", (uint64)obj, String(ScriptingObjectData(obj).TypeName)); #endif obj->OnManagedInstanceDeleted(); } @@ -877,7 +895,7 @@ void Scripting::RegisterObject(ScriptingObject* obj) #endif #if USE_OBJECTS_DISPOSE_CRASHES_DEBUGGING - LOG(Info, "[RegisterObject] obj = 0x{0:x}, {1}", (uint32)obj, String(ScriptingObjectData(obj).TypeName)); + LOG(Info, "[RegisterObject] obj = 0x{0:x}, {1}", (uint64)obj, String(ScriptingObjectData(obj).TypeName)); #endif _objectsDictionary.Add(obj->GetID(), obj); } @@ -889,7 +907,7 @@ void Scripting::UnregisterObject(ScriptingObject* obj) //ASSERT(!obj->_id.IsValid() || _objectsDictionary.ContainsValue(obj)); #if USE_OBJECTS_DISPOSE_CRASHES_DEBUGGING - LOG(Info, "[UnregisterObject] obj = 0x{0:x}, {1}", (uint32)obj, String(ScriptingObjectData(obj).TypeName)); + LOG(Info, "[UnregisterObject] obj = 0x{0:x}, {1}", (uint64)obj, String(ScriptingObjectData(obj).TypeName)); #endif _objectsDictionary.Remove(obj->GetID()); } diff --git a/Source/Engine/Scripting/ScriptingObject.cpp b/Source/Engine/Scripting/ScriptingObject.cpp index 9d2320d7f..dd9cf57a8 100644 --- a/Source/Engine/Scripting/ScriptingObject.cpp +++ b/Source/Engine/Scripting/ScriptingObject.cpp @@ -276,10 +276,6 @@ void PersistentScriptingObject::OnManagedInstanceDeleted() _gcHandle = 0; } - // Unregister object - if (IsRegistered()) - UnregisterObject(); - // But do not delete itself } From 58350c87e252502f8191589659374dcfbdb11daa Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 8 Feb 2021 20:20:39 +0100 Subject: [PATCH 51/68] Fix missing CharacterController bounds if controller is missing --- Source/Engine/Graphics/RenderTask.cpp | 3 +-- Source/Engine/Physics/Colliders/CharacterController.cpp | 5 +++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Source/Engine/Graphics/RenderTask.cpp b/Source/Engine/Graphics/RenderTask.cpp index d30e8e37c..405e0fe45 100644 --- a/Source/Engine/Graphics/RenderTask.cpp +++ b/Source/Engine/Graphics/RenderTask.cpp @@ -283,11 +283,10 @@ Viewport SceneRenderTask::GetViewport() const GPUTextureView* SceneRenderTask::GetOutputView() const { - if (Output) + if (Output && Output->IsAllocated()) return Output->View(); if (SwapChain) return SwapChain->GetBackBufferView(); - CRASH; return nullptr; } diff --git a/Source/Engine/Physics/Colliders/CharacterController.cpp b/Source/Engine/Physics/Colliders/CharacterController.cpp index e0630573e..79410bdf4 100644 --- a/Source/Engine/Physics/Colliders/CharacterController.cpp +++ b/Source/Engine/Physics/Colliders/CharacterController.cpp @@ -361,6 +361,11 @@ void CharacterController::OnTransformChanged() UpdateScale(); UpdateBounds(); } + else if (!_controller) + { + _box = BoundingBox(_transform.Translation, _transform.Translation); + BoundingSphere::FromBox(_box, _sphere); + } } void CharacterController::Serialize(SerializeStream& stream, const void* otherObj) From cb6b96dea6ef5bdd65f04e8a5f54cb785544a11d Mon Sep 17 00:00:00 2001 From: Vizepi Date: Tue, 9 Feb 2021 18:08:50 +0100 Subject: [PATCH 52/68] [C++] Added FLAXENGINE_API macro on SettingsBase class so static symbol are retrieved by linker --- Source/Engine/Core/Config/Settings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Engine/Core/Config/Settings.h b/Source/Engine/Core/Config/Settings.h index 0380c96b3..e21e558fc 100644 --- a/Source/Engine/Core/Config/Settings.h +++ b/Source/Engine/Core/Config/Settings.h @@ -9,7 +9,7 @@ /// /// Base class for all global settings containers for the engine. Helps to apply, store and expose properties to c#. /// -class SettingsBase +class FLAXENGINE_API SettingsBase { public: From 6673d70d0acbcd0519005a766ae842fd14b3576c Mon Sep 17 00:00:00 2001 From: Vizepi Date: Tue, 9 Feb 2021 18:20:20 +0100 Subject: [PATCH 53/68] [C++] Add missing header forcing client code to include two headers instead of one --- Source/Engine/Core/Config/LayersTagsSettings.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/Engine/Core/Config/LayersTagsSettings.h b/Source/Engine/Core/Config/LayersTagsSettings.h index 4ed9394fb..c01f915aa 100644 --- a/Source/Engine/Core/Config/LayersTagsSettings.h +++ b/Source/Engine/Core/Config/LayersTagsSettings.h @@ -3,6 +3,7 @@ #pragma once #include "Engine/Core/Config/Settings.h" +#include "Engine/Serialization/Json.h" /// /// Layers and objects tags settings. From 73efa35008e8aa2dbca96963b4d09360d844d3fc Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Tue, 9 Feb 2021 23:31:23 +0100 Subject: [PATCH 54/68] Add `Level.GetActors` and `Level.GetScripts` --- Source/Engine/Level/Level.cpp | 48 +++++++++++++++++++++++++++-------- Source/Engine/Level/Level.cs | 28 ++++++++++++++++++++ Source/Engine/Level/Level.h | 14 ++++++++++ 3 files changed, 80 insertions(+), 10 deletions(-) diff --git a/Source/Engine/Level/Level.cpp b/Source/Engine/Level/Level.cpp index 04918f24b..219893012 100644 --- a/Source/Engine/Level/Level.cpp +++ b/Source/Engine/Level/Level.cpp @@ -1326,12 +1326,8 @@ Actor* Level::FindActor(const MClass* type) CHECK_RETURN(type, nullptr); Actor* result = nullptr; ScopeLock lock(ScenesLock); - for (int32 i = 0; result == nullptr && i < Scenes.Count(); i++) - { result = Scenes[i]->FindActor(type); - } - return result; } @@ -1340,25 +1336,57 @@ Script* Level::FindScript(const MClass* type) CHECK_RETURN(type, nullptr); Script* result = nullptr; ScopeLock lock(ScenesLock); - for (int32 i = 0; result == nullptr && i < Scenes.Count(); i++) - { result = Scenes[i]->FindScript(type); + return result; +} + +namespace +{ + void GetActors(const MClass* type, Actor* actor, Array& result) + { + if (actor->GetClass()->IsSubClassOf(type)) + result.Add(actor); + for (auto child : actor->Children) + GetActors(type, child, result); } + void GetScripts(const MClass* type, Actor* actor, Array& result) + { + for (auto script : actor->Scripts) + if (script->GetClass()->IsSubClassOf(type)) + result.Add(script); + for (auto child : actor->Children) + GetScripts(type, child, result); + } +} + +Array Level::GetActors(const MClass* type) +{ + Array result; + CHECK_RETURN(type, result); + ScopeLock lock(ScenesLock); + for (int32 i = 0; i < Scenes.Count(); i++) + ::GetActors(type, Scenes[i], result); + return result; +} + +Array Level::GetScripts(const MClass* type) +{ + Array result; + CHECK_RETURN(type, result); + ScopeLock lock(ScenesLock); + for (int32 i = 0; i < Scenes.Count(); i++) + ::GetScripts(type, Scenes[i], result); return result; } Scene* Level::FindScene(const Guid& id) { ScopeLock lock(ScenesLock); - for (int32 i = 0; i < Scenes.Count(); i++) - { if (Scenes[i]->GetID() == id) return Scenes[i]; - } - return nullptr; } diff --git a/Source/Engine/Level/Level.cs b/Source/Engine/Level/Level.cs index 6232d2e54..1eafe08d5 100644 --- a/Source/Engine/Level/Level.cs +++ b/Source/Engine/Level/Level.cs @@ -77,5 +77,33 @@ namespace FlaxEngine { return FindActor(id) as T; } + + /// + /// Finds all the scripts of the given type in all the loaded scenes. + /// + /// Type of the object. + /// Found scripts list. + public static T[] GetScripts() where T : Script + { + var scripts = GetScripts(typeof(T)); + var result = new T[scripts.Length]; + for (int i = 0; i < scripts.Length; i++) + result[i] = scripts[i] as T; + return result; + } + + /// + /// Finds all the actors of the given type in all the loaded scenes. + /// + /// Type of the object. + /// Found actors list. + public static T[] GetActors() where T : Actor + { + var actors = GetActors(typeof(T)); + var result = new T[actors.Length]; + for (int i = 0; i < actors.Length; i++) + result[i] = actors[i] as T; + return result; + } } } diff --git a/Source/Engine/Level/Level.h b/Source/Engine/Level/Level.h index 0a10b58d2..5e274978a 100644 --- a/Source/Engine/Level/Level.h +++ b/Source/Engine/Level/Level.h @@ -377,6 +377,20 @@ public: return (T*)FindScript(T::GetStaticClass()); } + /// + /// Finds all the actors of the given type in all the loaded scenes. + /// + /// Type of the actor to search for. Includes any actors derived from the type. + /// Found actors list. + API_FUNCTION() static Array GetActors(const MClass* type); + + /// + /// Finds all the scripts of the given type in all the loaded scenes. + /// + /// Type of the script to search for. Includes any scripts derived from the type. + /// Found scripts list. + API_FUNCTION() static Array GetScripts(const MClass* type); + /// /// Tries to find scene with given ID. /// From 3a3c66b916b8a24d92917d5e32452d419e0e1283 Mon Sep 17 00:00:00 2001 From: Vizepi Date: Wed, 10 Feb 2021 20:32:32 +0100 Subject: [PATCH 55/68] [EDITOR] Fixed layer matrix order ( issue #153 ) --- Source/Editor/CustomEditors/Dedicated/LayersMatrixEditor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Editor/CustomEditors/Dedicated/LayersMatrixEditor.cs b/Source/Editor/CustomEditors/Dedicated/LayersMatrixEditor.cs index 44a273ee4..6c825f46d 100644 --- a/Source/Editor/CustomEditors/Dedicated/LayersMatrixEditor.cs +++ b/Source/Editor/CustomEditors/Dedicated/LayersMatrixEditor.cs @@ -76,7 +76,7 @@ namespace FlaxEditor.CustomEditors.Dedicated upperRightCell.AddChild(new Label { Height = labelsHeight, - Text = layerNames[layerIndex], + Text = layerNames[layerNames.Length - layerIndex - 1], HorizontalAlignment = TextAlignment.Near, }); bottomLeftCell.AddChild(new Label From 2263b3db523fb2c1d724cf974bdd7e9979b4066f Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Wed, 10 Feb 2021 22:59:32 +0100 Subject: [PATCH 56/68] Add ScriptingTypeHandle debugger view to flax.natvis --- Source/flax.natvis | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Source/flax.natvis b/Source/flax.natvis index 15ccaa7e6..550d8a4d4 100644 --- a/Source/flax.natvis +++ b/Source/flax.natvis @@ -206,4 +206,13 @@ + + + Null + Type={Module->Types._allocation._data[TypeIndex].Fullname} + + Module->Types._allocation._data[TypeIndex] + + + From 4c673bec9b9a93d1cd8063c1cb6e7e7a11f65142 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Wed, 10 Feb 2021 22:59:40 +0100 Subject: [PATCH 57/68] Add` BAGUETTE` --- Source/Editor/Windows/SplashScreen.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/Editor/Windows/SplashScreen.cpp b/Source/Editor/Windows/SplashScreen.cpp index b05c73761..bc92a8d2a 100644 --- a/Source/Editor/Windows/SplashScreen.cpp +++ b/Source/Editor/Windows/SplashScreen.cpp @@ -115,6 +115,7 @@ const Char* SplashScreenQuotes[] = TEXT("That's what she said"), TEXT("Compiling Shaders (93,788)"), TEXT("Hi There"), + TEXT("BAGUETTE"), }; SplashScreen::~SplashScreen() From 8158c94d26c1cc233933e638b810f55602f7f394 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Wed, 10 Feb 2021 23:13:16 +0100 Subject: [PATCH 58/68] Fix low-level `WindowsPlatform::Log` to not print invalid characters --- .../Engine/Platform/Windows/WindowsPlatform.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/Source/Engine/Platform/Windows/WindowsPlatform.cpp b/Source/Engine/Platform/Windows/WindowsPlatform.cpp index 0b1f70989..fa93800d8 100644 --- a/Source/Engine/Platform/Windows/WindowsPlatform.cpp +++ b/Source/Engine/Platform/Windows/WindowsPlatform.cpp @@ -630,8 +630,19 @@ void WindowsPlatform::Exit() void WindowsPlatform::Log(const StringView& msg) { - OutputDebugStringW(msg.Get()); - OutputDebugStringW(TEXT(PLATFORM_LINE_TERMINATOR)); + Char buffer[500]; + Char* str; + if (msg.Length() + 3 < ARRAY_COUNT(buffer)) + str = buffer; + else + str = new Char[msg.Length() + 3]; + MemoryCopy(str, msg.Get(), msg.Length() * sizeof(Char)); + str[msg.Length() + 0] = '\r'; + str[msg.Length() + 1] = '\n'; + str[msg.Length() + 2] = 0; + OutputDebugStringW(str); + if (str != buffer) + Free(str); } bool WindowsPlatform::IsDebuggerPresent() From 311793dd7e5a88b8d3882f4b3ffc7b32104fbfb7 Mon Sep 17 00:00:00 2001 From: stefnotch Date: Fri, 12 Feb 2021 22:50:47 +0100 Subject: [PATCH 59/68] Fix StartMouseCapture(true) with secondary monitors on the left Yes, negative mouse coordinates are a thing --- Source/Engine/Platform/Base/WindowBase.h | 1 + Source/Engine/Platform/Windows/WindowsWindow.cpp | 16 +++++++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/Source/Engine/Platform/Base/WindowBase.h b/Source/Engine/Platform/Base/WindowBase.h index 3da48bb7a..a8215bc8b 100644 --- a/Source/Engine/Platform/Base/WindowBase.h +++ b/Source/Engine/Platform/Base/WindowBase.h @@ -284,6 +284,7 @@ protected: Vector2 _trackingMouseOffset; bool _isUsingMouseOffset; + Rectangle _mouseOffsetScreenSize; bool _isTrackingMouse; explicit WindowBase(const CreateWindowSettings& settings); diff --git a/Source/Engine/Platform/Windows/WindowsWindow.cpp b/Source/Engine/Platform/Windows/WindowsWindow.cpp index dc130949c..61c8737b8 100644 --- a/Source/Engine/Platform/Windows/WindowsWindow.cpp +++ b/Source/Engine/Platform/Windows/WindowsWindow.cpp @@ -479,6 +479,10 @@ void WindowsWindow::StartTrackingMouse(bool useMouseScreenOffset) _trackingMouseOffset = Vector2::Zero; _isUsingMouseOffset = useMouseScreenOffset; + int32 x = 0 , y = 0, width = 0, height = 0; + GetScreenInfo(x, y, width, height); + _mouseOffsetScreenSize = Rectangle(x, y, width, height); + SetCapture(_handle); } } @@ -712,18 +716,20 @@ LRESULT WindowsWindow::WndProc(UINT msg, WPARAM wParam, LPARAM lParam) if (_isTrackingMouse && _isUsingMouseOffset) { // Check if move mouse to another edge of the desktop - Vector2 destopSize = Platform::GetVirtualDesktopSize(); + Vector2 desktopLocation = _mouseOffsetScreenSize.Location; + Vector2 destopSize = _mouseOffsetScreenSize.GetBottomRight(); + const Vector2 mousePos(static_cast(WINDOWS_GET_X_LPARAM(lParam)), static_cast(WINDOWS_GET_Y_LPARAM(lParam))); Vector2 mousePosition = ClientToScreen(mousePos); Vector2 newMousePosition = mousePosition; - if (mousePosition.X <= 1) + if (mousePosition.X <= desktopLocation.X + 2) newMousePosition.X = destopSize.X - 2; else if (mousePosition.X >= destopSize.X - 1) - newMousePosition.X = 2; - if (mousePosition.Y <= 1) + newMousePosition.X = desktopLocation.X + 2; + if (mousePosition.Y <= desktopLocation.Y + 2) newMousePosition.Y = destopSize.Y - 2; else if (mousePosition.Y >= destopSize.Y - 1) - newMousePosition.Y = 2; + newMousePosition.Y = desktopLocation.Y + 2; if (!Vector2::NearEqual(mousePosition, newMousePosition)) { _trackingMouseOffset -= newMousePosition - mousePosition; From ccc60af4b619ab81173315e7dd00b82ea9cf03aa Mon Sep 17 00:00:00 2001 From: GoaLitiuM Date: Sat, 13 Feb 2021 00:46:39 +0200 Subject: [PATCH 60/68] Fix crash in Windows platform logging with long lines --- Source/Engine/Platform/Windows/WindowsPlatform.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Engine/Platform/Windows/WindowsPlatform.cpp b/Source/Engine/Platform/Windows/WindowsPlatform.cpp index fa93800d8..cb9999a08 100644 --- a/Source/Engine/Platform/Windows/WindowsPlatform.cpp +++ b/Source/Engine/Platform/Windows/WindowsPlatform.cpp @@ -630,12 +630,12 @@ void WindowsPlatform::Exit() void WindowsPlatform::Log(const StringView& msg) { - Char buffer[500]; + Char buffer[512]; Char* str; if (msg.Length() + 3 < ARRAY_COUNT(buffer)) str = buffer; else - str = new Char[msg.Length() + 3]; + str = (Char*)Allocate((msg.Length() + 3) * sizeof(Char), 16); MemoryCopy(str, msg.Get(), msg.Length() * sizeof(Char)); str[msg.Length() + 0] = '\r'; str[msg.Length() + 1] = '\n'; From ac8c185056940588ee7e269ef938e574767a1ade Mon Sep 17 00:00:00 2001 From: stefnotch Date: Sun, 14 Feb 2021 08:43:50 +0100 Subject: [PATCH 61/68] Fix TreeNode hovering with collapsed children and also set DefaultNodeOffsetY to get rid of the spaces between the nodes --- Source/Editor/GUI/Tree/TreeNode.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Editor/GUI/Tree/TreeNode.cs b/Source/Editor/GUI/Tree/TreeNode.cs index 727da3edd..f7e5f115a 100644 --- a/Source/Editor/GUI/Tree/TreeNode.cs +++ b/Source/Editor/GUI/Tree/TreeNode.cs @@ -21,7 +21,7 @@ namespace FlaxEditor.GUI.Tree /// /// The default node offset on Y axis. /// - public const float DefaultNodeOffsetY = 1; + public const float DefaultNodeOffsetY = 0; private Tree _tree; @@ -539,7 +539,7 @@ namespace FlaxEditor.GUI.Tree { if (new Rectangle(_headerRect.X, _headerRect.Y - DefaultDragInsertPositionMargin - DefaultNodeOffsetY, _headerRect.Width, DefaultDragInsertPositionMargin * 2.0f).Contains(location)) _dragOverMode = DragItemPositioning.Above; - else if (IsCollapsed && new Rectangle(_headerRect.X, _headerRect.Bottom - DefaultDragInsertPositionMargin, _headerRect.Width, DefaultDragInsertPositionMargin * 2.0f).Contains(location)) + else if ((IsCollapsed || !HasAnyVisibleChild) && new Rectangle(_headerRect.X, _headerRect.Bottom - DefaultDragInsertPositionMargin, _headerRect.Width, DefaultDragInsertPositionMargin * 2.0f).Contains(location)) _dragOverMode = DragItemPositioning.Below; else _dragOverMode = DragItemPositioning.At; From ed1a3c2964996602769c335f8bef9c609b7c1ec6 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sun, 14 Feb 2021 14:54:56 +0100 Subject: [PATCH 62/68] Update mono --- Source/Engine/Scripting/ScriptingObject.cpp | 1 - .../Binaries/ThirdParty/x64/MonoPosixHelper.dll | 2 +- .../Windows/Binaries/ThirdParty/x64/eglib.pdb | 4 ++-- .../Windows/Binaries/ThirdParty/x64/libgcmonosgen.pdb | 4 ++-- .../Windows/Binaries/ThirdParty/x64/libmini.pdb | 4 ++-- .../Windows/Binaries/ThirdParty/x64/libmono-static.lib | 4 ++-- .../Windows/Binaries/ThirdParty/x64/libmonoruntime.pdb | 4 ++-- .../Windows/Binaries/ThirdParty/x64/libmonoutils.pdb | 4 ++-- Source/Tools/Flax.Build/Deps/Dependencies/mono.cs | 10 +++++----- 9 files changed, 18 insertions(+), 19 deletions(-) diff --git a/Source/Engine/Scripting/ScriptingObject.cpp b/Source/Engine/Scripting/ScriptingObject.cpp index dd9cf57a8..5cdea3ab4 100644 --- a/Source/Engine/Scripting/ScriptingObject.cpp +++ b/Source/Engine/Scripting/ScriptingObject.cpp @@ -11,7 +11,6 @@ #include "ManagedCLR/MClass.h" #include "ManagedCLR/MUtils.h" #include "ManagedCLR/MField.h" -#include "ManagedCLR/MUtils.h" #if PLATFORM_LINUX #include "ManagedCLR/MCore.h" #endif diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/MonoPosixHelper.dll b/Source/Platforms/Windows/Binaries/ThirdParty/x64/MonoPosixHelper.dll index 65c280e99..dd082f208 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/MonoPosixHelper.dll +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/MonoPosixHelper.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9ad92c41f484482e217f791b5ae7963f5d55c2799bc5578125a88f2d40f33262 +oid sha256:35a252fcb61a805c85558646d073e32f7eb54666931a73380b4dea2879c72584 size 157696 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/eglib.pdb b/Source/Platforms/Windows/Binaries/ThirdParty/x64/eglib.pdb index 1cb5d5f43..a79f59aac 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/eglib.pdb +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/eglib.pdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:86d71f01f6ba35e763467eb5b2be703831065ae7c9438fde4a32e1cd40d68880 -size 151552 +oid sha256:1ff34e923a27392a70eb465df1ecc03372aadac6f2753832cce3d82cd5ae1b75 +size 159744 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/libgcmonosgen.pdb b/Source/Platforms/Windows/Binaries/ThirdParty/x64/libgcmonosgen.pdb index 2c08c3457..166a8df92 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/libgcmonosgen.pdb +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/libgcmonosgen.pdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e7a6731228669866ebfb450bdd14bdb6e54eef8dcc10c36640016630ded6ef73 -size 290816 +oid sha256:d165b1a28ce64c030b4d242b86b813292ce038e0155ad0d6025ed7472e036ce4 +size 348160 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/libmini.pdb b/Source/Platforms/Windows/Binaries/ThirdParty/x64/libmini.pdb index a06e2ddf2..719362b2d 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/libmini.pdb +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/libmini.pdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6e12dfaf49963f4b736d9fbd7bbe16ccbf79045d64df71edc5209ffb25e0d1e0 -size 667648 +oid sha256:9cc98ae831f784a7dd6f15a1dbb083c63e6c50100a201501a7825a6d85baf53e +size 864256 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/libmono-static.lib b/Source/Platforms/Windows/Binaries/ThirdParty/x64/libmono-static.lib index ab2d5015d..1cc28852d 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/libmono-static.lib +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/libmono-static.lib @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b90fdbcfab9d89be16789604edbab46ee8ed0159846be60714ef27ac4444baf2 -size 28391654 +oid sha256:2eac1fd52b8d87a0fe4dce3c02e68da8b35bfaa44cb1689d5d8935f2ba09531b +size 28241218 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/libmonoruntime.pdb b/Source/Platforms/Windows/Binaries/ThirdParty/x64/libmonoruntime.pdb index e2e07cc4a..c60e7dbe4 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/libmonoruntime.pdb +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/libmonoruntime.pdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:db47e63ec05d2c50d661f89c062931787be1722e0387f0076b910a9092fbe962 -size 995328 +oid sha256:188ebd527b432f33f8bfccb4fbada27b029f362918ab5c4b6f82584f9d30b6f3 +size 1249280 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/libmonoutils.pdb b/Source/Platforms/Windows/Binaries/ThirdParty/x64/libmonoutils.pdb index 87d823d36..30be1562b 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/libmonoutils.pdb +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/libmonoutils.pdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3846908f7e00e2ef725c4c770dc69c277491c7e83df6047871fc9cd672d47a6d -size 299008 +oid sha256:289966b7d9ff6255e38a6e45d2b9a5179c42e0f1add6abb70f7fa5501dfc59bc +size 356352 diff --git a/Source/Tools/Flax.Build/Deps/Dependencies/mono.cs b/Source/Tools/Flax.Build/Deps/Dependencies/mono.cs index ca23d81ea..92c9bdec9 100644 --- a/Source/Tools/Flax.Build/Deps/Dependencies/mono.cs +++ b/Source/Tools/Flax.Build/Deps/Dependencies/mono.cs @@ -258,9 +258,8 @@ namespace Flax.Deps.Dependencies "mono_type_normalize", }; - private void BuildMsvc(BuildOptions options, TargetPlatform platform, TargetArchitecture architecture) + private void BuildMsvc(BuildOptions options, TargetPlatform platform, TargetArchitecture architecture, string configuration = "Release") { - var configuration = "Release"; string buildPlatform; switch (architecture) { @@ -491,12 +490,13 @@ namespace Flax.Deps.Dependencies { case TargetPlatform.Windows: { - BuildMsvc(options, platform, TargetArchitecture.x64); + var configuration = "Release"; + BuildMsvc(options, platform, TargetArchitecture.x64, configuration); //BuildBcl(options, platform); // Export header files - Deploy.VCEnvironment.BuildSolution(Path.Combine(root, "msvc", "libmono-dynamic.vcxproj"), "Release", "x64"); - Deploy.VCEnvironment.BuildSolution(Path.Combine(root, "msvc", "build-install.vcxproj"), "Release", "x64"); + Deploy.VCEnvironment.BuildSolution(Path.Combine(root, "msvc", "libmono-dynamic.vcxproj"), configuration, "x64"); + Deploy.VCEnvironment.BuildSolution(Path.Combine(root, "msvc", "build-install.vcxproj"), configuration, "x64"); // Get exported mono methods to forward them in engine module (on Win32 platforms) GetMonoExports(options); From 6bdc31df5a2360784a9ce0db76e68789f876a8ce Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sun, 14 Feb 2021 15:53:08 +0100 Subject: [PATCH 63/68] Fix using `get_Control` getter method from UIControl in Visual Script --- Source/Editor/Utilities/Utils.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Source/Editor/Utilities/Utils.cs b/Source/Editor/Utilities/Utils.cs index ac34d9e45..26c5ec92b 100644 --- a/Source/Editor/Utilities/Utils.cs +++ b/Source/Editor/Utilities/Utils.cs @@ -532,6 +532,8 @@ namespace FlaxEditor.Utilities break; case VariantType.Enum: case VariantType.Structure: + case VariantType.ManagedObject: + case VariantType.Typename: stream.Write(int.MaxValue); stream.WriteStrAnsi(type.FullName, 77); break; @@ -761,7 +763,7 @@ namespace FlaxEditor.Utilities data[i] = (byte)(c ^ 77); } var typeName = System.Text.Encoding.ASCII.GetString(data); - return TypeUtils.GetType(typeName).Type; + return TypeUtils.GetManagedType(typeName); } if (typeNameLength > 0) { @@ -773,7 +775,7 @@ namespace FlaxEditor.Utilities data[i] = (char)(c ^ 77); } var typeName = new string(data); - return TypeUtils.GetType(typeName).Type; + return TypeUtils.GetManagedType(typeName); } switch (variantType) { @@ -826,7 +828,7 @@ namespace FlaxEditor.Utilities data[i] = (byte)(c ^ 77); } var typeName = System.Text.Encoding.ASCII.GetString(data); - type = TypeUtils.GetType(typeName).Type; + type = TypeUtils.GetManagedType(typeName); } else if (typeNameLength > 0) { @@ -838,7 +840,7 @@ namespace FlaxEditor.Utilities data[i] = (char)(c ^ 77); } var typeName = new string(data); - type = TypeUtils.GetType(typeName).Type; + type = TypeUtils.GetManagedType(typeName); } switch (variantType) { From 3bbda838a22cfb98198aa62bfb9e9e27626bebe4 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sun, 14 Feb 2021 16:50:35 +0100 Subject: [PATCH 64/68] Fix error when spawning prefab with rigidbody --- Source/Engine/Level/Actor.cpp | 2 ++ Source/Engine/Level/Level.cpp | 2 +- Source/Engine/Level/Prefabs/PrefabManager.cpp | 4 +++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Source/Engine/Level/Actor.cpp b/Source/Engine/Level/Actor.cpp index 81a5b3155..e88791442 100644 --- a/Source/Engine/Level/Actor.cpp +++ b/Source/Engine/Level/Actor.cpp @@ -43,6 +43,8 @@ Actor::Actor(const SpawnParams& params) , _staticFlags(StaticFlags::FullyStatic) , _localTransform(Transform::Identity) , _transform(Transform::Identity) + , _sphere(BoundingSphere::Empty) + , _box(BoundingBox::Empty) , HideFlags(HideFlags::None) { } diff --git a/Source/Engine/Level/Level.cpp b/Source/Engine/Level/Level.cpp index 219893012..62d066803 100644 --- a/Source/Engine/Level/Level.cpp +++ b/Source/Engine/Level/Level.cpp @@ -973,7 +973,7 @@ bool Level::loadScene(rapidjson_flax::Value& data, int32 engineBuild, bool autoI if (obj && obj->GetParent() == nullptr) { sceneObjects->At(i) = nullptr; - LOG(Warning, "Scene object {0} {1} has missing parent object after scene load. Removing it.", obj->GetID(), obj->ToString()); + LOG(Warning, "Scene object {0} {1} has missing parent object after load. Removing it.", obj->GetID(), obj->ToString()); obj->DeleteObject(); } } diff --git a/Source/Engine/Level/Prefabs/PrefabManager.cpp b/Source/Engine/Level/Prefabs/PrefabManager.cpp index 44be0181b..512d6e9b7 100644 --- a/Source/Engine/Level/Prefabs/PrefabManager.cpp +++ b/Source/Engine/Level/Prefabs/PrefabManager.cpp @@ -181,6 +181,8 @@ Actor* PrefabManager::SpawnPrefab(Prefab* prefab, Actor* parent, Dictionary_parent = parent; + if (parent) + parent->Children.Add(root); // Link actors hierarchy for (int32 i = 0; i < sceneObjects->Count(); i++) @@ -226,7 +228,7 @@ Actor* PrefabManager::SpawnPrefab(Prefab* prefab, Actor* parent, DictionaryGetParent() == nullptr) { sceneObjects->At(i) = nullptr; - LOG(Warning, "Scene object {0} {1} has missing parent objct after prefab spawn. Removing it.", obj->GetID(), obj->ToString()); + LOG(Warning, "Scene object {0} {1} has missing parent object after load. Removing it.", obj->GetID(), obj->ToString()); obj->DeleteObject(); } } From a947dc0cc372162d5de3dbd0a00a5cbb4de61047 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sun, 14 Feb 2021 17:12:29 +0100 Subject: [PATCH 65/68] Fix properties names formatting for UI with 2 character words Fixes #229 --- Source/Editor/CustomEditors/CustomEditorsUtil.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Editor/CustomEditors/CustomEditorsUtil.cs b/Source/Editor/CustomEditors/CustomEditorsUtil.cs index 2f97da333..9b83dd820 100644 --- a/Source/Editor/CustomEditors/CustomEditorsUtil.cs +++ b/Source/Editor/CustomEditors/CustomEditorsUtil.cs @@ -71,7 +71,7 @@ namespace FlaxEditor.CustomEditors // Space before word starting with uppercase letter if (char.IsUpper(c) && i > 0) { - if (i + 2 < length && !char.IsUpper(name[i + 1]) && !char.IsUpper(name[i + 2])) + if (i + 1 < length && !char.IsUpper(name[i + 1])) sb.Append(' '); } // Space instead of underscore From 865f2b871d2ff1430f1390126c3d5ac0477be526 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sun, 14 Feb 2021 18:09:29 +0100 Subject: [PATCH 66/68] Fix default frame rate for fbx imported clips to 14 https://github.com/nem0/OpenFBX/commit/2650de730d3f2d41b5042992f9443affd58e3553 --- Source/ThirdParty/OpenFBX/ofbx.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/ThirdParty/OpenFBX/ofbx.cpp b/Source/ThirdParty/OpenFBX/ofbx.cpp index dc7c92718..36f942cf8 100644 --- a/Source/ThirdParty/OpenFBX/ofbx.cpp +++ b/Source/ThirdParty/OpenFBX/ofbx.cpp @@ -2894,7 +2894,7 @@ static float getFramerateFromTimeMode(FrameRate time_mode, float custom_frame_ra { switch (time_mode) { - case FrameRate_DEFAULT: return 1; + case FrameRate_DEFAULT: return 14; case FrameRate_120: return 120; case FrameRate_100: return 100; case FrameRate_60: return 60; From f82ef8c065ba875fb6b0ce59c491ed3860f47afc Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sun, 14 Feb 2021 18:18:58 +0100 Subject: [PATCH 67/68] Fix AssetPicker buttons usage without mouse down click over the control Fixes #233 --- Source/Editor/GUI/AssetPicker.cs | 53 +++++++++++++++----------------- 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/Source/Editor/GUI/AssetPicker.cs b/Source/Editor/GUI/AssetPicker.cs index 63c1276ab..db012ab1e 100644 --- a/Source/Editor/GUI/AssetPicker.cs +++ b/Source/Editor/GUI/AssetPicker.cs @@ -355,12 +355,10 @@ namespace FlaxEditor.GUI _mousePos = location; // Check if start drag drop - if (_isMouseDown && Vector2.Distance(location, _mouseDownPos) > 10.0f) + if (_isMouseDown && Vector2.Distance(location, _mouseDownPos) > 10.0f && IconRect.Contains(_mouseDownPos)) { - // Clear flag - _isMouseDown = false; - // Do the drag + _isMouseDown = false; DoDrag(); } @@ -370,35 +368,35 @@ namespace FlaxEditor.GUI /// public override bool OnMouseUp(Vector2 location, MouseButton button) { - if (button == MouseButton.Left) + if (button == MouseButton.Left && _isMouseDown) { _isMouseDown = false; - } - // Buttons logic - if (Button1Rect.Contains(location)) - { - // Show asset picker popup - Focus(); - AssetSearchPopup.Show(this, Button1Rect.BottomLeft, IsValid, assetItem => + // Buttons logic + if (Button1Rect.Contains(location)) { - SelectedItem = assetItem; - RootWindow.Focus(); + // Show asset picker popup Focus(); - }); - } - else if (_selected != null || _selectedItem != null) - { - if (Button2Rect.Contains(location) && _selectedItem != null) - { - // Select asset - Editor.Instance.Windows.ContentWin.Select(_selectedItem); + AssetSearchPopup.Show(this, Button1Rect.BottomLeft, IsValid, assetItem => + { + SelectedItem = assetItem; + RootWindow.Focus(); + Focus(); + }); } - else if (Button3Rect.Contains(location)) + else if (_selected != null || _selectedItem != null) { - // Deselect asset - Focus(); - SelectedItem = null; + if (Button2Rect.Contains(location) && _selectedItem != null) + { + // Select asset + Editor.Instance.Windows.ContentWin.Select(_selectedItem); + } + else if (Button3Rect.Contains(location)) + { + // Deselect asset + Focus(); + SelectedItem = null; + } } } @@ -409,8 +407,7 @@ namespace FlaxEditor.GUI /// public override bool OnMouseDown(Vector2 location, MouseButton button) { - // Set flag for dragging asset - if (button == MouseButton.Left && IconRect.Contains(location)) + if (button == MouseButton.Left) { _isMouseDown = true; _mouseDownPos = location; From b4bf488e3c82f6f8f79173009af0cc1ca612af99 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sun, 14 Feb 2021 18:41:28 +0100 Subject: [PATCH 68/68] Fix double-click mouse event not setting mouse button down Fixes #235 --- Source/Engine/Input/Input.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/Engine/Input/Input.cpp b/Source/Engine/Input/Input.cpp index 72cc6bcb9..825e7f6b2 100644 --- a/Source/Engine/Input/Input.cpp +++ b/Source/Engine/Input/Input.cpp @@ -191,6 +191,7 @@ bool Mouse::Update(EventQueue& queue) } case EventType::MouseDoubleClick: { + _state.MouseButtons[static_cast(e.MouseData.Button)] = true; break; } case EventType::MouseWheel: