From 8f76fe40498c014318d22f45c3ce644544eeeaa6 Mon Sep 17 00:00:00 2001
From: Ruan Lucas <79365912+RuanLucasGD@users.noreply.github.com>
Date: Fri, 9 Jun 2023 22:14:33 -0400
Subject: [PATCH 01/65] don't let rename source/content folders
---
Source/Editor/Content/Items/ContentFolder.cs | 11 ++++++++++-
Source/Editor/ProjectInfo.cs | 12 ++++++++++++
2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/Source/Editor/Content/Items/ContentFolder.cs b/Source/Editor/Content/Items/ContentFolder.cs
index 86c374fee..f3c698782 100644
--- a/Source/Editor/Content/Items/ContentFolder.cs
+++ b/Source/Editor/Content/Items/ContentFolder.cs
@@ -113,7 +113,16 @@ namespace FlaxEditor.Content
public override ContentItemSearchFilter SearchFilter => ContentItemSearchFilter.Other;
///
- public override bool CanRename => ParentFolder != null; // Deny rename action for root folders
+ public override bool CanRename
+ {
+ get
+ {
+ var hasParentFolder = ParentFolder != null;
+ var isContentFolder = IsFolder && Path == Editor.Instance.GameProject.ContentFolderPath;
+ var isSourceFolder = IsFolder && Path == Editor.Instance.GameProject.SourceFolderPath;
+ return hasParentFolder && !isContentFolder && !isSourceFolder;
+ }
+ }
///
public override bool CanDrag => ParentFolder != null; // Deny rename action for root folders
diff --git a/Source/Editor/ProjectInfo.cs b/Source/Editor/ProjectInfo.cs
index bc55a9c05..62402b0d8 100644
--- a/Source/Editor/ProjectInfo.cs
+++ b/Source/Editor/ProjectInfo.cs
@@ -55,6 +55,16 @@ namespace FlaxEditor
[NonSerialized]
public string ProjectFolderPath;
+ ///
+ /// The content assets folder
+ ///
+ public string ContentFolderPath;
+
+ ///
+ /// The source files folder path
+ ///
+ public string SourceFolderPath;
+
///
/// The project version.
///
@@ -157,6 +167,8 @@ namespace FlaxEditor
var project = JsonConvert.DeserializeObject(contents);
project.ProjectPath = path;
project.ProjectFolderPath = StringUtils.NormalizePath(Path.GetDirectoryName(path));
+ project.ContentFolderPath = StringUtils.NormalizePath(project.ProjectFolderPath + "/Content");
+ project.SourceFolderPath = StringUtils.NormalizePath(project.ProjectFolderPath + "/Source");
// Process project data
if (string.IsNullOrEmpty(project.Name))
From 164670cceb4b7bdc654b928e1da771a286e312d1 Mon Sep 17 00:00:00 2001
From: Ruan Lucas <79365912+RuanLucasGD@users.noreply.github.com>
Date: Mon, 12 Jun 2023 20:04:32 -0400
Subject: [PATCH 02/65] change content folder detection mode on "CanRename"
---
Source/Editor/Content/Items/ContentFolder.cs | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/Source/Editor/Content/Items/ContentFolder.cs b/Source/Editor/Content/Items/ContentFolder.cs
index f3c698782..57e55d3fe 100644
--- a/Source/Editor/Content/Items/ContentFolder.cs
+++ b/Source/Editor/Content/Items/ContentFolder.cs
@@ -118,9 +118,8 @@ namespace FlaxEditor.Content
get
{
var hasParentFolder = ParentFolder != null;
- var isContentFolder = IsFolder && Path == Editor.Instance.GameProject.ContentFolderPath;
- var isSourceFolder = IsFolder && Path == Editor.Instance.GameProject.SourceFolderPath;
- return hasParentFolder && !isContentFolder && !isSourceFolder;
+ var isContentFolder = Node is MainContentTreeNode;
+ return hasParentFolder && !isContentFolder;
}
}
From 2190031ccf42e954cffdc8931d0e0a7ef5857053 Mon Sep 17 00:00:00 2001
From: Ari Vuollet
Date: Sun, 18 Jun 2023 20:10:56 +0300
Subject: [PATCH 03/65] Support decimal values in Font sizes
---
Source/Editor/Windows/SplashScreen.cpp | 4 ++--
Source/Engine/Render2D/Font.cpp | 4 ++--
Source/Engine/Render2D/Font.h | 6 +++---
Source/Engine/Render2D/FontAsset.cpp | 2 +-
Source/Engine/Render2D/FontAsset.h | 2 +-
Source/Engine/Render2D/FontReference.cs | 8 ++++----
Source/Engine/UI/TextRender.cpp | 6 +++---
Source/Engine/UI/TextRender.h | 6 +++---
8 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/Source/Editor/Windows/SplashScreen.cpp b/Source/Editor/Windows/SplashScreen.cpp
index 3e36d3618..7cf7a7f78 100644
--- a/Source/Editor/Windows/SplashScreen.cpp
+++ b/Source/Editor/Windows/SplashScreen.cpp
@@ -304,6 +304,6 @@ void SplashScreen::OnFontLoaded(Asset* asset)
// Create fonts
const float s = _dpiScale;
- _titleFont = font->CreateFont((uint32)(35 * s));
- _subtitleFont = font->CreateFont((uint32)(9 * s));
+ _titleFont = font->CreateFont(35 * s);
+ _subtitleFont = font->CreateFont(9 * s);
}
diff --git a/Source/Engine/Render2D/Font.cpp b/Source/Engine/Render2D/Font.cpp
index f12a9ce1c..90423f5ce 100644
--- a/Source/Engine/Render2D/Font.cpp
+++ b/Source/Engine/Render2D/Font.cpp
@@ -7,7 +7,7 @@
#include "Engine/Threading/Threading.h"
#include "IncludeFreeType.h"
-Font::Font(FontAsset* parentAsset, int32 size)
+Font::Font(FontAsset* parentAsset, float size)
: ManagedScriptingObject(SpawnParams(Guid::New(), Font::TypeInitializer))
, _asset(parentAsset)
, _size(size)
@@ -436,7 +436,7 @@ void Font::FlushFaceSize() const
{
// Set the character size
const FT_Face face = _asset->GetFTFace();
- const FT_Error error = FT_Set_Char_Size(face, 0, ConvertPixelTo26Dot6((float)_size * FontManager::FontScale), DefaultDPI, DefaultDPI);
+ const FT_Error error = FT_Set_Char_Size(face, 0, ConvertPixelTo26Dot6(_size * FontManager::FontScale), DefaultDPI, DefaultDPI);
if (error)
{
LOG_FT_ERROR(error);
diff --git a/Source/Engine/Render2D/Font.h b/Source/Engine/Render2D/Font.h
index d68f497d6..90f723cd8 100644
--- a/Source/Engine/Render2D/Font.h
+++ b/Source/Engine/Render2D/Font.h
@@ -228,7 +228,7 @@ DECLARE_SCRIPTING_TYPE_NO_SPAWN(Font);
private:
FontAsset* _asset;
- int32 _size;
+ float _size;
int32 _height;
int32 _ascender;
int32 _descender;
@@ -244,7 +244,7 @@ public:
///
/// The parent asset.
/// The size.
- Font(FontAsset* parentAsset, int32 size);
+ Font(FontAsset* parentAsset, float size);
///
/// Finalizes an instance of the class.
@@ -264,7 +264,7 @@ public:
///
/// Gets font size.
///
- API_PROPERTY() FORCE_INLINE int32 GetSize() const
+ API_PROPERTY() FORCE_INLINE float GetSize() const
{
return _size;
}
diff --git a/Source/Engine/Render2D/FontAsset.cpp b/Source/Engine/Render2D/FontAsset.cpp
index 5fa07771f..f000eb3c6 100644
--- a/Source/Engine/Render2D/FontAsset.cpp
+++ b/Source/Engine/Render2D/FontAsset.cpp
@@ -92,7 +92,7 @@ void FontAsset::SetOptions(const FontOptions& value)
_options = value;
}
-Font* FontAsset::CreateFont(int32 size)
+Font* FontAsset::CreateFont(float size)
{
PROFILE_CPU();
diff --git a/Source/Engine/Render2D/FontAsset.h b/Source/Engine/Render2D/FontAsset.h
index abc601f45..60dbee01d 100644
--- a/Source/Engine/Render2D/FontAsset.h
+++ b/Source/Engine/Render2D/FontAsset.h
@@ -139,7 +139,7 @@ public:
///
/// The font characters size.
/// The created font object.
- API_FUNCTION() Font* CreateFont(int32 size);
+ API_FUNCTION() Font* CreateFont(float size);
///
/// Gets the font with bold style. Returns itself or creates a new virtual font asset using this font but with bold option enabled.
diff --git a/Source/Engine/Render2D/FontReference.cs b/Source/Engine/Render2D/FontReference.cs
index 290e10312..cc32bcd9a 100644
--- a/Source/Engine/Render2D/FontReference.cs
+++ b/Source/Engine/Render2D/FontReference.cs
@@ -13,7 +13,7 @@ namespace FlaxEngine
private FontAsset _font;
[NoSerialize]
- private int _size;
+ private float _size;
[NoSerialize]
private Font _cachedFont;
@@ -33,7 +33,7 @@ namespace FlaxEngine
///
/// The font.
/// The font size.
- public FontReference(FontAsset font, int size)
+ public FontReference(FontAsset font, float size)
{
_font = font;
_size = size;
@@ -91,7 +91,7 @@ namespace FlaxEngine
/// The size of the font characters.
///
[EditorOrder(10), Limit(1, 500, 0.1f), Tooltip("The size of the font characters.")]
- public int Size
+ public float Size
{
get => _size;
set
@@ -187,7 +187,7 @@ namespace FlaxEngine
unchecked
{
int hashCode = _font ? _font.GetHashCode() : 0;
- hashCode = (hashCode * 397) ^ _size;
+ hashCode = (hashCode * 397) ^ _size.GetHashCode();
return hashCode;
}
}
diff --git a/Source/Engine/UI/TextRender.cpp b/Source/Engine/UI/TextRender.cpp
index d4db794eb..cd60abddf 100644
--- a/Source/Engine/UI/TextRender.cpp
+++ b/Source/Engine/UI/TextRender.cpp
@@ -73,14 +73,14 @@ void TextRender::SetColor(const Color& value)
}
}
-int32 TextRender::GetFontSize() const
+float TextRender::GetFontSize() const
{
return _size;
}
-void TextRender::SetFontSize(int32 value)
+void TextRender::SetFontSize(float value)
{
- value = Math::Clamp(value, 1, 1024);
+ value = Math::Clamp(value, 1.0f, 1024.0f);
if (_size != value)
{
_size = value;
diff --git a/Source/Engine/UI/TextRender.h b/Source/Engine/UI/TextRender.h
index d69b5427b..816ad8aa4 100644
--- a/Source/Engine/UI/TextRender.h
+++ b/Source/Engine/UI/TextRender.h
@@ -38,7 +38,7 @@ private:
LocalizedString _text;
Color _color;
TextLayoutOptions _layoutOptions;
- int32 _size;
+ float _size;
int32 _sceneRenderingKey = -1;
BoundingBox _localBox;
@@ -91,12 +91,12 @@ public:
/// Gets the font characters size.
///
API_PROPERTY(Attributes="EditorOrder(40), DefaultValue(32), Limit(1, 1000), EditorDisplay(\"Text\")")
- int32 GetFontSize() const;
+ float GetFontSize() const;
///
/// Sets the font characters size.
///
- API_PROPERTY() void SetFontSize(int32 value);
+ API_PROPERTY() void SetFontSize(float value);
///
/// The draw passes to use for rendering this object.
From 6a1552505ec226794f793b43557a7a3cc543cbe4 Mon Sep 17 00:00:00 2001
From: Ari Vuollet
Date: Sun, 18 Jun 2023 21:22:24 +0300
Subject: [PATCH 04/65] Fix sluggish EditorViewport camera movement with high
DPI
Flooring the mouse delta values seems to drop slight movements in
viewport when screen DPI is high.
---
Source/Editor/Viewport/EditorViewport.cs | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/Source/Editor/Viewport/EditorViewport.cs b/Source/Editor/Viewport/EditorViewport.cs
index f56370352..b4fb8f8f1 100644
--- a/Source/Editor/Viewport/EditorViewport.cs
+++ b/Source/Editor/Viewport/EditorViewport.cs
@@ -1168,14 +1168,15 @@ namespace FlaxEditor.Viewport
{
offset = Float2.Zero;
}
- offset.X = offset.X > 0 ? Mathf.Floor(offset.X) : Mathf.Ceil(offset.X);
- offset.Y = offset.Y > 0 ? Mathf.Floor(offset.Y) : Mathf.Ceil(offset.Y);
- _mouseDelta = offset / size;
- _mouseDelta.Y *= size.Y / size.X;
var mouseDelta = Float2.Zero;
if (_useMouseFiltering)
{
+ offset.X = offset.X > 0 ? Mathf.Floor(offset.X) : Mathf.Ceil(offset.X);
+ offset.Y = offset.Y > 0 ? Mathf.Floor(offset.Y) : Mathf.Ceil(offset.Y);
+ _mouseDelta = offset / size;
+ _mouseDelta.Y *= size.Y / size.X;
+
// Update delta filtering buffer
_deltaFilteringBuffer[_deltaFilteringStep] = _mouseDelta;
_deltaFilteringStep++;
@@ -1192,6 +1193,8 @@ namespace FlaxEditor.Viewport
}
else
{
+ _mouseDelta = offset / size;
+ _mouseDelta.Y *= size.Y / size.X;
mouseDelta = _mouseDelta;
}
From 46c406cc9e97e5e8e7bcdcb3897a825d97934c0f Mon Sep 17 00:00:00 2001
From: Wiktor Kocielski
Date: Mon, 19 Jun 2023 15:54:03 +0300
Subject: [PATCH 05/65] Implement optional object replication
---
Source/Engine/Networking/NetworkReplicationHierarchy.cpp | 6 +++++-
Source/Engine/Networking/NetworkReplicationHierarchy.h | 2 +-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/Source/Engine/Networking/NetworkReplicationHierarchy.cpp b/Source/Engine/Networking/NetworkReplicationHierarchy.cpp
index d86acfc7f..3935229a9 100644
--- a/Source/Engine/Networking/NetworkReplicationHierarchy.cpp
+++ b/Source/Engine/Networking/NetworkReplicationHierarchy.cpp
@@ -80,7 +80,11 @@ void NetworkReplicationNode::Update(NetworkReplicationHierarchyUpdateResult* res
const float networkFPS = NetworkManager::NetworkFPS / result->ReplicationScale;
for (NetworkReplicationHierarchyObject& obj : Objects)
{
- if (obj.ReplicationFPS <= 0.0f)
+ if (obj.ReplicationFPS < 0.0f)
+ {
+ continue;
+ }
+ else if (obj.ReplicationFPS == 0.0f)
{
// Always relevant
result->AddObject(obj.Object);
diff --git a/Source/Engine/Networking/NetworkReplicationHierarchy.h b/Source/Engine/Networking/NetworkReplicationHierarchy.h
index 55cd6b7b1..f052a3b93 100644
--- a/Source/Engine/Networking/NetworkReplicationHierarchy.h
+++ b/Source/Engine/Networking/NetworkReplicationHierarchy.h
@@ -20,7 +20,7 @@ API_STRUCT(NoDefault, Namespace = "FlaxEngine.Networking") struct FLAXENGINE_API
// The object to replicate.
API_FIELD() ScriptingObjectReference Object;
- // The target amount of the replication updates per second (frequency of the replication). Constrained by NetworkManager::NetworkFPS. Use 0 for 'always relevant' object.
+ // The target amount of the replication updates per second (frequency of the replication). Constrained by NetworkManager::NetworkFPS. Use 0 for 'always relevant' object and < 0 for 'never relevant' objects that would only get synched on client join once.
API_FIELD() float ReplicationFPS = 60;
// The minimum distance from the player to the object at which it can process replication. For example, players further away won't receive object data. Use 0 if unused.
API_FIELD() float CullDistance = 15000;
From e17eed7029ffd63c46e7be1d4227769adc603dbc Mon Sep 17 00:00:00 2001
From: Wojtek Figat
Date: Mon, 19 Jun 2023 17:49:34 +0200
Subject: [PATCH 06/65] Fix regression in script values creation in Editor
#1184 #1183
---
Source/Editor/Scripting/ScriptType.cs | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/Source/Editor/Scripting/ScriptType.cs b/Source/Editor/Scripting/ScriptType.cs
index d174b7dff..454c3a5d2 100644
--- a/Source/Editor/Scripting/ScriptType.cs
+++ b/Source/Editor/Scripting/ScriptType.cs
@@ -832,7 +832,7 @@ namespace FlaxEditor.Scripting
get
{
if (_managed != null)
- return _managed.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null) != null;
+ return _managed.IsValueType || _managed.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null) != null;
return _custom?.CanCreateInstance ?? false;
}
}
@@ -893,9 +893,16 @@ namespace FlaxEditor.Scripting
{
if (_managed != null)
{
- var ctor = _managed.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null);
object value = RuntimeHelpers.GetUninitializedObject(_managed);
- ctor.Invoke(value, null);
+ if (!_managed.IsValueType)
+ {
+ var ctor = _managed.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null);
+#if !BUILD_RELEASE
+ if (ctor == null)
+ throw new Exception($"Missing empty constructor for type {_managed.FullName}.");
+#endif
+ ctor.Invoke(value, null);
+ }
return value;
}
return _custom.CreateInstance();
From f7e3480d79525e2e3692c95b865b0afdd19de084 Mon Sep 17 00:00:00 2001
From: Wojtek Figat
Date: Mon, 19 Jun 2023 18:01:25 +0200
Subject: [PATCH 07/65] Fix floating point comparison #1188
---
Source/Engine/Networking/NetworkReplicationHierarchy.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Source/Engine/Networking/NetworkReplicationHierarchy.cpp b/Source/Engine/Networking/NetworkReplicationHierarchy.cpp
index 3935229a9..99a43a34a 100644
--- a/Source/Engine/Networking/NetworkReplicationHierarchy.cpp
+++ b/Source/Engine/Networking/NetworkReplicationHierarchy.cpp
@@ -80,11 +80,11 @@ void NetworkReplicationNode::Update(NetworkReplicationHierarchyUpdateResult* res
const float networkFPS = NetworkManager::NetworkFPS / result->ReplicationScale;
for (NetworkReplicationHierarchyObject& obj : Objects)
{
- if (obj.ReplicationFPS < 0.0f)
+ if (obj.ReplicationFPS < -ZeroTolerance) // < 0
{
continue;
}
- else if (obj.ReplicationFPS == 0.0f)
+ else if (obj.ReplicationFPS < ZeroTolerance) // == 0
{
// Always relevant
result->AddObject(obj.Object);
From 6f487bcab5bb77364ee44543efa008ba0f497534 Mon Sep 17 00:00:00 2001
From: Wojtek Figat
Date: Mon, 19 Jun 2023 18:05:00 +0200
Subject: [PATCH 08/65] Fix doc comment warning #1188
---
Source/Engine/Networking/NetworkReplicationHierarchy.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Source/Engine/Networking/NetworkReplicationHierarchy.h b/Source/Engine/Networking/NetworkReplicationHierarchy.h
index f052a3b93..36701c15d 100644
--- a/Source/Engine/Networking/NetworkReplicationHierarchy.h
+++ b/Source/Engine/Networking/NetworkReplicationHierarchy.h
@@ -20,7 +20,7 @@ API_STRUCT(NoDefault, Namespace = "FlaxEngine.Networking") struct FLAXENGINE_API
// The object to replicate.
API_FIELD() ScriptingObjectReference Object;
- // The target amount of the replication updates per second (frequency of the replication). Constrained by NetworkManager::NetworkFPS. Use 0 for 'always relevant' object and < 0 for 'never relevant' objects that would only get synched on client join once.
+ // The target amount of the replication updates per second (frequency of the replication). Constrained by NetworkManager::NetworkFPS. Use 0 for 'always relevant' object and less than 0 (eg. -1) for 'never relevant' objects that would only get synched on client join once.
API_FIELD() float ReplicationFPS = 60;
// The minimum distance from the player to the object at which it can process replication. For example, players further away won't receive object data. Use 0 if unused.
API_FIELD() float CullDistance = 15000;
From b82f19a0dfbd87d5ae449c18bcc5c095b7f007e2 Mon Sep 17 00:00:00 2001
From: Ari Vuollet
Date: Mon, 19 Jun 2023 19:32:38 +0300
Subject: [PATCH 09/65] Support changing C# nullable references context build
option
---
.../Flax.Build/Build/DotNet/Builder.DotNet.cs | 5 ++-
.../Build/NativeCpp/BuildOptions.cs | 35 +++++++++++++++++++
.../VisualStudio/CSSDKProjectGenerator.cs | 2 +-
3 files changed, 40 insertions(+), 2 deletions(-)
diff --git a/Source/Tools/Flax.Build/Build/DotNet/Builder.DotNet.cs b/Source/Tools/Flax.Build/Build/DotNet/Builder.DotNet.cs
index 921a1e43f..e6a250eb5 100644
--- a/Source/Tools/Flax.Build/Build/DotNet/Builder.DotNet.cs
+++ b/Source/Tools/Flax.Build/Build/DotNet/Builder.DotNet.cs
@@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using Flax.Build.Graph;
+using Flax.Build.NativeCpp;
using Flax.Deploy;
namespace Flax.Build
@@ -242,7 +243,9 @@ namespace Flax.Build
args.Add("/filealign:512");
#if USE_NETCORE
args.Add("/langversion:11.0");
- args.Add("-nowarn:8632"); // Nullable
+ args.Add(string.Format("/nullable:{0}", buildOptions.ScriptingAPI.CSharpNullableReferences.ToString().ToLowerInvariant()));
+ if (buildOptions.ScriptingAPI.CSharpNullableReferences == CSharpNullableReferences.Disable)
+ args.Add("-nowarn:8632"); // The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
#else
args.Add("/langversion:7.3");
#endif
diff --git a/Source/Tools/Flax.Build/Build/NativeCpp/BuildOptions.cs b/Source/Tools/Flax.Build/Build/NativeCpp/BuildOptions.cs
index 8a5a55873..c2ea81372 100644
--- a/Source/Tools/Flax.Build/Build/NativeCpp/BuildOptions.cs
+++ b/Source/Tools/Flax.Build/Build/NativeCpp/BuildOptions.cs
@@ -23,6 +23,32 @@ namespace Flax.Build.NativeCpp
GenerateProject = 1,
}
+ ///
+ /// The nullable context type used with reference types (C#).
+ ///
+ public enum CSharpNullableReferences
+ {
+ ///
+ /// The code is nullable oblivious, nullable warnings and language analysis features are disabled.
+ ///
+ Disable,
+
+ ///
+ /// The compiler enables all null reference analysis and all language features.
+ ///
+ Enable,
+
+ ///
+ /// The compiler performs all null analysis and emits warnings when code might dereference null.
+ ///
+ Warnings,
+
+ ///
+ /// The compiler doesn't perform null analysis or emit warnings when code might dereference null.
+ ///
+ Annotations,
+ }
+
///
/// The native C++ module build settings container.
///
@@ -188,6 +214,15 @@ namespace Flax.Build.NativeCpp
///
public bool IgnoreMissingDocumentationWarnings;
+ ///
+ /// The nullable context used in C# project.
+ ///
+ public CSharpNullableReferences CSharpNullableReferences = CSharpNullableReferences.Disable;
+
+ public ScriptingAPIOptions()
+ {
+ }
+
///
/// Adds the other options into this.
///
diff --git a/Source/Tools/Flax.Build/Projects/VisualStudio/CSSDKProjectGenerator.cs b/Source/Tools/Flax.Build/Projects/VisualStudio/CSSDKProjectGenerator.cs
index ed8222fb7..efce04776 100644
--- a/Source/Tools/Flax.Build/Projects/VisualStudio/CSSDKProjectGenerator.cs
+++ b/Source/Tools/Flax.Build/Projects/VisualStudio/CSSDKProjectGenerator.cs
@@ -88,7 +88,7 @@ namespace Flax.Build.Projects.VisualStudio
csProjectFileContent.AppendLine(" net7.0");
csProjectFileContent.AppendLine(" disable");
- csProjectFileContent.AppendLine(" annotations");
+ csProjectFileContent.AppendLine(string.Format(" {0}", baseConfiguration.TargetBuildOptions.ScriptingAPI.CSharpNullableReferences.ToString().ToLowerInvariant()));
csProjectFileContent.AppendLine(" false");
csProjectFileContent.AppendLine(" false");
csProjectFileContent.AppendLine(" false");
From c0ba3b0edbf4e26b1efc34fce9a08e044e66e859 Mon Sep 17 00:00:00 2001
From: Ari Vuollet
Date: Mon, 19 Jun 2023 22:18:06 +0300
Subject: [PATCH 10/65] Expose Content importers and exporters for scripting
API
---
Source/Engine/ContentExporters/AssetsExportingManager.h | 2 +-
Source/Engine/ContentExporters/Types.h | 2 +-
Source/Engine/ContentImporters/AssetsImportingManager.h | 2 +-
Source/Engine/ContentImporters/Types.h | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/Source/Engine/ContentExporters/AssetsExportingManager.h b/Source/Engine/ContentExporters/AssetsExportingManager.h
index f9f50075e..7e3b11b6d 100644
--- a/Source/Engine/ContentExporters/AssetsExportingManager.h
+++ b/Source/Engine/ContentExporters/AssetsExportingManager.h
@@ -10,7 +10,7 @@
///
/// Assets Importing service allows to import or create new assets
///
-class AssetsExportingManager
+class FLAXENGINE_API AssetsExportingManager
{
public:
///
diff --git a/Source/Engine/ContentExporters/Types.h b/Source/Engine/ContentExporters/Types.h
index cfc341f37..a2095934f 100644
--- a/Source/Engine/ContentExporters/Types.h
+++ b/Source/Engine/ContentExporters/Types.h
@@ -26,7 +26,7 @@ typedef Function ExportAssetFunction;
///
/// Exporting asset context structure
///
-class ExportAssetContext : public NonCopyable
+class FLAXENGINE_API ExportAssetContext : public NonCopyable
{
public:
///
diff --git a/Source/Engine/ContentImporters/AssetsImportingManager.h b/Source/Engine/ContentImporters/AssetsImportingManager.h
index 2f8369a41..2930f8979 100644
--- a/Source/Engine/ContentImporters/AssetsImportingManager.h
+++ b/Source/Engine/ContentImporters/AssetsImportingManager.h
@@ -9,7 +9,7 @@
///
/// Assets Importing service allows to import or create new assets
///
-class AssetsImportingManager
+class FLAXENGINE_API AssetsImportingManager
{
public:
///
diff --git a/Source/Engine/ContentImporters/Types.h b/Source/Engine/ContentImporters/Types.h
index 05d1fc116..4ebf55583 100644
--- a/Source/Engine/ContentImporters/Types.h
+++ b/Source/Engine/ContentImporters/Types.h
@@ -28,7 +28,7 @@ typedef Function CreateAssetFunction;
///
/// Importing/creating asset context structure
///
-class CreateAssetContext : public NonCopyable
+class FLAXENGINE_API CreateAssetContext : public NonCopyable
{
private:
CreateAssetResult _applyChangesResult;
From cd7ad4e5f855c66d261eeedc57770ff6cbca672c Mon Sep 17 00:00:00 2001
From: Wojtek Figat
Date: Tue, 20 Jun 2023 15:17:46 +0200
Subject: [PATCH 11/65] Fix crash in particle effect
#1194
---
Source/Engine/Particles/ParticleEffect.cpp | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/Source/Engine/Particles/ParticleEffect.cpp b/Source/Engine/Particles/ParticleEffect.cpp
index 18bcbdd54..1d7fa18a1 100644
--- a/Source/Engine/Particles/ParticleEffect.cpp
+++ b/Source/Engine/Particles/ParticleEffect.cpp
@@ -299,17 +299,19 @@ void ParticleEffect::Stop()
void ParticleEffect::UpdateBounds()
{
BoundingBox bounds = BoundingBox::Empty;
- if (ParticleSystem && Instance.LastUpdateTime >= 0)
+ const auto particleSystem = ParticleSystem.Get();
+ if (particleSystem && Instance.LastUpdateTime >= 0)
{
- for (int32 j = 0; j < ParticleSystem->Tracks.Count(); j++)
+ for (int32 j = 0; j < particleSystem->Tracks.Count(); j++)
{
- const auto& track = ParticleSystem->Tracks[j];
+ const auto& track = particleSystem->Tracks[j];
if (track.Type != ParticleSystem::Track::Types::Emitter || track.Disabled)
continue;
- auto& emitter = ParticleSystem->Emitters[track.AsEmitter.Index];
- auto& data = Instance.Emitters[track.AsEmitter.Index];
- if (!emitter || emitter->Capacity == 0 || emitter->Graph.Layout.Size == 0)
+ const int32 emitterIndex = track.AsEmitter.Index;
+ ParticleEmitter* emitter = particleSystem->Emitters[emitterIndex].Get();
+ if (!emitter || emitter->Capacity == 0 || emitter->Graph.Layout.Size == 0 || Instance.Emitters.Count() <= emitterIndex)
continue;
+ auto& data = Instance.Emitters[emitterIndex];
BoundingBox emitterBounds;
if (emitter->GraphExecutorCPU.ComputeBounds(emitter, this, data, emitterBounds))
From 87e96a901758c6d1ba3a49813d28e3fa3d82f5f4 Mon Sep 17 00:00:00 2001
From: Ari Vuollet
Date: Tue, 20 Jun 2023 16:28:37 +0300
Subject: [PATCH 12/65] Fix native library lookup after hot reload
---
Source/Engine/Engine/NativeInterop.cs | 11 -----------
Source/Engine/Scripting/Runtime/DotNet.cpp | 3 ++-
2 files changed, 2 insertions(+), 12 deletions(-)
diff --git a/Source/Engine/Engine/NativeInterop.cs b/Source/Engine/Engine/NativeInterop.cs
index b33e4bcb6..faa19d060 100644
--- a/Source/Engine/Engine/NativeInterop.cs
+++ b/Source/Engine/Engine/NativeInterop.cs
@@ -58,19 +58,8 @@ namespace FlaxEngine.Interop
if (!loadedNativeLibraries.TryGetValue(libraryName, out IntPtr nativeLibrary))
{
if (!nativeLibraryPaths.TryGetValue(libraryName, out var nativeLibraryPath))
- {
nativeLibraryPath = libraryName;
- // Check if any of the loaded assemblies has matching native module filename
- foreach (var e in nativeLibraryPaths)
- {
- if (string.Equals(Path.GetFileNameWithoutExtension(e.Value), libraryName, StringComparison.Ordinal))
- {
- nativeLibraryPath = e.Value;
- break;
- }
- }
- }
nativeLibrary = NativeLibrary.Load(nativeLibraryPath, assembly, dllImportSearchPath);
loadedNativeLibraries.Add(libraryName, nativeLibrary);
assemblyOwnedNativeLibraries.Add(assembly, libraryName);
diff --git a/Source/Engine/Scripting/Runtime/DotNet.cpp b/Source/Engine/Scripting/Runtime/DotNet.cpp
index f2c5ee376..1736cc106 100644
--- a/Source/Engine/Scripting/Runtime/DotNet.cpp
+++ b/Source/Engine/Scripting/Runtime/DotNet.cpp
@@ -712,7 +712,8 @@ bool MAssembly::LoadImage(const String& assemblyPath, const StringView& nativePa
// Provide new path of hot-reloaded native library path for managed DllImport
if (nativePath.HasChars())
{
- RegisterNativeLibrary(assemblyPathAnsi.Get(), StringAnsi(nativePath).Get());
+ StringAnsi nativeName = _name.EndsWith(".CSharp") ? StringAnsi(_name.Get(), _name.Length() - 7) : StringAnsi(_name);
+ RegisterNativeLibrary(nativeName.Get(), StringAnsi(nativePath).Get());
}
_hasCachedClasses = false;
From d3073f52518f6d6dbd3c2e2616977904c320dd61 Mon Sep 17 00:00:00 2001
From: Ari Vuollet
Date: Tue, 20 Jun 2023 21:47:05 +0300
Subject: [PATCH 13/65] Release custom assets before scripting hot reload
---
Source/Engine/Scripting/Scripting.cpp | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/Source/Engine/Scripting/Scripting.cpp b/Source/Engine/Scripting/Scripting.cpp
index 9bddc333e..bbd109cd1 100644
--- a/Source/Engine/Scripting/Scripting.cpp
+++ b/Source/Engine/Scripting/Scripting.cpp
@@ -640,9 +640,9 @@ void Scripting::Reload(bool canTriggerSceneReload)
MCore::GC::WaitForPendingFinalizers();
// Destroy objects from game assemblies (eg. not released objects that might crash if persist in memory after reload)
+ const auto flaxModule = GetBinaryModuleFlaxEngine();
_objectsLocker.Lock();
{
- const auto flaxModule = GetBinaryModuleFlaxEngine();
for (auto i = _objectsDictionary.Begin(); i.IsNotEnd(); ++i)
{
auto obj = i->Value;
@@ -657,6 +657,15 @@ void Scripting::Reload(bool canTriggerSceneReload)
}
_objectsLocker.Unlock();
+ // Release assets sourced from game assemblies
+ for (auto asset : Content::GetAssets())
+ {
+ if (asset->GetTypeHandle().Module == flaxModule)
+ continue;
+
+ asset->DeleteObjectNow();
+ }
+
// Unload all game modules
LOG(Info, "Unloading game binary modules");
auto modules = BinaryModule::GetModules();
From 64a7985376109c646fd9b38d6d01a7df4364b278 Mon Sep 17 00:00:00 2001
From: Wojtek Figat
Date: Tue, 20 Jun 2023 21:59:36 +0200
Subject: [PATCH 14/65] Fix `GridGizmo` to render before transparency in Editor
viewport
#1196
---
Source/Editor/Gizmo/GridGizmo.cs | 137 +++++++++++++++++++-----------
Source/Engine/Debug/DebugDraw.cpp | 8 +-
2 files changed, 91 insertions(+), 54 deletions(-)
diff --git a/Source/Editor/Gizmo/GridGizmo.cs b/Source/Editor/Gizmo/GridGizmo.cs
index a36bb8da1..4b8dec2de 100644
--- a/Source/Editor/Gizmo/GridGizmo.cs
+++ b/Source/Editor/Gizmo/GridGizmo.cs
@@ -12,19 +12,98 @@ namespace FlaxEditor.Gizmo
[HideInEditor]
public class GridGizmo : GizmoBase
{
- private bool _enabled = true;
+ [HideInEditor]
+ private sealed class Renderer : PostProcessEffect
+ {
+ private IntPtr _debugDrawContext;
+
+ public Renderer()
+ {
+ Order = -100;
+ UseSingleTarget = true;
+ Location = PostProcessEffectLocation.BeforeForwardPass;
+ }
+
+ ~Renderer()
+ {
+ if (_debugDrawContext != IntPtr.Zero)
+ {
+ DebugDraw.FreeContext(_debugDrawContext);
+ _debugDrawContext = IntPtr.Zero;
+ }
+ }
+
+ public override void Render(GPUContext context, ref RenderContext renderContext, GPUTexture input, GPUTexture output)
+ {
+ Profiler.BeginEventGPU("Editor Grid");
+
+ if (_debugDrawContext == IntPtr.Zero)
+ _debugDrawContext = DebugDraw.AllocateContext();
+ DebugDraw.SetContext(_debugDrawContext);
+ DebugDraw.UpdateContext(_debugDrawContext, 1.0f / Mathf.Max(Engine.FramesPerSecond, 1));
+
+ var viewPos = (Vector3)renderContext.View.Position;
+ var plane = new Plane(Vector3.Zero, Vector3.UnitY);
+ var dst = CollisionsHelper.DistancePlanePoint(ref plane, ref viewPos);
+
+ float space, size;
+ if (dst <= 500.0f)
+ {
+ space = 50;
+ size = 8000;
+ }
+ else if (dst <= 2000.0f)
+ {
+ space = 100;
+ size = 8000;
+ }
+ else
+ {
+ space = 1000;
+ size = 100000;
+ }
+
+ Color color = Color.Gray * 0.7f;
+ int count = (int)(size / space);
+
+ Vector3 start = new Vector3(0, 0, size * -0.5f);
+ Vector3 end = new Vector3(0, 0, size * 0.5f);
+
+ for (int i = 0; i <= count; i++)
+ {
+ start.X = end.X = i * space + start.Z;
+ DebugDraw.DrawLine(start, end, color);
+ }
+
+ start = new Vector3(size * -0.5f, 0, 0);
+ end = new Vector3(size * 0.5f, 0, 0);
+
+ for (int i = 0; i <= count; i++)
+ {
+ start.Z = end.Z = i * space + start.X;
+ DebugDraw.DrawLine(start, end, color);
+ }
+
+ DebugDraw.Draw(ref renderContext, input.View(), null, true);
+ DebugDraw.SetContext(IntPtr.Zero);
+
+ Profiler.EndEventGPU();
+ }
+ }
+
+ private Renderer _renderer;
///
/// Gets or sets a value indicating whether this is enabled.
///
public bool Enabled
{
- get => _enabled;
+ get => _renderer.Enabled;
set
{
- if (_enabled != value)
+ if (_renderer.Enabled != value)
{
- _enabled = value;
+ _renderer.Enabled = value;
EnabledChanged?.Invoke(this);
}
}
@@ -42,55 +121,13 @@ namespace FlaxEditor.Gizmo
public GridGizmo(IGizmoOwner owner)
: base(owner)
{
+ _renderer = new Renderer();
+ owner.RenderTask.AddCustomPostFx(_renderer);
}
- ///
- public override void Draw(ref RenderContext renderContext)
+ ~GridGizmo()
{
- if (!Enabled)
- return;
-
- var viewPos = Owner.ViewPosition;
- var plane = new Plane(Vector3.Zero, Vector3.UnitY);
- var dst = CollisionsHelper.DistancePlanePoint(ref plane, ref viewPos);
-
- float space, size;
- if (dst <= 500.0f)
- {
- space = 50;
- size = 8000;
- }
- else if (dst <= 2000.0f)
- {
- space = 100;
- size = 8000;
- }
- else
- {
- space = 1000;
- size = 100000;
- }
-
- Color color = Color.Gray * 0.7f;
- int count = (int)(size / space);
-
- Vector3 start = new Vector3(0, 0, size * -0.5f);
- Vector3 end = new Vector3(0, 0, size * 0.5f);
-
- for (int i = 0; i <= count; i++)
- {
- start.X = end.X = i * space + start.Z;
- DebugDraw.DrawLine(start, end, color);
- }
-
- start = new Vector3(size * -0.5f, 0, 0);
- end = new Vector3(size * 0.5f, 0, 0);
-
- for (int i = 0; i <= count; i++)
- {
- start.Z = end.Z = i * space + start.X;
- DebugDraw.DrawLine(start, end, color);
- }
+ FlaxEngine.Object.Destroy(ref _renderer);
}
}
}
diff --git a/Source/Engine/Debug/DebugDraw.cpp b/Source/Engine/Debug/DebugDraw.cpp
index 891792d79..97422b9e2 100644
--- a/Source/Engine/Debug/DebugDraw.cpp
+++ b/Source/Engine/Debug/DebugDraw.cpp
@@ -466,7 +466,7 @@ inline void DrawText3D(const DebugText3D& t, const RenderContext& renderContext,
Matrix::Multiply(fw, vp, m);
Render2D::Begin(context, target, depthBuffer, viewport, m);
const StringView text(t.Text.Get(), t.Text.Count() - 1);
- Render2D::DrawText(DebugDrawFont->CreateFont(t.Size), text, t.Color, Vector2::Zero);
+ Render2D::DrawText(DebugDrawFont->CreateFont((float)t.Size), text, t.Color, Vector2::Zero);
Render2D::End();
}
@@ -777,7 +777,7 @@ void DebugDraw::Draw(RenderContext& renderContext, GPUTextureView* target, GPUTe
context->BindSR(0, renderContext.Buffers->DepthBuffer);
const bool enableDepthWrite = data.EnableDepthTest;
- context->SetRenderTarget(depthBuffer ? depthBuffer : *renderContext.Buffers->DepthBuffer, target);
+ context->SetRenderTarget(depthBuffer ? depthBuffer : (data.EnableDepthTest ? nullptr : renderContext.Buffers->DepthBuffer->View()), target);
// Lines
if (depthTestLines.VertexCount)
@@ -859,12 +859,12 @@ void DebugDraw::Draw(RenderContext& renderContext, GPUTextureView* target, GPUTe
for (auto& t : Context->DebugDrawDefault.DefaultText2D)
{
const StringView text(t.Text.Get(), t.Text.Count() - 1);
- Render2D::DrawText(DebugDrawFont->CreateFont(t.Size), text, t.Color, t.Position);
+ Render2D::DrawText(DebugDrawFont->CreateFont((float)t.Size), text, t.Color, t.Position);
}
for (auto& t : Context->DebugDrawDefault.OneFrameText2D)
{
const StringView text(t.Text.Get(), t.Text.Count() - 1);
- Render2D::DrawText(DebugDrawFont->CreateFont(t.Size), text, t.Color, t.Position);
+ Render2D::DrawText(DebugDrawFont->CreateFont((float)t.Size), text, t.Color, t.Position);
}
Render2D::End();
}
From 74760a76614345b3c1c172e1ffd4108e047473ca Mon Sep 17 00:00:00 2001
From: Ari Vuollet
Date: Wed, 21 Jun 2023 13:14:27 +0300
Subject: [PATCH 15/65] Add support for writing UTF-8 files in
FileBase::WriteAllText
---
Source/Engine/Core/Encoding.h | 2 +-
Source/Engine/Platform/Base/FileBase.cpp | 39 ++++++++++++++++++++++++
2 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/Source/Engine/Core/Encoding.h b/Source/Engine/Core/Encoding.h
index 6ac716ba8..3e74144e2 100644
--- a/Source/Engine/Core/Encoding.h
+++ b/Source/Engine/Core/Encoding.h
@@ -4,4 +4,4 @@
#include "Enums.h"
-DECLARE_ENUM_3(Encoding, ANSI, Unicode, UnicodeBigEndian);
+DECLARE_ENUM_4(Encoding, ANSI, Unicode, UnicodeBigEndian, UTF8);
diff --git a/Source/Engine/Platform/Base/FileBase.cpp b/Source/Engine/Platform/Base/FileBase.cpp
index f45685c7f..4794e2452 100644
--- a/Source/Engine/Platform/Base/FileBase.cpp
+++ b/Source/Engine/Platform/Base/FileBase.cpp
@@ -309,6 +309,45 @@ bool FileBase::WriteAllText(const StringView& path, const Char* data, int32 leng
return WriteAllBytes(path, tmp.Get(), tmp.Count());
}
+ case Encoding::UTF8:
+ {
+ Array tmp;
+ tmp.SetCapacity(length);
+
+ for (int i=0; i> 6));
+ tmp.Add(0x80 | (c & 0x3F));
+ }
+ else if (c < 0xD800 || c >= 0xE000)
+ {
+ tmp.Add(0xE0 | (c >> 12));
+ tmp.Add(0x80 | ((c >> 6) & 0x3F));
+ tmp.Add(0x80 | (c & 0x3F));
+ }
+ else // Surrogate pair
+ {
+ ++i;
+ if (i >= length)
+ return true;
+
+ uint32 p = 0x10000 + (((c & 0x3FF) << 10) | (data[i] & 0x3FF));
+ tmp.Add(0xF0 | (p >> 18));
+ tmp.Add(0x80 | ((p >> 12) & 0x3F));
+ tmp.Add(0x80 | ((p >> 6) & 0x3F));
+ tmp.Add(0x80 | (p & 0x3F));
+ }
+ }
+
+ return WriteAllBytes(path, tmp.Get(), tmp.Count());
+ }
default:
return true;
}
From 83485d2f528cfeb52c12ef7193a22d0dbcffa3c8 Mon Sep 17 00:00:00 2001
From: Ari Vuollet
Date: Wed, 21 Jun 2023 13:16:49 +0300
Subject: [PATCH 16/65] Write generated build configuration files in UTF-8
Git seems to have issues with handling UTF-16 encoded files, so it would
be more appropriate to write the generated files with more common UTF-8
encoding instead.
---
Source/Editor/Editor.cpp | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/Source/Editor/Editor.cpp b/Source/Editor/Editor.cpp
index 8a92d11f4..527bfeb6d 100644
--- a/Source/Editor/Editor.cpp
+++ b/Source/Editor/Editor.cpp
@@ -184,7 +184,7 @@ bool Editor::CheckProjectUpgrade()
" BuildNativeCode = false;\n"
" }}\n"
"}}\n"
- ), codeName), Encoding::Unicode);
+ ), codeName), Encoding::UTF8);
if (useEditorModule)
{
File::WriteAllText(gameEditorModuleFolder / String::Format(TEXT("{0}Editor.Build.cs"), codeName), String::Format(TEXT(
@@ -211,7 +211,7 @@ bool Editor::CheckProjectUpgrade()
" BuildNativeCode = false;\n"
" }}\n"
"}}\n"
- ), codeName), Encoding::Unicode);
+ ), codeName), Encoding::UTF8);
}
// Generate target files
@@ -229,7 +229,7 @@ bool Editor::CheckProjectUpgrade()
" Modules.Add(\"{0}\");\n"
" }}\n"
"}}\n"
- ), codeName), Encoding::Unicode);
+ ), codeName), Encoding::UTF8);
const String editorTargetGameEditorModule = useEditorModule ? String::Format(TEXT(" Modules.Add(\"{0}Editor\");\n"), codeName) : String::Empty;
File::WriteAllText(sourceFolder / String::Format(TEXT("{0}EditorTarget.Build.cs"), codeName), String::Format(TEXT(
"using Flax.Build;\n"
@@ -246,7 +246,7 @@ bool Editor::CheckProjectUpgrade()
"{1}"
" }}\n"
"}}\n"
- ), codeName, editorTargetGameEditorModule), Encoding::Unicode);
+ ), codeName, editorTargetGameEditorModule), Encoding::UTF8);
// Generate new project file
Project->ProjectPath = root / String::Format(TEXT("{0}.flaxproj"), codeName);
@@ -454,7 +454,7 @@ int32 Editor::LoadProduct()
" // Reference the modules for game\n"
" Modules.Add(\"Game\");\n"
" }\n"
- "}\n"), Encoding::Unicode);
+ "}\n"), Encoding::UTF8);
failed |= File::WriteAllText(projectPath / TEXT("Source/GameEditorTarget.Build.cs"),TEXT(
"using Flax.Build;\n"
"\n"
@@ -468,7 +468,7 @@ int32 Editor::LoadProduct()
" // Reference the modules for editor\n"
" Modules.Add(\"Game\");\n"
" }\n"
- "}\n"), Encoding::Unicode);
+ "}\n"), Encoding::UTF8);
failed |= File::WriteAllText(projectPath / TEXT("Source/Game/Game.Build.cs"),TEXT(
"using Flax.Build;\n"
"using Flax.Build.NativeCpp;\n"
@@ -496,7 +496,7 @@ int32 Editor::LoadProduct()
" // To add C++ define use: options.PublicDefinitions.Add(\"COMPILE_WITH_FLAX\");\n"
" // To learn more see scripting documentation.\n"
" }\n"
- "}\n"), Encoding::Unicode);
+ "}\n"), Encoding::UTF8);
if (failed)
return 12;
}
From 9c2a04aa213ac231782df126e1dc3f91c529789c Mon Sep 17 00:00:00 2001
From: Chandler Cox
Date: Wed, 21 Jun 2023 07:24:37 -0500
Subject: [PATCH 17/65] Add eol=lf to gitattribute
---
.gitattributes | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.gitattributes b/.gitattributes
index f84404f19..df7d89342 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,5 +1,5 @@
# Set the default behavior, in case people don't have core.autocrlf set.
-* text=auto
+* text=auto eol=lf
# Explicitly declare text files you want to always be normalized and converted to native line endings on checkout.
*.c text diff=cpp
From 875dd30d57dd064498032da1d1b1a2ab7f8a5faf Mon Sep 17 00:00:00 2001
From: Ruan Lucas <79365912+RuanLucasGD@users.noreply.github.com>
Date: Wed, 21 Jun 2023 21:27:38 -0400
Subject: [PATCH 18/65] add optional parameter to find only active actors on
Level.FinActors(tag)
---
Source/Engine/Level/Level.cpp | 12 +++++++-----
Source/Engine/Level/Level.h | 3 ++-
2 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/Source/Engine/Level/Level.cpp b/Source/Engine/Level/Level.cpp
index ae617b980..7b6a3844f 100644
--- a/Source/Engine/Level/Level.cpp
+++ b/Source/Engine/Level/Level.cpp
@@ -740,12 +740,14 @@ Actor* FindActorRecursive(Actor* node, const Tag& tag)
return result;
}
-void FindActorsRecursive(Actor* node, const Tag& tag, Array& result)
+void FindActorsRecursive(Actor* node, const Tag& tag, const bool activeOnly, Array& result)
{
+ if (activeOnly && !node->GetIsActive())
+ return;
if (node->HasTag(tag))
result.Add(node);
for (Actor* child : node->Children)
- FindActorsRecursive(child, tag, result);
+ FindActorsRecursive(child, tag, activeOnly, result);
}
void FindActorsRecursiveByParentTags(Actor* node, const Array& tags, Array& result)
@@ -785,19 +787,19 @@ void FindActorRecursive(Actor* node, const Tag& tag, Array& result)
FindActorRecursive(child, tag, result);
}
-Array Level::FindActors(const Tag& tag, Actor* root)
+Array Level::FindActors(const Tag& tag, const bool activeOnly, Actor* root)
{
PROFILE_CPU();
Array result;
if (root)
{
- FindActorsRecursive(root, tag, result);
+ FindActorsRecursive(root, tag, activeOnly, result);
}
else
{
ScopeLock lock(ScenesLock);
for (Scene* scene : Scenes)
- FindActorsRecursive(scene, tag, result);
+ FindActorsRecursive(scene, tag, activeOnly, result);
}
return result;
}
diff --git a/Source/Engine/Level/Level.h b/Source/Engine/Level/Level.h
index e27b81bb9..a7524b40a 100644
--- a/Source/Engine/Level/Level.h
+++ b/Source/Engine/Level/Level.h
@@ -494,9 +494,10 @@ public:
/// Tries to find the actors with the given tag (returns all found).
///
/// The tag of the actor to search for.
+ /// Find only active actors.
/// The custom root actor to start searching from (hierarchical), otherwise null to search all loaded scenes.
/// Found actors or empty if none.
- API_FUNCTION() static Array FindActors(const Tag& tag, Actor* root = nullptr);
+ API_FUNCTION() static Array FindActors(const Tag& tag, const bool activeOnly = false, Actor* root = nullptr);
///
/// Search actors using a parent parentTag.
From 072d70722c640b563270c91070f37584c151ffb7 Mon Sep 17 00:00:00 2001
From: Ruan Lucas <79365912+RuanLucasGD@users.noreply.github.com>
Date: Wed, 21 Jun 2023 21:38:22 -0400
Subject: [PATCH 19/65] add optional parameter to find only active actors on
Level.FindActorsByParentTag
---
Source/Engine/Level/Level.cpp | 14 ++++++++------
Source/Engine/Level/Level.h | 3 ++-
2 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/Source/Engine/Level/Level.cpp b/Source/Engine/Level/Level.cpp
index 7b6a3844f..ab8a9bbfe 100644
--- a/Source/Engine/Level/Level.cpp
+++ b/Source/Engine/Level/Level.cpp
@@ -750,8 +750,10 @@ void FindActorsRecursive(Actor* node, const Tag& tag, const bool activeOnly, Arr
FindActorsRecursive(child, tag, activeOnly, result);
}
-void FindActorsRecursiveByParentTags(Actor* node, const Array& tags, Array& result)
+void FindActorsRecursiveByParentTags(Actor* node, const Array& tags, const bool activeOnly, Array& result)
{
+ if (activeOnly && !node->GetIsActive())
+ return;
for (Tag tag : tags)
{
if (node->HasTag(tag))
@@ -761,7 +763,7 @@ void FindActorsRecursiveByParentTags(Actor* node, const Array& tags, Array<
}
}
for (Actor* child : node->Children)
- FindActorsRecursiveByParentTags(child, tags, result);
+ FindActorsRecursiveByParentTags(child, tags, activeOnly, result);
}
Actor* Level::FindActor(const Tag& tag, Actor* root)
@@ -804,7 +806,7 @@ Array Level::FindActors(const Tag& tag, const bool activeOnly, Actor* ro
return result;
}
-Array Level::FindActorsByParentTag(const Tag& parentTag, Actor* root)
+Array Level::FindActorsByParentTag(const Tag& parentTag, const bool activeOnly, Actor* root)
{
PROFILE_CPU();
Array result;
@@ -816,19 +818,19 @@ Array Level::FindActorsByParentTag(const Tag& parentTag, Actor* root)
}
if (subTags.Count() == 1)
{
- result = FindActors(subTags[0], root);
+ result = FindActors(subTags[0], activeOnly, root);
return result;
}
if (root)
{
- FindActorsRecursiveByParentTags(root, subTags, result);
+ FindActorsRecursiveByParentTags(root, subTags, activeOnly, result);
}
else
{
ScopeLock lock(ScenesLock);
for (Scene* scene : Scenes)
- FindActorsRecursiveByParentTags(scene, subTags, result);
+ FindActorsRecursiveByParentTags(scene, subTags, activeOnly, result);
}
return result;
diff --git a/Source/Engine/Level/Level.h b/Source/Engine/Level/Level.h
index a7524b40a..9a041bda9 100644
--- a/Source/Engine/Level/Level.h
+++ b/Source/Engine/Level/Level.h
@@ -503,9 +503,10 @@ public:
/// Search actors using a parent parentTag.
///
/// The tag to search actors with subtags belonging to this tag
+ /// Find only active actors.
/// The custom root actor to start searching from (hierarchical), otherwise null to search all loaded scenes.
/// Returns all actors that have subtags belonging to the given parent parentTag
- API_FUNCTION() static Array FindActorsByParentTag(const Tag& parentTag, Actor* root = nullptr);
+ API_FUNCTION() static Array FindActorsByParentTag(const Tag& parentTag, const bool activeOnly = false, Actor* root = nullptr);
private:
// Actor API
From 028ccfca2e3b435e8da331750c8707cedc1b4cc8 Mon Sep 17 00:00:00 2001
From: Wiktor Kocielski <118038102+Withaust@users.noreply.github.com>
Date: Fri, 23 Jun 2023 13:14:59 +0300
Subject: [PATCH 20/65] Update NetworkReplicationNode::AddObject
---
Source/Engine/Networking/NetworkReplicationHierarchy.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Source/Engine/Networking/NetworkReplicationHierarchy.cpp b/Source/Engine/Networking/NetworkReplicationHierarchy.cpp
index 99a43a34a..32b7978d0 100644
--- a/Source/Engine/Networking/NetworkReplicationHierarchy.cpp
+++ b/Source/Engine/Networking/NetworkReplicationHierarchy.cpp
@@ -49,7 +49,7 @@ bool NetworkReplicationHierarchyUpdateResult::GetClientLocation(int32 clientInde
void NetworkReplicationNode::AddObject(NetworkReplicationHierarchyObject obj)
{
- if (obj.ReplicationFPS > 0.0f)
+ if (obj.ReplicationFPS > ZeroTolerance) // > 0
{
// Randomize initial replication update to spread rep rates more evenly for large scenes that register all objects within the same frame
obj.ReplicationUpdatesLeft = NetworkReplicationNodeObjectCounter++ % Math::Clamp(Math::RoundToInt(NetworkManager::NetworkFPS / obj.ReplicationFPS), 1, 60);
From 9b570a46d2b1b894f6c019f3aea57f687a2dbea7 Mon Sep 17 00:00:00 2001
From: Wojtek Figat
Date: Fri, 23 Jun 2023 21:28:16 +0200
Subject: [PATCH 21/65] Codestyle tweak
---
Source/Editor/Gizmo/GridGizmo.cs | 3 +++
Source/Engine/Platform/Base/FileBase.cpp | 2 +-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/Source/Editor/Gizmo/GridGizmo.cs b/Source/Editor/Gizmo/GridGizmo.cs
index 4b8dec2de..8b4f49986 100644
--- a/Source/Editor/Gizmo/GridGizmo.cs
+++ b/Source/Editor/Gizmo/GridGizmo.cs
@@ -125,6 +125,9 @@ namespace FlaxEditor.Gizmo
owner.RenderTask.AddCustomPostFx(_renderer);
}
+ ///
+ /// Destructor.
+ ///
~GridGizmo()
{
FlaxEngine.Object.Destroy(ref _renderer);
diff --git a/Source/Engine/Platform/Base/FileBase.cpp b/Source/Engine/Platform/Base/FileBase.cpp
index 4794e2452..eb11292b0 100644
--- a/Source/Engine/Platform/Base/FileBase.cpp
+++ b/Source/Engine/Platform/Base/FileBase.cpp
@@ -314,7 +314,7 @@ bool FileBase::WriteAllText(const StringView& path, const Char* data, int32 leng
Array tmp;
tmp.SetCapacity(length);
- for (int i=0; i
Date: Fri, 23 Jun 2023 22:22:50 +0200
Subject: [PATCH 22/65] Fix missing collision events generated during
`CharacterController::Move`
#1200
---
.../Physics/PhysX/PhysicsBackendPhysX.cpp | 56 +++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp b/Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp
index 41430fb4d..69dfeaa27 100644
--- a/Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp
+++ b/Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp
@@ -203,6 +203,60 @@ class CharacterControllerFilterPhysX : public PxControllerFilterCallback
}
};
+class CharacterControllerHitReportPhysX : public PxUserControllerHitReport
+{
+ void onHit(const PxControllerHit& hit, Collision& c)
+ {
+ ASSERT_LOW_LAYER(c.ThisActor && c.OtherActor);
+ c.Impulse = Vector3::Zero;
+ c.ThisVelocity = P2C(hit.dir) * hit.length;
+ c.OtherVelocity = Vector3::Zero;
+ c.ContactsCount = 1;
+ ContactPoint& contact = c.Contacts[0];
+ contact.Point = P2C(hit.worldPos);
+ contact.Normal = P2C(hit.worldNormal);
+ contact.Separation = 0.0f;
+
+ //auto simulationEventCallback = static_cast(hit.controller->getScene()->getSimulationEventCallback());
+ //simulationEventCallback->Collisions[SimulationEventCallback::CollidersPair(c.ThisActor, c.OtherActor)] = c;
+ // TODO: build additional list for hit-only events to properly send enter/exit pairs instead of spamming every frame whether controller executes move
+
+ // Single-hit collision
+ c.ThisActor->OnCollisionEnter(c);
+ c.SwapObjects();
+ c.ThisActor->OnCollisionEnter(c);
+ c.SwapObjects();
+ c.ThisActor->OnCollisionExit(c);
+ c.SwapObjects();
+ c.ThisActor->OnCollisionExit(c);
+ }
+
+ void onShapeHit(const PxControllerShapeHit& hit) override
+ {
+ Collision c;
+ PxShape* controllerShape;
+ hit.controller->getActor()->getShapes(&controllerShape, 1);
+ c.ThisActor = static_cast(controllerShape->userData);
+ c.OtherActor = static_cast(hit.shape->userData);
+ onHit(hit, c);
+ }
+
+ void onControllerHit(const PxControllersHit& hit) override
+ {
+ Collision c;
+ PxShape* controllerShape;
+ hit.controller->getActor()->getShapes(&controllerShape, 1);
+ c.ThisActor = static_cast(controllerShape->userData);
+ hit.other->getActor()->getShapes(&controllerShape, 1);
+ c.OtherActor = static_cast(controllerShape->userData);
+ onHit(hit, c);
+ }
+
+ void onObstacleHit(const PxControllerObstacleHit& hit) override
+ {
+ }
+};
+
#if WITH_VEHICLE
class WheelFilterPhysX : public PxQueryFilterCallback
@@ -383,6 +437,7 @@ namespace
QueryFilterPhysX QueryFilter;
CharacterQueryFilterPhysX CharacterQueryFilter;
CharacterControllerFilterPhysX CharacterControllerFilter;
+ CharacterControllerHitReportPhysX CharacterControllerHitReport;
Dictionary> SceneOrigins;
CriticalSection FlushLocker;
@@ -2475,6 +2530,7 @@ void* PhysicsBackend::CreateController(void* scene, IPhysicsActor* actor, Physic
const Vector3 sceneOrigin = SceneOrigins[scenePhysX->Scene];
PxCapsuleControllerDesc desc;
desc.userData = actor;
+ desc.reportCallback = &CharacterControllerHitReport;
desc.contactOffset = Math::Max(contactOffset, ZeroTolerance);
desc.position = PxExtendedVec3(position.X - sceneOrigin.X, position.Y - sceneOrigin.Y, position.Z - sceneOrigin.Z);
desc.slopeLimit = Math::Cos(slopeLimit * DegreesToRadians);
From 1d8ae580b71eb3db23d55135f2f634014cd78c12 Mon Sep 17 00:00:00 2001
From: Chandler Cox
Date: Sat, 24 Jun 2023 12:05:51 -0500
Subject: [PATCH 23/65] Add Realloc with alignment.
---
Source/Engine/Core/Memory/Memory.h | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/Source/Engine/Core/Memory/Memory.h b/Source/Engine/Core/Memory/Memory.h
index 770fd2c22..a35929ed2 100644
--- a/Source/Engine/Core/Memory/Memory.h
+++ b/Source/Engine/Core/Memory/Memory.h
@@ -36,6 +36,32 @@ namespace AllocatorExt
return result;
}
+ ///
+ /// Reallocates block of the memory.
+ ///
+ ///
+ /// A pointer to the memory block to reallocate.
+ /// The size of the new allocation (in bytes).
+ /// The memory alignment (in bytes). Must be an integer power of 2.
+ /// The pointer to the allocated chunk of the memory. The pointer is a multiple of alignment.
+ inline void* ReallocWithAlignment(void* ptr, uint64 newSize, uint64 alignment)
+ {
+ if (newSize == 0)
+ {
+ Allocator::Free(ptr);
+ return nullptr;
+ }
+ if (!ptr)
+ return Allocator::Allocate(newSize, alignment);
+ void* result = Allocator::Allocate(newSize, alignment);
+ if (result)
+ {
+ Platform::MemoryCopy(result, ptr, newSize);
+ Allocator::Free(ptr);
+ }
+ return result;
+ }
+
///
/// Reallocates block of the memory.
///
From 9282bcfbbfaca4ed83bb2355f1292f40053df305 Mon Sep 17 00:00:00 2001
From: Wojtek Figat
Date: Sun, 25 Jun 2023 21:24:30 +0200
Subject: [PATCH 24/65] Fix crash due to invalid RPC codegen for enum value
type variable
---
Source/Tools/Flax.Build/Utilities/MonoCecil.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Source/Tools/Flax.Build/Utilities/MonoCecil.cs b/Source/Tools/Flax.Build/Utilities/MonoCecil.cs
index 0301e33d2..188327931 100644
--- a/Source/Tools/Flax.Build/Utilities/MonoCecil.cs
+++ b/Source/Tools/Flax.Build/Utilities/MonoCecil.cs
@@ -249,7 +249,7 @@ namespace Flax.Build
public static void GetType(this ModuleDefinition module, string fullName, out TypeReference type)
{
- if (!module.TryGetTypeReference(fullName, out type))
+ //if (!module.TryGetTypeReference(fullName, out type)) // TODO: this seams to return 'FlaxEngine.Networking.NetworkManagerMode' as a Class instead of Enum
{
// Do manual search
foreach (var a in module.AssemblyReferences)
From cbd1e5c837c0c28a81ddf2e7dc2e2a82bf9a30cc Mon Sep 17 00:00:00 2001
From: Wiktor Kocielski
Date: Sun, 25 Jun 2023 23:39:59 +0300
Subject: [PATCH 25/65] Add NetworkReplicationNode::GetObject
---
.../Engine/Networking/NetworkReplicationHierarchy.cpp | 11 +++++++++++
.../Engine/Networking/NetworkReplicationHierarchy.h | 8 ++++++++
2 files changed, 19 insertions(+)
diff --git a/Source/Engine/Networking/NetworkReplicationHierarchy.cpp b/Source/Engine/Networking/NetworkReplicationHierarchy.cpp
index 32b7978d0..364e4f7dd 100644
--- a/Source/Engine/Networking/NetworkReplicationHierarchy.cpp
+++ b/Source/Engine/Networking/NetworkReplicationHierarchy.cpp
@@ -63,6 +63,17 @@ bool NetworkReplicationNode::RemoveObject(ScriptingObject* obj)
return !Objects.Remove(obj);
}
+bool NetworkReplicationNode::GetObject(ScriptingObject* obj, NetworkReplicationHierarchyObject& result)
+{
+ const int32 index = Objects.Find(obj);
+ if (index != -1)
+ {
+ result = Objects[index];
+ return true;
+ }
+ return false;
+}
+
bool NetworkReplicationNode::DirtyObject(ScriptingObject* obj)
{
const int32 index = Objects.Find(obj);
diff --git a/Source/Engine/Networking/NetworkReplicationHierarchy.h b/Source/Engine/Networking/NetworkReplicationHierarchy.h
index 36701c15d..1260859a5 100644
--- a/Source/Engine/Networking/NetworkReplicationHierarchy.h
+++ b/Source/Engine/Networking/NetworkReplicationHierarchy.h
@@ -200,6 +200,14 @@ API_CLASS(Abstract, Namespace = "FlaxEngine.Networking") class FLAXENGINE_API Ne
/// True on successful removal, otherwise false.
API_FUNCTION() virtual bool RemoveObject(ScriptingObject* obj);
+ ///
+ /// Gets object from the hierarchy.
+ ///
+ /// The object to get.
+ /// The hierarchy object to retrieve.
+ /// True on successful retrieval, otherwise false.
+ API_FUNCTION() bool GetObject(ScriptingObject* obj, NetworkReplicationHierarchyObject& result);
+
///
/// Force replicates the object during the next update. Resets any internal tracking state to force the synchronization.
///
From 65397621e90138ce9e2b6992cbb1fcd409954321 Mon Sep 17 00:00:00 2001
From: Wiktor Kocielski
Date: Mon, 26 Jun 2023 17:12:48 +0300
Subject: [PATCH 26/65] Make GetObject virtual and implement for Grid
---
.../Networking/NetworkReplicationHierarchy.cpp | 12 ++++++++++++
.../Engine/Networking/NetworkReplicationHierarchy.h | 3 ++-
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/Source/Engine/Networking/NetworkReplicationHierarchy.cpp b/Source/Engine/Networking/NetworkReplicationHierarchy.cpp
index 364e4f7dd..e95a06423 100644
--- a/Source/Engine/Networking/NetworkReplicationHierarchy.cpp
+++ b/Source/Engine/Networking/NetworkReplicationHierarchy.cpp
@@ -186,6 +186,18 @@ bool NetworkReplicationGridNode::RemoveObject(ScriptingObject* obj)
return false;
}
+bool NetworkReplicationGridNode::GetObject(ScriptingObject* obj, NetworkReplicationHierarchyObject& result)
+{
+ for (const auto& e : _children)
+ {
+ if (e.Value.Node->GetObject(obj, result))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
void NetworkReplicationGridNode::Update(NetworkReplicationHierarchyUpdateResult* result)
{
CHECK(result);
diff --git a/Source/Engine/Networking/NetworkReplicationHierarchy.h b/Source/Engine/Networking/NetworkReplicationHierarchy.h
index 1260859a5..ae482dfa6 100644
--- a/Source/Engine/Networking/NetworkReplicationHierarchy.h
+++ b/Source/Engine/Networking/NetworkReplicationHierarchy.h
@@ -206,7 +206,7 @@ API_CLASS(Abstract, Namespace = "FlaxEngine.Networking") class FLAXENGINE_API Ne
/// The object to get.
/// The hierarchy object to retrieve.
/// True on successful retrieval, otherwise false.
- API_FUNCTION() bool GetObject(ScriptingObject* obj, NetworkReplicationHierarchyObject& result);
+ API_FUNCTION() virtual bool GetObject(ScriptingObject* obj, NetworkReplicationHierarchyObject& result);
///
/// Force replicates the object during the next update. Resets any internal tracking state to force the synchronization.
@@ -255,6 +255,7 @@ public:
void AddObject(NetworkReplicationHierarchyObject obj) override;
bool RemoveObject(ScriptingObject* obj) override;
+ bool GetObject(ScriptingObject* obj, NetworkReplicationHierarchyObject& result) override;
void Update(NetworkReplicationHierarchyUpdateResult* result) override;
};
From 60137059889fa164c3897288ee3a3fffe5824e8d Mon Sep 17 00:00:00 2001
From: Wiktor Kocielski
Date: Mon, 26 Jun 2023 17:32:19 +0300
Subject: [PATCH 27/65] Implement object to cell caching for the grid
---
.../NetworkReplicationHierarchy.cpp | 34 ++++++++++++-------
.../Networking/NetworkReplicationHierarchy.h | 1 +
2 files changed, 23 insertions(+), 12 deletions(-)
diff --git a/Source/Engine/Networking/NetworkReplicationHierarchy.cpp b/Source/Engine/Networking/NetworkReplicationHierarchy.cpp
index e95a06423..5097b6a26 100644
--- a/Source/Engine/Networking/NetworkReplicationHierarchy.cpp
+++ b/Source/Engine/Networking/NetworkReplicationHierarchy.cpp
@@ -167,6 +167,7 @@ void NetworkReplicationGridNode::AddObject(NetworkReplicationHierarchyObject obj
cell->MinCullDistance = obj.CullDistance;
}
cell->Node->AddObject(obj);
+ _objectToCell[obj.Object] = coord;
// Cache minimum culling distance for a whole cell to skip it at once
cell->MinCullDistance = Math::Min(cell->MinCullDistance, obj.CullDistance);
@@ -174,26 +175,35 @@ void NetworkReplicationGridNode::AddObject(NetworkReplicationHierarchyObject obj
bool NetworkReplicationGridNode::RemoveObject(ScriptingObject* obj)
{
- for (const auto& e : _children)
+ Int3 coord;
+
+ if (!_objectToCell.TryGet(obj, coord))
{
- if (e.Value.Node->RemoveObject(obj))
- {
- // TODO: remove empty cells?
- // TODO: update MinCullDistance for cell?
- return true;
- }
+ return false;
+ }
+
+ if (_children[coord].Node->RemoveObject(obj))
+ {
+ _objectToCell.Remove(obj);
+ // TODO: remove empty cells?
+ // TODO: update MinCullDistance for cell?
+ return true;
}
return false;
}
bool NetworkReplicationGridNode::GetObject(ScriptingObject* obj, NetworkReplicationHierarchyObject& result)
{
- for (const auto& e : _children)
+ Int3 coord;
+
+ if (!_objectToCell.TryGet(obj, coord))
{
- if (e.Value.Node->GetObject(obj, result))
- {
- return true;
- }
+ return false;
+ }
+
+ if (_children[coord].Node->GetObject(obj, result))
+ {
+ return true;
}
return false;
}
diff --git a/Source/Engine/Networking/NetworkReplicationHierarchy.h b/Source/Engine/Networking/NetworkReplicationHierarchy.h
index ae482dfa6..b054de453 100644
--- a/Source/Engine/Networking/NetworkReplicationHierarchy.h
+++ b/Source/Engine/Networking/NetworkReplicationHierarchy.h
@@ -246,6 +246,7 @@ private:
};
Dictionary _children;
+ Dictionary _objectToCell;
public:
///
From 020b0a90d76a58dce1d3dbceedff6fe5b7c1addf Mon Sep 17 00:00:00 2001
From: Ruan Lucas <79365912+RuanLucasGD@users.noreply.github.com>
Date: Tue, 27 Jun 2023 00:22:12 -0400
Subject: [PATCH 28/65] remove unecessary code
---
Source/Editor/ProjectInfo.cs | 12 ------------
1 file changed, 12 deletions(-)
diff --git a/Source/Editor/ProjectInfo.cs b/Source/Editor/ProjectInfo.cs
index 62402b0d8..bc55a9c05 100644
--- a/Source/Editor/ProjectInfo.cs
+++ b/Source/Editor/ProjectInfo.cs
@@ -55,16 +55,6 @@ namespace FlaxEditor
[NonSerialized]
public string ProjectFolderPath;
- ///
- /// The content assets folder
- ///
- public string ContentFolderPath;
-
- ///
- /// The source files folder path
- ///
- public string SourceFolderPath;
-
///
/// The project version.
///
@@ -167,8 +157,6 @@ namespace FlaxEditor
var project = JsonConvert.DeserializeObject(contents);
project.ProjectPath = path;
project.ProjectFolderPath = StringUtils.NormalizePath(Path.GetDirectoryName(path));
- project.ContentFolderPath = StringUtils.NormalizePath(project.ProjectFolderPath + "/Content");
- project.SourceFolderPath = StringUtils.NormalizePath(project.ProjectFolderPath + "/Source");
// Process project data
if (string.IsNullOrEmpty(project.Name))
From 75d5023354f8c6f3cdf046845b4b1bc8cb96fff1 Mon Sep 17 00:00:00 2001
From: Wojtek Figat
Date: Tue, 27 Jun 2023 23:24:02 +0200
Subject: [PATCH 29/65] Fix tooltip for project folder
---
Source/Editor/Utilities/Utils.cs | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Source/Editor/Utilities/Utils.cs b/Source/Editor/Utilities/Utils.cs
index d980b0c4a..fe801bbaf 100644
--- a/Source/Editor/Utilities/Utils.cs
+++ b/Source/Editor/Utilities/Utils.cs
@@ -1125,7 +1125,9 @@ namespace FlaxEditor.Utilities
public static string GetAssetNamePathWithExt(string path)
{
var projectFolder = Globals.ProjectFolder;
- if (path.StartsWith(projectFolder))
+ if (path == projectFolder)
+ path = string.Empty;
+ else if (path.StartsWith(projectFolder))
path = path.Substring(projectFolder.Length + 1);
return path;
}
From 90f9754781105f2d29e898aa820bb0c57f54de59 Mon Sep 17 00:00:00 2001
From: Ari Vuollet
Date: Wed, 28 Jun 2023 00:35:06 +0300
Subject: [PATCH 30/65] Release custom assets before binary modules on
scripting release
---
Source/Engine/Scripting/Scripting.cpp | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/Source/Engine/Scripting/Scripting.cpp b/Source/Engine/Scripting/Scripting.cpp
index bbd109cd1..e2d709653 100644
--- a/Source/Engine/Scripting/Scripting.cpp
+++ b/Source/Engine/Scripting/Scripting.cpp
@@ -559,6 +559,16 @@ void Scripting::Release()
}
_objectsLocker.Unlock();
+ // Release assets sourced from game assemblies
+ const auto flaxModule = GetBinaryModuleFlaxEngine();
+ for (auto asset : Content::GetAssets())
+ {
+ if (asset->GetTypeHandle().Module == flaxModule)
+ continue;
+
+ asset->DeleteObjectNow();
+ }
+
// Unload assemblies (from back to front)
{
LOG(Info, "Unloading binary modules");
From fe8260fe140a2b0c7285611726852f87b05c6fd3 Mon Sep 17 00:00:00 2001
From: PhyresiCompany
Date: Tue, 27 Jun 2023 19:58:37 -0300
Subject: [PATCH 31/65] Window improvements with a new approach
---
.../Viewport/Previews/AnimatedModelPreview.cs | 116 ++---------
.../Viewport/Previews/MaterialPreview.cs | 50 +++--
.../Viewport/Previews/ModelBasePreview.cs | 27 +--
.../Editor/Viewport/Previews/ModelPreview.cs | 84 ++++++--
.../Viewport/Previews/SkinnedModelPreview.cs | 188 ++++++++++++++++++
.../Windows/Assets/CollisionDataWindow.cs | 3 +
Source/Editor/Windows/Assets/ModelWindow.cs | 9 +
.../Windows/Assets/SkinnedModelWindow.cs | 11 +-
8 files changed, 342 insertions(+), 146 deletions(-)
create mode 100644 Source/Editor/Viewport/Previews/SkinnedModelPreview.cs
diff --git a/Source/Editor/Viewport/Previews/AnimatedModelPreview.cs b/Source/Editor/Viewport/Previews/AnimatedModelPreview.cs
index 2310668b6..aae48fe11 100644
--- a/Source/Editor/Viewport/Previews/AnimatedModelPreview.cs
+++ b/Source/Editor/Viewport/Previews/AnimatedModelPreview.cs
@@ -15,11 +15,13 @@ namespace FlaxEditor.Viewport.Previews
///
public class AnimatedModelPreview : AssetPreview
{
+ ///
+ public AnimatedModel _previewModel;
+
private ContextMenuButton _showNodesButton, _showBoundsButton, _showFloorButton, _showNodesNamesButton;
- private bool _showNodes, _showBounds, _showFloor, _showCurrentLOD, _showNodesNames;
- private AnimatedModel _previewModel;
+ private bool _showNodes, _showBounds, _showFloor, _showNodesNames;
private StaticModel _floorModel;
- private ContextMenuButton _showCurrentLODButton;
+
private bool _playAnimation, _playAnimationOnce;
private float _playSpeed = 1.0f;
@@ -207,26 +209,6 @@ namespace FlaxEditor.Viewport.Previews
// Show Floor
_showFloorButton = ViewWidgetShowMenu.AddButton("Floor", button => ShowFloor = !ShowFloor);
_showFloorButton.IndexInParent = 1;
-
- // Show Current LOD
- _showCurrentLODButton = ViewWidgetShowMenu.AddButton("Current LOD", button =>
- {
- _showCurrentLOD = !_showCurrentLOD;
- _showCurrentLODButton.Icon = _showCurrentLOD ? Style.Current.CheckBoxTick : SpriteHandle.Invalid;
- });
- _showCurrentLODButton.IndexInParent = 2;
-
- // Preview LOD
- {
- var previewLOD = ViewWidgetButtonMenu.AddButton("Preview LOD");
- previewLOD.CloseMenuOnClick = false;
- var previewLODValue = new IntValueBox(-1, 90, 2, 70.0f, -1, 10, 0.02f)
- {
- Parent = previewLOD
- };
- previewLODValue.ValueChanged += () => _previewModel.ForcedLOD = previewLODValue.Value;
- ViewWidgetButtonMenu.VisibleChanged += control => previewLODValue.Value = _previewModel.ForcedLOD;
- }
}
// Enable shadows
@@ -339,44 +321,6 @@ namespace FlaxEditor.Viewport.Previews
_previewModel.ResetAnimation();
}
- private int ComputeLODIndex(SkinnedModel model)
- {
- if (PreviewActor.ForcedLOD != -1)
- return PreviewActor.ForcedLOD;
-
- // Based on RenderTools::ComputeModelLOD
- CreateProjectionMatrix(out var projectionMatrix);
- float screenMultiple = 0.5f * Mathf.Max(projectionMatrix.M11, projectionMatrix.M22);
- var sphere = PreviewActor.Sphere;
- var viewOrigin = ViewPosition;
- var distSqr = Vector3.DistanceSquared(ref sphere.Center, ref viewOrigin);
- var screenRadiusSquared = Mathf.Square(screenMultiple * sphere.Radius) / Mathf.Max(1.0f, distSqr);
-
- // Check if model is being culled
- if (Mathf.Square(model.MinScreenSize * 0.5f) > screenRadiusSquared)
- return -1;
-
- // Skip if no need to calculate LOD
- if (model.LoadedLODs == 0)
- return -1;
- var lods = model.LODs;
- if (lods.Length == 0)
- return -1;
- if (lods.Length == 1)
- return 0;
-
- // Iterate backwards and return the first matching LOD
- for (int lodIndex = lods.Length - 1; lodIndex >= 0; lodIndex--)
- {
- if (Mathf.Square(lods[lodIndex].ScreenSize * 0.5f) >= screenRadiusSquared)
- {
- return lodIndex + PreviewActor.LODBias;
- }
- }
-
- return 0;
- }
-
///
protected override void OnDebugDraw(GPUContext context, ref RenderContext renderContext)
{
@@ -440,45 +384,6 @@ namespace FlaxEditor.Viewport.Previews
}
}
- ///
- public override void Draw()
- {
- base.Draw();
-
- var skinnedModel = _previewModel.SkinnedModel;
- if (skinnedModel == null || !skinnedModel.IsLoaded)
- return;
- var lods = skinnedModel.LODs;
- if (lods.Length == 0)
- {
- // Force show skeleton for models without geometry
- ShowNodes = true;
- return;
- }
- if (_showCurrentLOD)
- {
- var lodIndex = ComputeLODIndex(skinnedModel);
- string text = string.Format("Current LOD: {0}", lodIndex);
- if (lodIndex != -1)
- {
- lodIndex = Mathf.Clamp(lodIndex + PreviewActor.LODBias, 0, lods.Length - 1);
- var lod = lods[lodIndex];
- int triangleCount = 0, vertexCount = 0;
- for (int meshIndex = 0; meshIndex < lod.Meshes.Length; meshIndex++)
- {
- var mesh = lod.Meshes[meshIndex];
- triangleCount += mesh.TriangleCount;
- vertexCount += mesh.VertexCount;
- }
- text += string.Format("\nTriangles: {0:N0}\nVertices: {1:N0}", triangleCount, vertexCount);
- }
- var font = Style.Current.FontMedium;
- var pos = new Float2(10, 50);
- Render2D.DrawText(font, text, new Rectangle(pos + Float2.One, Size), Color.Black);
- Render2D.DrawText(font, text, new Rectangle(pos, Size), Color.White);
- }
- }
-
///
public override void Update(float deltaTime)
{
@@ -498,6 +403,14 @@ namespace FlaxEditor.Viewport.Previews
}
}
+ ///
+ /// Calls SetArcBallView from ViewportCamera
+ ///
+ public void CallSetArcBallView()
+ {
+ ViewportCamera.SetArcBallView(_previewModel.Box);
+ }
+
///
public override bool OnKeyDown(KeyboardKeys key)
{
@@ -505,7 +418,7 @@ namespace FlaxEditor.Viewport.Previews
{
case KeyboardKeys.F:
// Pay respect..
- ViewportCamera.SetArcBallView(_previewModel.Box);
+ CallSetArcBallView();
return true;
case KeyboardKeys.Spacebar:
PlayAnimation = !PlayAnimation;
@@ -525,7 +438,6 @@ namespace FlaxEditor.Viewport.Previews
_showNodesButton = null;
_showBoundsButton = null;
_showFloorButton = null;
- _showCurrentLODButton = null;
_showNodesNamesButton = null;
base.OnDestroy();
diff --git a/Source/Editor/Viewport/Previews/MaterialPreview.cs b/Source/Editor/Viewport/Previews/MaterialPreview.cs
index 632ec199e..3dfab1cff 100644
--- a/Source/Editor/Viewport/Previews/MaterialPreview.cs
+++ b/Source/Editor/Viewport/Previews/MaterialPreview.cs
@@ -4,6 +4,8 @@ using System;
using FlaxEditor.Surface;
using FlaxEngine;
using FlaxEngine.GUI;
+using FlaxEditor.Viewport.Widgets;
+using FlaxEditor.GUI.ContextMenu;
using Object = FlaxEngine.Object;
namespace FlaxEditor.Viewport.Previews
@@ -63,6 +65,11 @@ namespace FlaxEditor.Viewport.Previews
}
}
+ ///
+ /// The "Model" widget button context menu.
+ ///
+ private ContextMenu modelWidgetButtonMenu;
+
///
/// Gets or sets the selected preview model index.
///
@@ -80,6 +87,27 @@ namespace FlaxEditor.Viewport.Previews
}
}
+ ///
+ /// Fill out all models
+ ///
+ ///
+ private void ModelWidgetMenuOnVisibleChanged(Control control)
+ {
+ if (!control.Visible) return;
+
+ modelWidgetButtonMenu.ItemsContainer.DisposeChildren();
+
+ // Fill out all models
+ for (int i = 0; i < Models.Length; i++)
+ {
+ var index = i;
+ var button = modelWidgetButtonMenu.AddButton(Models[index]);
+ button.ButtonClicked += (button) => SelectedModelIndex = index;
+ button.Checked = SelectedModelIndex == index;
+ button.Tag = index;
+ }
+ }
+
///
/// Initializes a new instance of the class.
///
@@ -95,20 +123,18 @@ namespace FlaxEditor.Viewport.Previews
Task.AddCustomActor(_previewModel);
// Create context menu for primitive switching
- if (useWidgets && ViewWidgetButtonMenu != null)
+ if (useWidgets)
{
- ViewWidgetButtonMenu.AddSeparator();
- var modelSelect = ViewWidgetButtonMenu.AddChildMenu("Model").ContextMenu;
-
- // Fill out all models
- for (int i = 0; i < Models.Length; i++)
+ // Model mode widget
+ var modelMode = new ViewportWidgetsContainer(ViewportWidgetLocation.UpperRight);
+ modelWidgetButtonMenu = new ContextMenu();
+ modelWidgetButtonMenu.VisibleChanged += ModelWidgetMenuOnVisibleChanged;
+ var previewLODSModeButton = new ViewportWidgetButton("Model", SpriteHandle.Invalid, modelWidgetButtonMenu)
{
- var button = modelSelect.AddButton(Models[i]);
- button.Tag = i;
- }
-
- // Link the action
- modelSelect.ButtonClicked += (button) => SelectedModelIndex = (int)button.Tag;
+ TooltipText = "Change material model",
+ Parent = modelMode,
+ };
+ modelMode.Parent = this;
}
}
diff --git a/Source/Editor/Viewport/Previews/ModelBasePreview.cs b/Source/Editor/Viewport/Previews/ModelBasePreview.cs
index ffba23094..e5834edc9 100644
--- a/Source/Editor/Viewport/Previews/ModelBasePreview.cs
+++ b/Source/Editor/Viewport/Previews/ModelBasePreview.cs
@@ -56,25 +56,14 @@ namespace FlaxEditor.Viewport.Previews
// Link actors for rendering
Task.AddCustomActor(StaticModel);
Task.AddCustomActor(AnimatedModel);
+ }
- if (useWidgets)
- {
- // Preview LOD
- {
- var previewLOD = ViewWidgetButtonMenu.AddButton("Preview LOD");
- previewLOD.CloseMenuOnClick = false;
- var previewLODValue = new IntValueBox(-1, 90, 2, 70.0f, -1, 10, 0.02f)
- {
- Parent = previewLOD
- };
- previewLODValue.ValueChanged += () =>
- {
- StaticModel.ForcedLOD = previewLODValue.Value;
- AnimatedModel.ForcedLOD = previewLODValue.Value;
- };
- ViewWidgetButtonMenu.VisibleChanged += control => previewLODValue.Value = StaticModel.ForcedLOD;
- }
- }
+ ///
+ /// Calls SetArcBallView from ViewportCamera
+ ///
+ public void CallSetArcBallView()
+ {
+ ViewportCamera.SetArcBallView(StaticModel.Model != null ? StaticModel.Box : AnimatedModel.Box);
}
private void OnBegin(RenderTask task, GPUContext context)
@@ -104,7 +93,7 @@ namespace FlaxEditor.Viewport.Previews
{
case KeyboardKeys.F:
// Pay respect..
- ViewportCamera.SetArcBallView(StaticModel.Model != null ? StaticModel.Box : AnimatedModel.Box);
+ CallSetArcBallView();
break;
}
return base.OnKeyDown(key);
diff --git a/Source/Editor/Viewport/Previews/ModelPreview.cs b/Source/Editor/Viewport/Previews/ModelPreview.cs
index 9193b6d40..dc0de37da 100644
--- a/Source/Editor/Viewport/Previews/ModelPreview.cs
+++ b/Source/Editor/Viewport/Previews/ModelPreview.cs
@@ -5,6 +5,7 @@ using FlaxEditor.GUI.Input;
using FlaxEngine;
using FlaxEngine.GUI;
using FlaxEngine.Utilities;
+using FlaxEditor.Viewport.Widgets;
using Object = FlaxEngine.Object;
namespace FlaxEditor.Viewport.Previews
@@ -20,6 +21,29 @@ namespace FlaxEditor.Viewport.Previews
private bool _showBounds, _showCurrentLOD, _showNormals, _showTangents, _showBitangents, _showFloor;
private MeshDataCache _meshDatas;
+ ///
+ /// The "PreviewLODS" widget button context menu.
+ ///
+ private ContextMenu previewLODSWidgetButtonMenu;
+
+ ///
+ /// Gets or sets a value that shows LOD statistics
+ ///
+ public bool ShowCurrentLOD
+ {
+ get => _showCurrentLOD;
+ set
+ {
+ if (_showCurrentLOD == value)
+ return;
+ _showCurrentLOD = value;
+ if (value)
+ ShowDebugDraw = true;
+ if (_showCurrentLODButton != null)
+ _showCurrentLODButton.Checked = value;
+ }
+ }
+
///
/// Gets or sets the model asset to preview.
///
@@ -198,16 +222,41 @@ namespace FlaxEditor.Viewport.Previews
});
_showCurrentLODButton.IndexInParent = 2;
- // Preview LOD
+ // PreviewLODS mode widget
+ var PreviewLODSMode = new ViewportWidgetsContainer(ViewportWidgetLocation.UpperRight);
+ previewLODSWidgetButtonMenu = new ContextMenu();
+ previewLODSWidgetButtonMenu.VisibleChanged += PreviewLODSWidgetMenuOnVisibleChanged;
+ var previewLODSModeButton = new ViewportWidgetButton("Preview LOD", SpriteHandle.Invalid, previewLODSWidgetButtonMenu)
{
- var previewLOD = ViewWidgetButtonMenu.AddButton("Preview LOD");
- previewLOD.CloseMenuOnClick = false;
- var previewLODValue = new IntValueBox(-1, 90, 2, 70.0f, -1, 10, 0.02f)
- {
- Parent = previewLOD
- };
- previewLODValue.ValueChanged += () => _previewModel.ForcedLOD = previewLODValue.Value;
- ViewWidgetButtonMenu.VisibleChanged += control => previewLODValue.Value = _previewModel.ForcedLOD;
+ TooltipText = "Preview LOD properties",
+ Parent = PreviewLODSMode,
+ };
+ PreviewLODSMode.Parent = this;
+ }
+ }
+
+ ///
+ /// Fill out all Model LODS
+ ///
+ ///
+ private void PreviewLODSWidgetMenuOnVisibleChanged(Control control)
+ {
+ if (!control.Visible)
+ return;
+
+ var model = _previewModel.Model;
+ if (model && !model.WaitForLoaded() && model.IsLoaded)
+ {
+ previewLODSWidgetButtonMenu.ItemsContainer.DisposeChildren();
+ var lods = model.LODs.Length;
+ for (int i = -1; i < lods; i++)
+ {
+ var index = i;
+ var button = previewLODSWidgetButtonMenu.AddButton("LOD " + (index == -1 ? "Auto" : index));
+ button.ButtonClicked += (button) => _previewModel.ForcedLOD = index;
+ button.Checked = _previewModel.ForcedLOD == index;
+ button.Tag = index;
+ if (lods <= 1) return;
}
}
}
@@ -346,8 +395,11 @@ namespace FlaxEditor.Viewport.Previews
if (_showCurrentLOD)
{
var asset = Model;
- var lodIndex = ComputeLODIndex(asset, out var screenSize);
- string text = string.Format("Current LOD: {0}\nScreen Size: {1:F2}", lodIndex, screenSize);
+ var lodIndex = ComputeLODIndex(asset, out var screenSize);
+ var auto = _previewModel.ForcedLOD == -1;
+ string text = auto ? "LOD Automatic" : "";
+ text += auto ? string.Format("\nScreen Size: {0:F2}", screenSize) : "";
+ text += string.Format("\nCurrent LOD: {0}", lodIndex);
if (lodIndex != -1)
{
var lods = asset.LODs;
@@ -369,6 +421,14 @@ namespace FlaxEditor.Viewport.Previews
}
}
+ ///
+ /// Calls SetArcBallView from ViewportCamera
+ ///
+ public void CallSetArcBallView()
+ {
+ ViewportCamera.SetArcBallView(_previewModel.Box);
+ }
+
///
public override bool OnKeyDown(KeyboardKeys key)
{
@@ -376,7 +436,7 @@ namespace FlaxEditor.Viewport.Previews
{
case KeyboardKeys.F:
// Pay respect..
- ViewportCamera.SetArcBallView(_previewModel.Box);
+ CallSetArcBallView();
break;
}
return base.OnKeyDown(key);
diff --git a/Source/Editor/Viewport/Previews/SkinnedModelPreview.cs b/Source/Editor/Viewport/Previews/SkinnedModelPreview.cs
new file mode 100644
index 000000000..a8b98b423
--- /dev/null
+++ b/Source/Editor/Viewport/Previews/SkinnedModelPreview.cs
@@ -0,0 +1,188 @@
+using System;
+using FlaxEditor.GUI.ContextMenu;
+using FlaxEngine;
+using FlaxEngine.GUI;
+using FlaxEditor.Viewport.Widgets;
+
+namespace FlaxEditor.Viewport.Previews
+{
+ ///
+ /// Animation asset preview editor viewport.
+ ///
+ ///
+ public class SkinnedModelPreview : AnimatedModelPreview
+ {
+ private bool _showCurrentLOD;
+ private ContextMenuButton _showCurrentLODButton;
+
+ ///
+ /// The "PreviewLODS" widget button context menu.
+ ///
+ private ContextMenu previewLODSWidgetButtonMenu;
+
+ ///
+ /// Gets or sets a value that shows LOD statistics
+ ///
+ public bool ShowCurrentLOD
+ {
+ get => _showCurrentLOD;
+ set
+ {
+ if (_showCurrentLOD == value)
+ return;
+ _showCurrentLOD = value;
+ if (value)
+ ShowDebugDraw = true;
+ if (_showCurrentLODButton != null)
+ _showCurrentLODButton.Checked = value;
+ }
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// if set to true use widgets.
+ public SkinnedModelPreview(bool useWidgets)
+ : base(useWidgets)
+ {
+ if (useWidgets)
+ {
+ // Show Current LOD
+ _showCurrentLODButton = ViewWidgetShowMenu.AddButton("Current LOD", button =>
+ {
+ _showCurrentLOD = !_showCurrentLOD;
+ _showCurrentLODButton.Icon = _showCurrentLOD ? Style.Current.CheckBoxTick : SpriteHandle.Invalid;
+ });
+ _showCurrentLODButton.IndexInParent = 2;
+
+ // PreviewLODS mode widget
+ var PreviewLODSMode = new ViewportWidgetsContainer(ViewportWidgetLocation.UpperRight);
+ previewLODSWidgetButtonMenu = new ContextMenu();
+ previewLODSWidgetButtonMenu.VisibleChanged += PreviewLODSWidgetMenuOnVisibleChanged;
+ var previewLODSModeButton = new ViewportWidgetButton("Preview LOD", SpriteHandle.Invalid, previewLODSWidgetButtonMenu)
+ {
+ TooltipText = "Preview LOD properties",
+ Parent = PreviewLODSMode,
+ };
+ PreviewLODSMode.Parent = this;
+ }
+ }
+
+ ///
+ /// Fill out all SkinnedModel LODS
+ ///
+ ///
+ private void PreviewLODSWidgetMenuOnVisibleChanged(Control control)
+ {
+ if (!control.Visible)
+ return;
+
+ var skinned = _previewModel.SkinnedModel;
+ if (skinned && !skinned.WaitForLoaded() && skinned.IsLoaded)
+ {
+ previewLODSWidgetButtonMenu.ItemsContainer.DisposeChildren();
+ var lods = skinned.LODs.Length;
+ for (int i = -1; i < lods; i++)
+ {
+ var index = i;
+ var button = previewLODSWidgetButtonMenu.AddButton("LOD " + (index == -1 ? "Auto" : index));
+ button.ButtonClicked += (button) => _previewModel.ForcedLOD = index;
+ button.Checked = _previewModel.ForcedLOD == index;
+ button.Tag = index;
+ if (lods <= 1) return;
+ }
+ }
+ }
+
+ ///
+ private int ComputeLODIndex(SkinnedModel model, out float screenSize)
+ {
+ screenSize = 1.0f;
+ if (PreviewActor.ForcedLOD != -1)
+ return PreviewActor.ForcedLOD;
+
+ // Based on RenderTools::ComputeModelLOD
+ CreateProjectionMatrix(out var projectionMatrix);
+ float screenMultiple = 0.5f * Mathf.Max(projectionMatrix.M11, projectionMatrix.M22);
+ var sphere = PreviewActor.Sphere;
+ var viewOrigin = ViewPosition;
+ var distSqr = Vector3.DistanceSquared(ref sphere.Center, ref viewOrigin);
+ var screenRadiusSquared = Mathf.Square(screenMultiple * sphere.Radius) / Mathf.Max(1.0f, distSqr);
+ screenSize = Mathf.Sqrt((float)screenRadiusSquared) * 2.0f;
+
+ // Check if model is being culled
+ if (Mathf.Square(model.MinScreenSize * 0.5f) > screenRadiusSquared)
+ return -1;
+
+ // Skip if no need to calculate LOD
+ if (model.LoadedLODs == 0)
+ return -1;
+ var lods = model.LODs;
+ if (lods.Length == 0)
+ return -1;
+ if (lods.Length == 1)
+ return 0;
+
+ // Iterate backwards and return the first matching LOD
+ for (int lodIndex = lods.Length - 1; lodIndex >= 0; lodIndex--)
+ {
+ if (Mathf.Square(lods[lodIndex].ScreenSize * 0.5f) >= screenRadiusSquared)
+ {
+ return lodIndex + PreviewActor.LODBias;
+ }
+ }
+
+ return 0;
+ }
+
+ ///
+ public override void Draw()
+ {
+ base.Draw();
+
+ var skinnedModel = _previewModel.SkinnedModel;
+ if (skinnedModel == null || !skinnedModel.IsLoaded)
+ return;
+ var lods = skinnedModel.LODs;
+ if (lods.Length == 0)
+ {
+ // Force show skeleton for models without geometry
+ ShowNodes = true;
+ return;
+ }
+ if (_showCurrentLOD)
+ {
+ var lodIndex = ComputeLODIndex(skinnedModel, out var screenSize);
+ var auto = _previewModel.ForcedLOD == -1;
+ string text = auto ? "LOD Automatic" : "";
+ text += auto ? string.Format("\nScreen Size: {0:F2}", screenSize) : "";
+ text += string.Format("\nCurrent LOD: {0}", lodIndex);
+ if (lodIndex != -1)
+ {
+ lodIndex = Mathf.Clamp(lodIndex + PreviewActor.LODBias, 0, lods.Length - 1);
+ var lod = lods[lodIndex];
+ int triangleCount = 0, vertexCount = 0;
+ for (int meshIndex = 0; meshIndex < lod.Meshes.Length; meshIndex++)
+ {
+ var mesh = lod.Meshes[meshIndex];
+ triangleCount += mesh.TriangleCount;
+ vertexCount += mesh.VertexCount;
+ }
+ text += string.Format("\nTriangles: {0:N0}\nVertices: {1:N0}", triangleCount, vertexCount);
+ }
+ var font = Style.Current.FontMedium;
+ var pos = new Float2(10, 50);
+ Render2D.DrawText(font, text, new Rectangle(pos + Float2.One, Size), Color.Black);
+ Render2D.DrawText(font, text, new Rectangle(pos, Size), Color.White);
+ }
+ }
+
+ ///
+ public override void OnDestroy()
+ {
+ _showCurrentLODButton = null;
+
+ base.OnDestroy();
+ }
+ }
+}
diff --git a/Source/Editor/Windows/Assets/CollisionDataWindow.cs b/Source/Editor/Windows/Assets/CollisionDataWindow.cs
index 9ce4c8765..82e0681fa 100644
--- a/Source/Editor/Windows/Assets/CollisionDataWindow.cs
+++ b/Source/Editor/Windows/Assets/CollisionDataWindow.cs
@@ -182,6 +182,9 @@ namespace FlaxEditor.Windows.Assets
{
// Toolstrip
_toolstrip.AddSeparator();
+
+ _toolstrip.AddButton(editor.Icons.CenterView64, () => _preview.CallSetArcBallView()).LinkTooltip("Show whole collision");
+
_toolstrip.AddButton(editor.Icons.Docs64, () => Platform.OpenUrl(Utilities.Constants.DocsUrl + "manual/physics/colliders/collision-data.html")).LinkTooltip("See documentation to learn more");
// Split Panel
diff --git a/Source/Editor/Windows/Assets/ModelWindow.cs b/Source/Editor/Windows/Assets/ModelWindow.cs
index e44882b73..cc7657fc7 100644
--- a/Source/Editor/Windows/Assets/ModelWindow.cs
+++ b/Source/Editor/Windows/Assets/ModelWindow.cs
@@ -779,12 +779,18 @@ namespace FlaxEditor.Windows.Assets
private MeshDataCache _meshData;
private ModelImportSettings _importSettings = new ModelImportSettings();
private float _backfacesThreshold = 0.6f;
+ private ToolStripButton _showCurrentLODButton;
///
public ModelWindow(Editor editor, AssetItem item)
: base(editor, item)
{
// Toolstrip
+ _toolstrip.AddSeparator();
+ _showCurrentLODButton = (ToolStripButton)_toolstrip.AddButton(editor.Icons.Info64, () => _preview.ShowCurrentLOD = !_preview.ShowCurrentLOD).LinkTooltip("Show LOD statistics");
+
+ _toolstrip.AddButton(editor.Icons.CenterView64, () => _preview.CallSetArcBallView()).LinkTooltip("Show whole model");
+
_toolstrip.AddSeparator();
_toolstrip.AddButton(editor.Icons.Docs64, () => Platform.OpenUrl(Utilities.Constants.DocsUrl + "manual/graphics/models/index.html")).LinkTooltip("See documentation to learn more");
@@ -869,6 +875,8 @@ namespace FlaxEditor.Windows.Assets
}
}
+ _showCurrentLODButton.Checked = _preview.ShowCurrentLOD;
+
base.Update(deltaTime);
}
@@ -946,6 +954,7 @@ namespace FlaxEditor.Windows.Assets
base.OnDestroy();
Object.Destroy(ref _highlightActor);
+ _showCurrentLODButton = null;
}
}
}
diff --git a/Source/Editor/Windows/Assets/SkinnedModelWindow.cs b/Source/Editor/Windows/Assets/SkinnedModelWindow.cs
index d18593549..367fc3a1a 100644
--- a/Source/Editor/Windows/Assets/SkinnedModelWindow.cs
+++ b/Source/Editor/Windows/Assets/SkinnedModelWindow.cs
@@ -31,7 +31,7 @@ namespace FlaxEditor.Windows.Assets
///
public sealed class SkinnedModelWindow : ModelBaseWindow
{
- private sealed class Preview : AnimatedModelPreview
+ private sealed class Preview : SkinnedModelPreview
{
private readonly SkinnedModelWindow _window;
@@ -1105,6 +1105,7 @@ namespace FlaxEditor.Windows.Assets
private Preview _preview;
private AnimatedModel _highlightActor;
private ToolStripButton _showNodesButton;
+ private ToolStripButton _showCurrentLODButton;
private MeshData[][] _meshDatas;
private bool _meshDatasInProgress;
@@ -1116,7 +1117,13 @@ namespace FlaxEditor.Windows.Assets
{
// Toolstrip
_toolstrip.AddSeparator();
+
+ _showCurrentLODButton = (ToolStripButton)_toolstrip.AddButton(editor.Icons.Info64, () => _preview.ShowCurrentLOD = !_preview.ShowCurrentLOD).LinkTooltip("Show LOD statistics");
+
_showNodesButton = (ToolStripButton)_toolstrip.AddButton(editor.Icons.Bone64, () => _preview.ShowNodes = !_preview.ShowNodes).LinkTooltip("Show animated model nodes debug view");
+
+ _toolstrip.AddButton(editor.Icons.CenterView64, () => _preview.CallSetArcBallView()).LinkTooltip("Show whole model");
+
_toolstrip.AddSeparator();
_toolstrip.AddButton(editor.Icons.Docs64, () => Platform.OpenUrl(Utilities.Constants.DocsUrl + "manual/animation/skinned-model/index.html")).LinkTooltip("See documentation to learn more");
@@ -1265,6 +1272,7 @@ namespace FlaxEditor.Windows.Assets
}
}
+ _showCurrentLODButton.Checked = _preview.ShowCurrentLOD;
_showNodesButton.Checked = _preview.ShowNodes;
base.Update(deltaTime);
@@ -1349,6 +1357,7 @@ namespace FlaxEditor.Windows.Assets
Object.Destroy(ref _highlightActor);
_preview = null;
_showNodesButton = null;
+ _showCurrentLODButton = null;
}
}
}
From 76e4e1b8d49e6a71ae9f6c3c5df7555507a568bc Mon Sep 17 00:00:00 2001
From: Ruan Lucas <79365912+RuanLucasGD@users.noreply.github.com>
Date: Tue, 27 Jun 2023 21:08:12 -0400
Subject: [PATCH 32/65] fix debug vehicle wheel orientation
---
Source/Engine/Physics/Actors/WheeledVehicle.cpp | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/Source/Engine/Physics/Actors/WheeledVehicle.cpp b/Source/Engine/Physics/Actors/WheeledVehicle.cpp
index 2ed59c8f6..995150bdc 100644
--- a/Source/Engine/Physics/Actors/WheeledVehicle.cpp
+++ b/Source/Engine/Physics/Actors/WheeledVehicle.cpp
@@ -230,10 +230,11 @@ void WheeledVehicle::DrawPhysicsDebug(RenderView& view)
{
const Vector3 currentPos = wheel.Collider->GetPosition();
const Vector3 basePos = currentPos - Vector3(0, data.State.SuspensionOffset, 0);
+ const Quaternion wheelDebugOrientation = wheel.Collider->GetOrientation() * Quaternion::Euler(90, 0, 90);
DEBUG_DRAW_WIRE_SPHERE(BoundingSphere(basePos, wheel.Radius * 0.07f), Color::Blue * 0.3f, 0, true);
DEBUG_DRAW_WIRE_SPHERE(BoundingSphere(currentPos, wheel.Radius * 0.08f), Color::Blue * 0.8f, 0, true);
DEBUG_DRAW_LINE(basePos, currentPos, Color::Blue, 0, true);
- DEBUG_DRAW_WIRE_CYLINDER(currentPos, wheel.Collider->GetOrientation(), wheel.Radius, wheel.Width, Color::Red * 0.8f, 0, true);
+ DEBUG_DRAW_WIRE_CYLINDER(currentPos, wheelDebugOrientation, wheel.Radius, wheel.Width, Color::Red * 0.8f, 0, true);
if (!data.State.IsInAir)
{
DEBUG_DRAW_WIRE_SPHERE(BoundingSphere(data.State.TireContactPoint, 5.0f), Color::Green, 0, true);
@@ -260,6 +261,7 @@ void WheeledVehicle::OnDebugDrawSelected()
{
const Vector3 currentPos = wheel.Collider->GetPosition();
const Vector3 basePos = currentPos - Vector3(0, data.State.SuspensionOffset, 0);
+ const Quaternion wheelDebugOrientation = wheel.Collider->GetOrientation() * Quaternion::Euler(90, 0, 90);
Transform actorPose = Transform::Identity, shapePose = Transform::Identity;
PhysicsBackend::GetRigidActorPose(_actor, actorPose.Translation, actorPose.Orientation);
PhysicsBackend::GetShapeLocalPose(wheel.Collider->GetPhysicsShape(), shapePose.Translation, shapePose.Orientation);
@@ -267,7 +269,7 @@ void WheeledVehicle::OnDebugDrawSelected()
DEBUG_DRAW_WIRE_SPHERE(BoundingSphere(currentPos, wheel.Radius * 0.08f), Color::Blue * 0.8f, 0, false);
DEBUG_DRAW_WIRE_SPHERE(BoundingSphere(actorPose.LocalToWorld(shapePose.Translation), wheel.Radius * 0.11f), Color::OrangeRed * 0.8f, 0, false);
DEBUG_DRAW_LINE(basePos, currentPos, Color::Blue, 0, false);
- DEBUG_DRAW_WIRE_CYLINDER(currentPos, wheel.Collider->GetOrientation(), wheel.Radius, wheel.Width, Color::Red * 0.4f, 0, false);
+ DEBUG_DRAW_WIRE_CYLINDER(currentPos, wheelDebugOrientation, wheel.Radius, wheel.Width, Color::Red * 0.4f, 0, false);
if (!data.State.SuspensionTraceStart.IsZero())
{
DEBUG_DRAW_WIRE_SPHERE(BoundingSphere(data.State.SuspensionTraceStart, 5.0f), Color::AliceBlue, 0, false);
From 17aa4ea60dc4b48243c225612995ad515211e932 Mon Sep 17 00:00:00 2001
From: Wojtek Figat
Date: Wed, 28 Jun 2023 12:21:58 +0200
Subject: [PATCH 33/65] Optimize `CollisionsHelper::FrustumContainsBox`
---
Source/Engine/Core/Math/BoundingFrustum.h | 1 +
Source/Engine/Core/Math/CollisionsHelper.cpp | 19 +++++--------------
2 files changed, 6 insertions(+), 14 deletions(-)
diff --git a/Source/Engine/Core/Math/BoundingFrustum.h b/Source/Engine/Core/Math/BoundingFrustum.h
index 61c5d122f..287d33c2f 100644
--- a/Source/Engine/Core/Math/BoundingFrustum.h
+++ b/Source/Engine/Core/Math/BoundingFrustum.h
@@ -12,6 +12,7 @@
///
API_STRUCT(InBuild) struct FLAXENGINE_API BoundingFrustum
{
+ friend CollisionsHelper;
private:
Matrix _matrix;
diff --git a/Source/Engine/Core/Math/CollisionsHelper.cpp b/Source/Engine/Core/Math/CollisionsHelper.cpp
index 60ba61f28..8ad5b7673 100644
--- a/Source/Engine/Core/Math/CollisionsHelper.cpp
+++ b/Source/Engine/Core/Math/CollisionsHelper.cpp
@@ -939,7 +939,6 @@ bool CollisionsHelper::RayIntersectsSphere(const Ray& ray, const BoundingSphere&
normal = Vector3::Up;
return false;
}
-
const Vector3 point = ray.Position + ray.Direction * distance;
normal = Vector3::Normalize(point - sphere.Center);
return true;
@@ -953,22 +952,17 @@ bool CollisionsHelper::RayIntersectsSphere(const Ray& ray, const BoundingSphere&
point = Vector3::Zero;
return false;
}
-
point = ray.Position + ray.Direction * distance;
return true;
}
PlaneIntersectionType CollisionsHelper::PlaneIntersectsPoint(const Plane& plane, const Vector3& point)
{
- Real distance = Vector3::Dot(plane.Normal, point);
- distance += plane.D;
-
+ const Real distance = Vector3::Dot(plane.Normal, point) + plane.D;
if (distance > Plane::DistanceEpsilon)
return PlaneIntersectionType::Front;
-
if (distance < Plane::DistanceEpsilon)
return PlaneIntersectionType::Back;
-
return PlaneIntersectionType::Intersecting;
}
@@ -1169,7 +1163,6 @@ ContainmentType CollisionsHelper::SphereContainsPoint(const BoundingSphere& sphe
{
if (Vector3::DistanceSquared(point, sphere.Center) <= sphere.Radius * sphere.Radius)
return ContainmentType::Contains;
-
return ContainmentType::Disjoint;
}
@@ -1254,13 +1247,10 @@ ContainmentType CollisionsHelper::SphereContainsBox(const BoundingSphere& sphere
ContainmentType CollisionsHelper::SphereContainsSphere(const BoundingSphere& sphere1, const BoundingSphere& sphere2)
{
const Real distance = Vector3::Distance(sphere1.Center, sphere2.Center);
-
if (sphere1.Radius + sphere2.Radius < distance)
return ContainmentType::Disjoint;
-
if (sphere1.Radius - sphere2.Radius < distance)
return ContainmentType::Intersects;
-
return ContainmentType::Contains;
}
@@ -1274,7 +1264,8 @@ ContainmentType CollisionsHelper::FrustumContainsBox(const BoundingFrustum& frus
auto result = ContainmentType::Contains;
for (int32 i = 0; i < 6; i++)
{
- Plane plane = frustum.GetPlane(i);
+ Plane plane = frustum._planes[i];
+
Vector3 p = box.Minimum;
if (plane.Normal.X >= 0)
p.X = box.Maximum.X;
@@ -1282,7 +1273,7 @@ ContainmentType CollisionsHelper::FrustumContainsBox(const BoundingFrustum& frus
p.Y = box.Maximum.Y;
if (plane.Normal.Z >= 0)
p.Z = box.Maximum.Z;
- if (PlaneIntersectsPoint(plane, p) == PlaneIntersectionType::Back)
+ if (Vector3::Dot(plane.Normal, p) + plane.D < Plane::DistanceEpsilon)
return ContainmentType::Disjoint;
p = box.Maximum;
@@ -1292,7 +1283,7 @@ ContainmentType CollisionsHelper::FrustumContainsBox(const BoundingFrustum& frus
p.Y = box.Minimum.Y;
if (plane.Normal.Z >= 0)
p.Z = box.Minimum.Z;
- if (PlaneIntersectsPoint(plane, p) == PlaneIntersectionType::Back)
+ if (Vector3::Dot(plane.Normal, p) + plane.D < Plane::DistanceEpsilon)
result = ContainmentType::Intersects;
}
return result;
From fb6bc75e3a4cc2fae13ee7416b4c8ada25076e54 Mon Sep 17 00:00:00 2001
From: Wojtek Figat
Date: Wed, 28 Jun 2023 13:42:18 +0200
Subject: [PATCH 34/65] Fix `launchSettings.json` generation bug
---
.../Projects/VisualStudio/VisualStudioProjectGenerator.cs | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Source/Tools/Flax.Build/Projects/VisualStudio/VisualStudioProjectGenerator.cs b/Source/Tools/Flax.Build/Projects/VisualStudio/VisualStudioProjectGenerator.cs
index fb5c90872..1955a57ba 100644
--- a/Source/Tools/Flax.Build/Projects/VisualStudio/VisualStudioProjectGenerator.cs
+++ b/Source/Tools/Flax.Build/Projects/VisualStudio/VisualStudioProjectGenerator.cs
@@ -547,6 +547,7 @@ namespace Flax.Build.Projects.VisualStudio
if (project.Type == TargetType.DotNetCore)
{
var path = Path.Combine(Path.GetDirectoryName(project.Path), "Properties/launchSettings.json");
+ path = Utilities.NormalizePath(path);
if (profiles.ContainsKey(path))
profile.AppendLine(",");
profile.AppendLine($" \"{project.BaseName}\": {{");
@@ -568,6 +569,7 @@ namespace Flax.Build.Projects.VisualStudio
var folder = Path.GetDirectoryName(e.Key);
if (!Directory.Exists(folder))
Directory.CreateDirectory(folder);
+ profile.Clear();
profile.AppendLine("{");
profile.AppendLine(" \"profiles\": {");
profile.AppendLine(e.Value);
From d3b96742e73b6a1bfa2a1356bb90ebb42a2fb379 Mon Sep 17 00:00:00 2001
From: Ari Vuollet
Date: Wed, 28 Jun 2023 14:42:06 +0300
Subject: [PATCH 35/65] Fix compile-time error in HashSet::ClearDelete
---
Source/Engine/Core/Collections/HashSet.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Source/Engine/Core/Collections/HashSet.h b/Source/Engine/Core/Collections/HashSet.h
index 698788869..ad6f8ffc6 100644
--- a/Source/Engine/Core/Collections/HashSet.h
+++ b/Source/Engine/Core/Collections/HashSet.h
@@ -357,8 +357,8 @@ public:
{
for (Iterator i = Begin(); i.IsNotEnd(); ++i)
{
- if (i->Value)
- ::Delete(i->Value);
+ if (i->Item)
+ ::Delete(i->Item);
}
Clear();
}
From 093928f2f96059489f4c47463463a6a2671b0ece Mon Sep 17 00:00:00 2001
From: Chandler Cox
Date: Wed, 28 Jun 2023 06:42:54 -0500
Subject: [PATCH 36/65] Change name to `ReallocAligned`
---
Source/Engine/Core/Memory/Memory.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Source/Engine/Core/Memory/Memory.h b/Source/Engine/Core/Memory/Memory.h
index a35929ed2..96acc0746 100644
--- a/Source/Engine/Core/Memory/Memory.h
+++ b/Source/Engine/Core/Memory/Memory.h
@@ -44,7 +44,7 @@ namespace AllocatorExt
/// The size of the new allocation (in bytes).
/// The memory alignment (in bytes). Must be an integer power of 2.
/// The pointer to the allocated chunk of the memory. The pointer is a multiple of alignment.
- inline void* ReallocWithAlignment(void* ptr, uint64 newSize, uint64 alignment)
+ inline void* ReallocAligned(void* ptr, uint64 newSize, uint64 alignment)
{
if (newSize == 0)
{
From b16a6199d0b26c9aa1e0437bd8e2fa581704d53a Mon Sep 17 00:00:00 2001
From: Wojtek Figat
Date: Wed, 28 Jun 2023 14:52:58 +0200
Subject: [PATCH 37/65] Fix invoking Client RPC on Host client when it's not
included in `targetIds` list
---
Source/Engine/Core/Types/Span.h | 11 ++++++
.../Engine/Networking/NetworkReplicator.cpp | 18 +++++++--
Source/Engine/Networking/NetworkReplicator.cs | 5 ++-
Source/Engine/Networking/NetworkReplicator.h | 5 ++-
Source/Engine/Networking/NetworkRpc.h | 7 +---
.../Build/Plugins/NetworkingPlugin.cs | 39 ++++---------------
6 files changed, 41 insertions(+), 44 deletions(-)
diff --git a/Source/Engine/Core/Types/Span.h b/Source/Engine/Core/Types/Span.h
index 678550e85..e7bea5fbd 100644
--- a/Source/Engine/Core/Types/Span.h
+++ b/Source/Engine/Core/Types/Span.h
@@ -114,3 +114,14 @@ inline Span ToSpan(const T* ptr, int32 length)
{
return Span(ptr, length);
}
+
+template
+inline bool SpanContains(const Span span, const T& value)
+{
+ for (int32 i = 0; i < span.Length(); i++)
+ {
+ if (span.Get()[i] == value)
+ return true;
+ }
+ return false;
+}
diff --git a/Source/Engine/Networking/NetworkReplicator.cpp b/Source/Engine/Networking/NetworkReplicator.cpp
index c41e104ef..ae7549a50 100644
--- a/Source/Engine/Networking/NetworkReplicator.cpp
+++ b/Source/Engine/Networking/NetworkReplicator.cpp
@@ -700,9 +700,9 @@ void NetworkReplicator::AddRPC(const ScriptingTypeHandle& typeHandle, const Stri
NetworkRpcInfo::RPCsTable[rpcName] = rpcInfo;
}
-void NetworkReplicator::CSharpEndInvokeRPC(ScriptingObject* obj, const ScriptingTypeHandle& type, const StringAnsiView& name, NetworkStream* argsStream, MArray* targetIds)
+bool NetworkReplicator::CSharpEndInvokeRPC(ScriptingObject* obj, const ScriptingTypeHandle& type, const StringAnsiView& name, NetworkStream* argsStream, MArray* targetIds)
{
- EndInvokeRPC(obj, type, GetCSharpCachedName(name), argsStream, MUtils::ToSpan(targetIds));
+ return EndInvokeRPC(obj, type, GetCSharpCachedName(name), argsStream, MUtils::ToSpan(targetIds));
}
StringAnsiView NetworkReplicator::GetCSharpCachedName(const StringAnsiView& name)
@@ -1113,12 +1113,12 @@ NetworkStream* NetworkReplicator::BeginInvokeRPC()
return CachedWriteStream;
}
-void NetworkReplicator::EndInvokeRPC(ScriptingObject* obj, const ScriptingTypeHandle& type, const StringAnsiView& name, NetworkStream* argsStream, Span targetIds)
+bool NetworkReplicator::EndInvokeRPC(ScriptingObject* obj, const ScriptingTypeHandle& type, const StringAnsiView& name, NetworkStream* argsStream, Span targetIds)
{
Scripting::ObjectsLookupIdMapping.Set(nullptr);
const NetworkRpcInfo* info = NetworkRpcInfo::RPCsTable.TryGet(NetworkRpcName(type, name));
if (!info || !obj || NetworkManager::IsOffline())
- return;
+ return false;
ObjectsLock.Lock();
auto& rpc = RpcQueue.AddOne();
rpc.Object = obj;
@@ -1135,6 +1135,16 @@ void NetworkReplicator::EndInvokeRPC(ScriptingObject* obj, const ScriptingTypeHa
}
#endif
ObjectsLock.Unlock();
+
+ // Check if skip local execution (eg. server rpc called from client or client rpc with specific targets)
+ const NetworkManagerMode networkMode = NetworkManager::Mode;
+ if (info->Server && networkMode == NetworkManagerMode::Client)
+ return true;
+ if (info->Client && networkMode == NetworkManagerMode::Server)
+ return true;
+ if (info->Client && networkMode == NetworkManagerMode::Host && targetIds.IsValid() && !SpanContains(targetIds, NetworkManager::LocalClientId))
+ return true;
+ return false;
}
void NetworkInternal::NetworkReplicatorClientConnected(NetworkClient* client)
diff --git a/Source/Engine/Networking/NetworkReplicator.cs b/Source/Engine/Networking/NetworkReplicator.cs
index 1ca251f75..bc437b82e 100644
--- a/Source/Engine/Networking/NetworkReplicator.cs
+++ b/Source/Engine/Networking/NetworkReplicator.cs
@@ -120,10 +120,11 @@ namespace FlaxEngine.Networking
/// The RPC name.
/// The RPC serialized arguments stream returned from BeginInvokeRPC.
/// Optional list with network client IDs that should receive RPC. Empty to send on all clients. Ignored by Server RPCs.
+ /// True if RPC cannot be executed locally, false if execute it locally too (checks RPC mode and target client ids).
[Unmanaged]
- public static void EndInvokeRPC(Object obj, Type type, string name, NetworkStream argsStream, uint[] targetIds = null)
+ public static bool EndInvokeRPC(Object obj, Type type, string name, NetworkStream argsStream, uint[] targetIds = null)
{
- Internal_CSharpEndInvokeRPC(FlaxEngine.Object.GetUnmanagedPtr(obj), type, name, FlaxEngine.Object.GetUnmanagedPtr(argsStream), targetIds);
+ return Internal_CSharpEndInvokeRPC(FlaxEngine.Object.GetUnmanagedPtr(obj), type, name, FlaxEngine.Object.GetUnmanagedPtr(argsStream), targetIds);
}
///
diff --git a/Source/Engine/Networking/NetworkReplicator.h b/Source/Engine/Networking/NetworkReplicator.h
index 156e7eeea..ecccc52cd 100644
--- a/Source/Engine/Networking/NetworkReplicator.h
+++ b/Source/Engine/Networking/NetworkReplicator.h
@@ -195,13 +195,14 @@ public:
/// The RPC name.
/// The RPC serialized arguments stream returned from BeginInvokeRPC.
/// Optional list with network client IDs that should receive RPC. Empty to send on all clients. Ignored by Server RPCs.
- static void EndInvokeRPC(ScriptingObject* obj, const ScriptingTypeHandle& type, const StringAnsiView& name, NetworkStream* argsStream, Span targetIds = Span());
+ /// True if RPC cannot be executed locally, false if execute it locally too (checks RPC mode and target client ids).
+ static bool EndInvokeRPC(ScriptingObject* obj, const ScriptingTypeHandle& type, const StringAnsiView& name, NetworkStream* argsStream, Span targetIds = Span());
private:
#if !COMPILE_WITHOUT_CSHARP
API_FUNCTION(NoProxy) static void AddSerializer(const ScriptingTypeHandle& typeHandle, const Function& serialize, const Function& deserialize);
API_FUNCTION(NoProxy) static void AddRPC(const ScriptingTypeHandle& typeHandle, const StringAnsiView& name, const Function& execute, bool isServer, bool isClient, NetworkChannelType channel);
- API_FUNCTION(NoProxy) static void CSharpEndInvokeRPC(ScriptingObject* obj, const ScriptingTypeHandle& type, const StringAnsiView& name, NetworkStream* argsStream, MArray* targetIds);
+ API_FUNCTION(NoProxy) static bool CSharpEndInvokeRPC(ScriptingObject* obj, const ScriptingTypeHandle& type, const StringAnsiView& name, NetworkStream* argsStream, MArray* targetIds);
static StringAnsiView GetCSharpCachedName(const StringAnsiView& name);
#endif
};
diff --git a/Source/Engine/Networking/NetworkRpc.h b/Source/Engine/Networking/NetworkRpc.h
index c0c8a558e..6e8d26752 100644
--- a/Source/Engine/Networking/NetworkRpc.h
+++ b/Source/Engine/Networking/NetworkRpc.h
@@ -41,7 +41,7 @@ struct FLAXENGINE_API NetworkRpcInfo
uint8 Client : 1;
uint8 Channel : 4;
void (*Execute)(ScriptingObject* obj, NetworkStream* stream, void* tag);
- void (*Invoke)(ScriptingObject* obj, void** args);
+ bool (*Invoke)(ScriptingObject* obj, void** args);
void* Tag;
///
@@ -83,10 +83,7 @@ FORCE_INLINE void NetworkRpcInitArg(Array>& args, con
{ \
Array> args; \
NetworkRpcInitArg(args, __VA_ARGS__); \
- rpcInfo.Invoke(this, args.Get()); \
- if (rpcInfo.Server && networkMode == NetworkManagerMode::Client) \
- return; \
- if (rpcInfo.Client && networkMode == NetworkManagerMode::Server) \
+ if (rpcInfo.Invoke(this, args.Get())) \
return; \
} \
}
diff --git a/Source/Tools/Flax.Build/Build/Plugins/NetworkingPlugin.cs b/Source/Tools/Flax.Build/Build/Plugins/NetworkingPlugin.cs
index 21464ab55..b24b887b3 100644
--- a/Source/Tools/Flax.Build/Build/Plugins/NetworkingPlugin.cs
+++ b/Source/Tools/Flax.Build/Build/Plugins/NetworkingPlugin.cs
@@ -254,7 +254,7 @@ namespace Flax.Build.Plugins
// Generated method thunk to invoke RPC to network
{
- contents.Append(" static void ").Append(functionInfo.Name).AppendLine("_Invoke(ScriptingObject* obj, void** args)");
+ contents.Append(" static bool ").Append(functionInfo.Name).AppendLine("_Invoke(ScriptingObject* obj, void** args)");
contents.AppendLine(" {");
contents.AppendLine(" NetworkStream* stream = NetworkReplicator::BeginInvokeRPC();");
contents.AppendLine(" Span targetIds;");
@@ -274,7 +274,7 @@ namespace Flax.Build.Plugins
}
// Invoke RPC
- contents.AppendLine($" NetworkReplicator::EndInvokeRPC(obj, {typeInfo.NativeName}::TypeInitializer, StringAnsiView(\"{functionInfo.Name}\", {functionInfo.Name.Length}), stream, targetIds);");
+ contents.AppendLine($" return NetworkReplicator::EndInvokeRPC(obj, {typeInfo.NativeName}::TypeInitializer, StringAnsiView(\"{functionInfo.Name}\", {functionInfo.Name.Length}), stream, targetIds);");
contents.AppendLine(" }");
}
contents.AppendLine();
@@ -1753,10 +1753,10 @@ namespace Flax.Build.Plugins
if (jumpBodyEnd == null)
throw new Exception("Missing IL Return op code in method " + method.Name);
il.Emit(OpCodes.Ldloc, varsStart + 0);
- il.Emit(OpCodes.Brfalse_S, jumpIf2Start);
+ il.Emit(OpCodes.Brfalse, jumpIf2Start);
il.Emit(OpCodes.Ldloc, varsStart + 2);
il.Emit(OpCodes.Ldc_I4_2);
- il.Emit(OpCodes.Beq_S, jumpIfBodyStart);
+ il.Emit(OpCodes.Beq, jumpIfBodyStart);
// ||
il.Emit(jumpIf2Start);
il.Emit(OpCodes.Ldloc, varsStart + 1);
@@ -1812,35 +1812,12 @@ namespace Flax.Build.Plugins
else
il.Emit(OpCodes.Ldnull);
var endInvokeRPC = networkReplicatorType.Resolve().GetMethod("EndInvokeRPC", 5);
+ if (endInvokeRPC.ReturnType.FullName != boolType.FullName)
+ throw new Exception("Invalid EndInvokeRPC return type. Remove any 'Binaries' folders to force project recompile.");
il.Emit(OpCodes.Call, module.ImportReference(endInvokeRPC));
- // if (server && networkMode == NetworkManagerMode.Client) return;
- if (methodRPC.IsServer)
- {
- il.Emit(OpCodes.Nop);
- il.Emit(OpCodes.Ldloc, varsStart + 2);
- il.Emit(OpCodes.Ldc_I4_2);
- var tmp = ilp.Create(OpCodes.Nop);
- il.Emit(OpCodes.Beq_S, tmp);
- il.Emit(OpCodes.Br, jumpBodyStart);
- il.Emit(tmp);
- //il.Emit(OpCodes.Ret);
- il.Emit(OpCodes.Br, jumpBodyEnd);
- }
-
- // if (client && networkMode == NetworkManagerMode.Server) return;
- if (methodRPC.IsClient)
- {
- il.Emit(OpCodes.Nop);
- il.Emit(OpCodes.Ldloc, varsStart + 2);
- il.Emit(OpCodes.Ldc_I4_1);
- var tmp = ilp.Create(OpCodes.Nop);
- il.Emit(OpCodes.Beq_S, tmp);
- il.Emit(OpCodes.Br, jumpBodyStart);
- il.Emit(tmp);
- //il.Emit(OpCodes.Ret);
- il.Emit(OpCodes.Br, jumpBodyEnd);
- }
+ // if (EndInvokeRPC) return
+ il.Emit(OpCodes.Brtrue, jumpBodyEnd);
// Continue to original method body
il.Emit(jumpBodyStart);
From 864f5f77f5024ab6e038fd1dfd82b7027cf2d520 Mon Sep 17 00:00:00 2001
From: Wojtek Figat
Date: Wed, 28 Jun 2023 14:53:23 +0200
Subject: [PATCH 38/65] Add output binaries folder cleanp to build clear
command
---
Source/Tools/Flax.Build/Build/Builder.cs | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/Source/Tools/Flax.Build/Build/Builder.cs b/Source/Tools/Flax.Build/Build/Builder.cs
index 0765a94ab..aa0f7c879 100644
--- a/Source/Tools/Flax.Build/Build/Builder.cs
+++ b/Source/Tools/Flax.Build/Build/Builder.cs
@@ -143,6 +143,16 @@ namespace Flax.Build
{
Log.Info("Removing: " + targetBuildOptions.IntermediateFolder);
CleanDirectory(intermediateFolder);
+ intermediateFolder.Create();
+ }
+
+ // Delete all output files
+ var outputFolder = new DirectoryInfo(targetBuildOptions.OutputFolder);
+ if (outputFolder.Exists)
+ {
+ Log.Info("Removing: " + targetBuildOptions.OutputFolder);
+ CleanDirectory(outputFolder);
+ outputFolder.Create();
}
}
}
From bf6daed6d20957f2831ea8cc63399b5dd00fd325 Mon Sep 17 00:00:00 2001
From: Ari Vuollet
Date: Wed, 28 Jun 2023 15:56:42 +0300
Subject: [PATCH 39/65] Fix Intellisense errors with referenced binary module
structures
---
Source/Tools/Flax.Build/Build/Builder.Projects.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Source/Tools/Flax.Build/Build/Builder.Projects.cs b/Source/Tools/Flax.Build/Build/Builder.Projects.cs
index 2860148de..4fbabe986 100644
--- a/Source/Tools/Flax.Build/Build/Builder.Projects.cs
+++ b/Source/Tools/Flax.Build/Build/Builder.Projects.cs
@@ -330,7 +330,7 @@ namespace Flax.Build
var referenceBuildOptions = GetBuildOptions(referenceTarget, configurationData.TargetBuildOptions.Platform, configurationData.TargetBuildOptions.Toolchain, configurationData.Architecture, configurationData.Configuration, reference.Project.ProjectFolderPath);
referenceBuildOptions.Flags |= BuildFlags.GenerateProject;
var referenceModules = CollectModules(rules, referenceBuildOptions.Platform, referenceTarget, referenceBuildOptions, referenceBuildOptions.Toolchain, referenceBuildOptions.Architecture, referenceBuildOptions.Configuration);
- var referenceBinaryModules = GetBinaryModules(projectInfo, referenceTarget, referenceModules);
+ var referenceBinaryModules = referenceModules.Keys.GroupBy(x => x.BinaryModuleName).ToArray();
foreach (var binaryModule in referenceBinaryModules)
{
project.Defines.Add(binaryModule.Key.ToUpperInvariant() + "_API=");
From 9536c376234f8097a8d8154f9049ac97a5face34 Mon Sep 17 00:00:00 2001
From: Wojtek Figat
Date: Wed, 28 Jun 2023 15:12:58 +0200
Subject: [PATCH 40/65] Add ability to unset type reference with `null` item
---
Source/Editor/GUI/Popups/TypeSearchPopup.cs | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/Source/Editor/GUI/Popups/TypeSearchPopup.cs b/Source/Editor/GUI/Popups/TypeSearchPopup.cs
index 9d9ee2040..73c5baab7 100644
--- a/Source/Editor/GUI/Popups/TypeSearchPopup.cs
+++ b/Source/Editor/GUI/Popups/TypeSearchPopup.cs
@@ -27,6 +27,17 @@ namespace FlaxEditor.GUI
///
public ScriptType Type => _type;
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public TypeItemView()
+ {
+ _type = ScriptType.Null;
+ Name = "";
+ TooltipText = "Unset value.";
+ Tag = _type;
+ }
+
///
/// Initializes a new instance of the class.
///
@@ -83,6 +94,7 @@ namespace FlaxEditor.GUI
// TODO: use async thread to search types without UI stall
var allTypes = Editor.Instance.CodeEditing.All.Get();
+ AddItem(new TypeItemView());
for (int i = 0; i < allTypes.Count; i++)
{
var type = allTypes[i];
From 890248edf218e81466f07c2dbf69a41f53f22230 Mon Sep 17 00:00:00 2001
From: Wojtek Figat
Date: Wed, 28 Jun 2023 15:13:33 +0200
Subject: [PATCH 41/65] Fix `MClass::HasInterface` in .NET 7
---
Source/Engine/Scripting/Runtime/DotNet.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Source/Engine/Scripting/Runtime/DotNet.cpp b/Source/Engine/Scripting/Runtime/DotNet.cpp
index 1736cc106..246c1620f 100644
--- a/Source/Engine/Scripting/Runtime/DotNet.cpp
+++ b/Source/Engine/Scripting/Runtime/DotNet.cpp
@@ -846,7 +846,7 @@ bool MClass::IsSubClassOf(const MClass* klass, bool checkInterfaces) const
bool MClass::HasInterface(const MClass* klass) const
{
static void* TypeIsAssignableFrom = GetStaticMethodPointer(TEXT("TypeIsAssignableFrom"));
- return klass && CallStaticMethod(TypeIsAssignableFrom, _handle, klass->_handle);
+ return klass && CallStaticMethod(TypeIsAssignableFrom, klass->_handle, _handle);
}
bool MClass::IsInstanceOfType(MObject* object) const
From c44e97c8bc8ea413056412e5a0e747a295e94835 Mon Sep 17 00:00:00 2001
From: Wojtek Figat
Date: Wed, 28 Jun 2023 15:22:48 +0200
Subject: [PATCH 42/65] Bump build number
---
Flax.flaxproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flax.flaxproj b/Flax.flaxproj
index d8e86b1ed..7cebe1714 100644
--- a/Flax.flaxproj
+++ b/Flax.flaxproj
@@ -3,7 +3,7 @@
"Version": {
"Major": 1,
"Minor": 6,
- "Build": 6342
+ "Build": 6343
},
"Company": "Flax",
"Copyright": "Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.",
From bb3cefbe54d14182c971bced908d1ff4f1bec4ee Mon Sep 17 00:00:00 2001
From: Wojtek Figat
Date: Wed, 28 Jun 2023 15:48:32 +0200
Subject: [PATCH 43/65] Add check for `NetworkClientsMask` to ensure it has
capacity
---
Source/Engine/Networking/NetworkReplicator.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/Source/Engine/Networking/NetworkReplicator.cpp b/Source/Engine/Networking/NetworkReplicator.cpp
index ae7549a50..daf2537f4 100644
--- a/Source/Engine/Networking/NetworkReplicator.cpp
+++ b/Source/Engine/Networking/NetworkReplicator.cpp
@@ -1151,6 +1151,7 @@ void NetworkInternal::NetworkReplicatorClientConnected(NetworkClient* client)
{
ScopeLock lock(ObjectsLock);
NewClients.Add(client);
+ ASSERT(sizeof(NetworkClientsMask) * 8 >= (uint32)NetworkManager::Clients.Count()); // Ensure that clients mask can hold all of clients
}
void NetworkInternal::NetworkReplicatorClientDisconnected(NetworkClient* client)
From 45a1d336899fb689d3ec8856719c881ec7a91069 Mon Sep 17 00:00:00 2001
From: Ruan Lucas <79365912+RuanLucasGD@users.noreply.github.com>
Date: Wed, 28 Jun 2023 09:56:15 -0400
Subject: [PATCH 44/65] fix orientation
---
Source/Engine/Physics/Actors/WheeledVehicle.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Source/Engine/Physics/Actors/WheeledVehicle.cpp b/Source/Engine/Physics/Actors/WheeledVehicle.cpp
index 995150bdc..f5f729d39 100644
--- a/Source/Engine/Physics/Actors/WheeledVehicle.cpp
+++ b/Source/Engine/Physics/Actors/WheeledVehicle.cpp
@@ -230,7 +230,7 @@ void WheeledVehicle::DrawPhysicsDebug(RenderView& view)
{
const Vector3 currentPos = wheel.Collider->GetPosition();
const Vector3 basePos = currentPos - Vector3(0, data.State.SuspensionOffset, 0);
- const Quaternion wheelDebugOrientation = wheel.Collider->GetOrientation() * Quaternion::Euler(90, 0, 90);
+ const Quaternion wheelDebugOrientation = GetOrientation() * Quaternion::Euler(-data.State.RotationAngle, data.State.SteerAngle, 0) * Quaternion::Euler(90, 0, 90);
DEBUG_DRAW_WIRE_SPHERE(BoundingSphere(basePos, wheel.Radius * 0.07f), Color::Blue * 0.3f, 0, true);
DEBUG_DRAW_WIRE_SPHERE(BoundingSphere(currentPos, wheel.Radius * 0.08f), Color::Blue * 0.8f, 0, true);
DEBUG_DRAW_LINE(basePos, currentPos, Color::Blue, 0, true);
@@ -261,7 +261,7 @@ void WheeledVehicle::OnDebugDrawSelected()
{
const Vector3 currentPos = wheel.Collider->GetPosition();
const Vector3 basePos = currentPos - Vector3(0, data.State.SuspensionOffset, 0);
- const Quaternion wheelDebugOrientation = wheel.Collider->GetOrientation() * Quaternion::Euler(90, 0, 90);
+ const Quaternion wheelDebugOrientation = GetOrientation() * Quaternion::Euler(-data.State.RotationAngle, data.State.SteerAngle, 0) * Quaternion::Euler(90, 0, 90);
Transform actorPose = Transform::Identity, shapePose = Transform::Identity;
PhysicsBackend::GetRigidActorPose(_actor, actorPose.Translation, actorPose.Orientation);
PhysicsBackend::GetShapeLocalPose(wheel.Collider->GetPhysicsShape(), shapePose.Translation, shapePose.Orientation);
From bb9711277ae8094323f255c514bd66e222542c67 Mon Sep 17 00:00:00 2001
From: Wojtek Figat
Date: Wed, 28 Jun 2023 16:27:42 +0200
Subject: [PATCH 45/65] Cleanup code from #1213
---
.../Viewport/Previews/AnimatedModelPreview.cs | 12 +--
.../Viewport/Previews/MaterialPreview.cs | 48 +++++------
.../Viewport/Previews/ModelBasePreview.cs | 8 +-
.../Editor/Viewport/Previews/ModelPreview.cs | 79 ++++++++-----------
.../Viewport/Previews/SkinnedModelPreview.cs | 65 +++++++--------
.../Windows/Assets/CollisionDataWindow.cs | 4 +-
Source/Editor/Windows/Assets/ModelWindow.cs | 4 +-
.../Windows/Assets/SkinnedModelWindow.cs | 6 +-
8 files changed, 88 insertions(+), 138 deletions(-)
diff --git a/Source/Editor/Viewport/Previews/AnimatedModelPreview.cs b/Source/Editor/Viewport/Previews/AnimatedModelPreview.cs
index aae48fe11..4a1c57757 100644
--- a/Source/Editor/Viewport/Previews/AnimatedModelPreview.cs
+++ b/Source/Editor/Viewport/Previews/AnimatedModelPreview.cs
@@ -3,8 +3,6 @@
using System;
using FlaxEditor.GUI.ContextMenu;
using FlaxEngine;
-using FlaxEditor.GUI.Input;
-using FlaxEngine.GUI;
using Object = FlaxEngine.Object;
namespace FlaxEditor.Viewport.Previews
@@ -15,13 +13,10 @@ namespace FlaxEditor.Viewport.Previews
///
public class AnimatedModelPreview : AssetPreview
{
- ///
public AnimatedModel _previewModel;
-
private ContextMenuButton _showNodesButton, _showBoundsButton, _showFloorButton, _showNodesNamesButton;
private bool _showNodes, _showBounds, _showFloor, _showNodesNames;
private StaticModel _floorModel;
-
private bool _playAnimation, _playAnimationOnce;
private float _playSpeed = 1.0f;
@@ -404,9 +399,9 @@ namespace FlaxEditor.Viewport.Previews
}
///
- /// Calls SetArcBallView from ViewportCamera
+ /// Resets the camera to focus on a object.
///
- public void CallSetArcBallView()
+ public void ResetCamera()
{
ViewportCamera.SetArcBallView(_previewModel.Box);
}
@@ -417,8 +412,7 @@ namespace FlaxEditor.Viewport.Previews
switch (key)
{
case KeyboardKeys.F:
- // Pay respect..
- CallSetArcBallView();
+ ResetCamera();
return true;
case KeyboardKeys.Spacebar:
PlayAnimation = !PlayAnimation;
diff --git a/Source/Editor/Viewport/Previews/MaterialPreview.cs b/Source/Editor/Viewport/Previews/MaterialPreview.cs
index 3dfab1cff..5520d6c4c 100644
--- a/Source/Editor/Viewport/Previews/MaterialPreview.cs
+++ b/Source/Editor/Viewport/Previews/MaterialPreview.cs
@@ -48,6 +48,7 @@ namespace FlaxEditor.Viewport.Previews
private int _selectedModelIndex;
private Image _guiMaterialControl;
private readonly MaterialBase[] _postFxMaterialsCache = new MaterialBase[1];
+ private ContextMenu _modelWidgetButtonMenu;
///
/// Gets or sets the material asset to preview. It can be or .
@@ -65,11 +66,6 @@ namespace FlaxEditor.Viewport.Previews
}
}
- ///
- /// The "Model" widget button context menu.
- ///
- private ContextMenu modelWidgetButtonMenu;
-
///
/// Gets or sets the selected preview model index.
///
@@ -87,27 +83,6 @@ namespace FlaxEditor.Viewport.Previews
}
}
- ///
- /// Fill out all models
- ///
- ///
- private void ModelWidgetMenuOnVisibleChanged(Control control)
- {
- if (!control.Visible) return;
-
- modelWidgetButtonMenu.ItemsContainer.DisposeChildren();
-
- // Fill out all models
- for (int i = 0; i < Models.Length; i++)
- {
- var index = i;
- var button = modelWidgetButtonMenu.AddButton(Models[index]);
- button.ButtonClicked += (button) => SelectedModelIndex = index;
- button.Checked = SelectedModelIndex == index;
- button.Tag = index;
- }
- }
-
///
/// Initializes a new instance of the class.
///
@@ -127,9 +102,24 @@ namespace FlaxEditor.Viewport.Previews
{
// Model mode widget
var modelMode = new ViewportWidgetsContainer(ViewportWidgetLocation.UpperRight);
- modelWidgetButtonMenu = new ContextMenu();
- modelWidgetButtonMenu.VisibleChanged += ModelWidgetMenuOnVisibleChanged;
- var previewLODSModeButton = new ViewportWidgetButton("Model", SpriteHandle.Invalid, modelWidgetButtonMenu)
+ _modelWidgetButtonMenu = new ContextMenu();
+ _modelWidgetButtonMenu.VisibleChanged += control =>
+ {
+ if (!control.Visible)
+ return;
+ _modelWidgetButtonMenu.ItemsContainer.DisposeChildren();
+
+ // Fill out all models
+ for (int i = 0; i < Models.Length; i++)
+ {
+ var index = i;
+ var button = _modelWidgetButtonMenu.AddButton(Models[index]);
+ button.ButtonClicked += _ => SelectedModelIndex = index;
+ button.Checked = SelectedModelIndex == index;
+ button.Tag = index;
+ }
+ };
+ new ViewportWidgetButton("Model", SpriteHandle.Invalid, _modelWidgetButtonMenu)
{
TooltipText = "Change material model",
Parent = modelMode,
diff --git a/Source/Editor/Viewport/Previews/ModelBasePreview.cs b/Source/Editor/Viewport/Previews/ModelBasePreview.cs
index e5834edc9..e4f1109d4 100644
--- a/Source/Editor/Viewport/Previews/ModelBasePreview.cs
+++ b/Source/Editor/Viewport/Previews/ModelBasePreview.cs
@@ -1,6 +1,5 @@
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
-using FlaxEditor.GUI.Input;
using FlaxEngine;
using Object = FlaxEngine.Object;
@@ -59,9 +58,9 @@ namespace FlaxEditor.Viewport.Previews
}
///
- /// Calls SetArcBallView from ViewportCamera
+ /// Resets the camera to focus on a object.
///
- public void CallSetArcBallView()
+ public void ResetCamera()
{
ViewportCamera.SetArcBallView(StaticModel.Model != null ? StaticModel.Box : AnimatedModel.Box);
}
@@ -92,8 +91,7 @@ namespace FlaxEditor.Viewport.Previews
switch (key)
{
case KeyboardKeys.F:
- // Pay respect..
- CallSetArcBallView();
+ ResetCamera();
break;
}
return base.OnKeyDown(key);
diff --git a/Source/Editor/Viewport/Previews/ModelPreview.cs b/Source/Editor/Viewport/Previews/ModelPreview.cs
index dc0de37da..a0b6d0ca0 100644
--- a/Source/Editor/Viewport/Previews/ModelPreview.cs
+++ b/Source/Editor/Viewport/Previews/ModelPreview.cs
@@ -1,7 +1,6 @@
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
using FlaxEditor.GUI.ContextMenu;
-using FlaxEditor.GUI.Input;
using FlaxEngine;
using FlaxEngine.GUI;
using FlaxEngine.Utilities;
@@ -17,15 +16,11 @@ namespace FlaxEditor.Viewport.Previews
public class ModelPreview : AssetPreview
{
private ContextMenuButton _showBoundsButton, _showCurrentLODButton, _showNormalsButton, _showTangentsButton, _showBitangentsButton, _showFloorButton;
+ private ContextMenu _previewLODsWidgetButtonMenu;
private StaticModel _previewModel, _floorModel;
private bool _showBounds, _showCurrentLOD, _showNormals, _showTangents, _showBitangents, _showFloor;
private MeshDataCache _meshDatas;
- ///
- /// The "PreviewLODS" widget button context menu.
- ///
- private ContextMenu previewLODSWidgetButtonMenu;
-
///
/// Gets or sets a value that shows LOD statistics
///
@@ -37,8 +32,6 @@ namespace FlaxEditor.Viewport.Previews
if (_showCurrentLOD == value)
return;
_showCurrentLOD = value;
- if (value)
- ShowDebugDraw = true;
if (_showCurrentLODButton != null)
_showCurrentLODButton.Checked = value;
}
@@ -222,42 +215,36 @@ namespace FlaxEditor.Viewport.Previews
});
_showCurrentLODButton.IndexInParent = 2;
- // PreviewLODS mode widget
- var PreviewLODSMode = new ViewportWidgetsContainer(ViewportWidgetLocation.UpperRight);
- previewLODSWidgetButtonMenu = new ContextMenu();
- previewLODSWidgetButtonMenu.VisibleChanged += PreviewLODSWidgetMenuOnVisibleChanged;
- var previewLODSModeButton = new ViewportWidgetButton("Preview LOD", SpriteHandle.Invalid, previewLODSWidgetButtonMenu)
+ // Preview LODs mode widget
+ var PreviewLODsMode = new ViewportWidgetsContainer(ViewportWidgetLocation.UpperRight);
+ _previewLODsWidgetButtonMenu = new ContextMenu();
+ _previewLODsWidgetButtonMenu.VisibleChanged += control =>
+ {
+ if (!control.Visible)
+ return;
+ var model = _previewModel.Model;
+ if (model && !model.WaitForLoaded())
+ {
+ _previewLODsWidgetButtonMenu.ItemsContainer.DisposeChildren();
+ var lods = model.LODs.Length;
+ for (int i = -1; i < lods; i++)
+ {
+ var index = i;
+ var button = _previewLODsWidgetButtonMenu.AddButton("LOD " + (index == -1 ? "Auto" : index));
+ button.ButtonClicked += _ => _previewModel.ForcedLOD = index;
+ button.Checked = _previewModel.ForcedLOD == index;
+ button.Tag = index;
+ if (lods <= 1)
+ break;
+ }
+ }
+ };
+ new ViewportWidgetButton("Preview LOD", SpriteHandle.Invalid, _previewLODsWidgetButtonMenu)
{
TooltipText = "Preview LOD properties",
- Parent = PreviewLODSMode,
+ Parent = PreviewLODsMode,
};
- PreviewLODSMode.Parent = this;
- }
- }
-
- ///
- /// Fill out all Model LODS
- ///
- ///
- private void PreviewLODSWidgetMenuOnVisibleChanged(Control control)
- {
- if (!control.Visible)
- return;
-
- var model = _previewModel.Model;
- if (model && !model.WaitForLoaded() && model.IsLoaded)
- {
- previewLODSWidgetButtonMenu.ItemsContainer.DisposeChildren();
- var lods = model.LODs.Length;
- for (int i = -1; i < lods; i++)
- {
- var index = i;
- var button = previewLODSWidgetButtonMenu.AddButton("LOD " + (index == -1 ? "Auto" : index));
- button.ButtonClicked += (button) => _previewModel.ForcedLOD = index;
- button.Checked = _previewModel.ForcedLOD == index;
- button.Tag = index;
- if (lods <= 1) return;
- }
+ PreviewLODsMode.Parent = this;
}
}
@@ -361,7 +348,7 @@ namespace FlaxEditor.Viewport.Previews
var distSqr = Vector3.DistanceSquared(ref sphere.Center, ref viewOrigin);
var screenRadiusSquared = Mathf.Square(screenMultiple * sphere.Radius) / Mathf.Max(1.0f, distSqr);
screenSize = Mathf.Sqrt((float)screenRadiusSquared) * 2.0f;
-
+
// Check if model is being culled
if (Mathf.Square(model.MinScreenSize * 0.5f) > screenRadiusSquared)
return -1;
@@ -422,9 +409,9 @@ namespace FlaxEditor.Viewport.Previews
}
///
- /// Calls SetArcBallView from ViewportCamera
+ /// Resets the camera to focus on a object.
///
- public void CallSetArcBallView()
+ public void ResetCamera()
{
ViewportCamera.SetArcBallView(_previewModel.Box);
}
@@ -435,8 +422,7 @@ namespace FlaxEditor.Viewport.Previews
switch (key)
{
case KeyboardKeys.F:
- // Pay respect..
- CallSetArcBallView();
+ ResetCamera();
break;
}
return base.OnKeyDown(key);
@@ -449,6 +435,7 @@ namespace FlaxEditor.Viewport.Previews
Object.Destroy(ref _previewModel);
_showBoundsButton = null;
_showCurrentLODButton = null;
+ _previewLODsWidgetButtonMenu = null;
_showNormalsButton = null;
_showTangentsButton = null;
_showBitangentsButton = null;
diff --git a/Source/Editor/Viewport/Previews/SkinnedModelPreview.cs b/Source/Editor/Viewport/Previews/SkinnedModelPreview.cs
index a8b98b423..c11ea9ea4 100644
--- a/Source/Editor/Viewport/Previews/SkinnedModelPreview.cs
+++ b/Source/Editor/Viewport/Previews/SkinnedModelPreview.cs
@@ -1,4 +1,5 @@
-using System;
+// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
+
using FlaxEditor.GUI.ContextMenu;
using FlaxEngine;
using FlaxEngine.GUI;
@@ -14,11 +15,7 @@ namespace FlaxEditor.Viewport.Previews
{
private bool _showCurrentLOD;
private ContextMenuButton _showCurrentLODButton;
-
- ///
- /// The "PreviewLODS" widget button context menu.
- ///
- private ContextMenu previewLODSWidgetButtonMenu;
+ private ContextMenu _previewLODsWidgetButtonMenu;
///
/// Gets or sets a value that shows LOD statistics
@@ -31,8 +28,6 @@ namespace FlaxEditor.Viewport.Previews
if (_showCurrentLOD == value)
return;
_showCurrentLOD = value;
- if (value)
- ShowDebugDraw = true;
if (_showCurrentLODButton != null)
_showCurrentLODButton.Checked = value;
}
@@ -57,9 +52,29 @@ namespace FlaxEditor.Viewport.Previews
// PreviewLODS mode widget
var PreviewLODSMode = new ViewportWidgetsContainer(ViewportWidgetLocation.UpperRight);
- previewLODSWidgetButtonMenu = new ContextMenu();
- previewLODSWidgetButtonMenu.VisibleChanged += PreviewLODSWidgetMenuOnVisibleChanged;
- var previewLODSModeButton = new ViewportWidgetButton("Preview LOD", SpriteHandle.Invalid, previewLODSWidgetButtonMenu)
+ _previewLODsWidgetButtonMenu = new ContextMenu();
+ _previewLODsWidgetButtonMenu.VisibleChanged += control =>
+ {
+ if (!control.Visible)
+ return;
+ var skinned = _previewModel.SkinnedModel;
+ if (skinned && !skinned.WaitForLoaded())
+ {
+ _previewLODsWidgetButtonMenu.ItemsContainer.DisposeChildren();
+ var lods = skinned.LODs.Length;
+ for (int i = -1; i < lods; i++)
+ {
+ var index = i;
+ var button = _previewLODsWidgetButtonMenu.AddButton("LOD " + (index == -1 ? "Auto" : index));
+ button.ButtonClicked += (button) => _previewModel.ForcedLOD = index;
+ button.Checked = _previewModel.ForcedLOD == index;
+ button.Tag = index;
+ if (lods <= 1)
+ break;
+ }
+ }
+ };
+ new ViewportWidgetButton("Preview LOD", SpriteHandle.Invalid, _previewLODsWidgetButtonMenu)
{
TooltipText = "Preview LOD properties",
Parent = PreviewLODSMode,
@@ -68,33 +83,6 @@ namespace FlaxEditor.Viewport.Previews
}
}
- ///
- /// Fill out all SkinnedModel LODS
- ///
- ///
- private void PreviewLODSWidgetMenuOnVisibleChanged(Control control)
- {
- if (!control.Visible)
- return;
-
- var skinned = _previewModel.SkinnedModel;
- if (skinned && !skinned.WaitForLoaded() && skinned.IsLoaded)
- {
- previewLODSWidgetButtonMenu.ItemsContainer.DisposeChildren();
- var lods = skinned.LODs.Length;
- for (int i = -1; i < lods; i++)
- {
- var index = i;
- var button = previewLODSWidgetButtonMenu.AddButton("LOD " + (index == -1 ? "Auto" : index));
- button.ButtonClicked += (button) => _previewModel.ForcedLOD = index;
- button.Checked = _previewModel.ForcedLOD == index;
- button.Tag = index;
- if (lods <= 1) return;
- }
- }
- }
-
- ///
private int ComputeLODIndex(SkinnedModel model, out float screenSize)
{
screenSize = 1.0f;
@@ -181,6 +169,7 @@ namespace FlaxEditor.Viewport.Previews
public override void OnDestroy()
{
_showCurrentLODButton = null;
+ _previewLODsWidgetButtonMenu = null;
base.OnDestroy();
}
diff --git a/Source/Editor/Windows/Assets/CollisionDataWindow.cs b/Source/Editor/Windows/Assets/CollisionDataWindow.cs
index 82e0681fa..cc1daa45b 100644
--- a/Source/Editor/Windows/Assets/CollisionDataWindow.cs
+++ b/Source/Editor/Windows/Assets/CollisionDataWindow.cs
@@ -182,9 +182,7 @@ namespace FlaxEditor.Windows.Assets
{
// Toolstrip
_toolstrip.AddSeparator();
-
- _toolstrip.AddButton(editor.Icons.CenterView64, () => _preview.CallSetArcBallView()).LinkTooltip("Show whole collision");
-
+ _toolstrip.AddButton(editor.Icons.CenterView64, () => _preview.ResetCamera()).LinkTooltip("Show whole collision");
_toolstrip.AddButton(editor.Icons.Docs64, () => Platform.OpenUrl(Utilities.Constants.DocsUrl + "manual/physics/colliders/collision-data.html")).LinkTooltip("See documentation to learn more");
// Split Panel
diff --git a/Source/Editor/Windows/Assets/ModelWindow.cs b/Source/Editor/Windows/Assets/ModelWindow.cs
index cc7657fc7..f70f6a3b5 100644
--- a/Source/Editor/Windows/Assets/ModelWindow.cs
+++ b/Source/Editor/Windows/Assets/ModelWindow.cs
@@ -788,9 +788,7 @@ namespace FlaxEditor.Windows.Assets
// Toolstrip
_toolstrip.AddSeparator();
_showCurrentLODButton = (ToolStripButton)_toolstrip.AddButton(editor.Icons.Info64, () => _preview.ShowCurrentLOD = !_preview.ShowCurrentLOD).LinkTooltip("Show LOD statistics");
-
- _toolstrip.AddButton(editor.Icons.CenterView64, () => _preview.CallSetArcBallView()).LinkTooltip("Show whole model");
-
+ _toolstrip.AddButton(editor.Icons.CenterView64, () => _preview.ResetCamera()).LinkTooltip("Show whole model");
_toolstrip.AddSeparator();
_toolstrip.AddButton(editor.Icons.Docs64, () => Platform.OpenUrl(Utilities.Constants.DocsUrl + "manual/graphics/models/index.html")).LinkTooltip("See documentation to learn more");
diff --git a/Source/Editor/Windows/Assets/SkinnedModelWindow.cs b/Source/Editor/Windows/Assets/SkinnedModelWindow.cs
index 367fc3a1a..a7ee6e767 100644
--- a/Source/Editor/Windows/Assets/SkinnedModelWindow.cs
+++ b/Source/Editor/Windows/Assets/SkinnedModelWindow.cs
@@ -1117,13 +1117,9 @@ namespace FlaxEditor.Windows.Assets
{
// Toolstrip
_toolstrip.AddSeparator();
-
_showCurrentLODButton = (ToolStripButton)_toolstrip.AddButton(editor.Icons.Info64, () => _preview.ShowCurrentLOD = !_preview.ShowCurrentLOD).LinkTooltip("Show LOD statistics");
-
_showNodesButton = (ToolStripButton)_toolstrip.AddButton(editor.Icons.Bone64, () => _preview.ShowNodes = !_preview.ShowNodes).LinkTooltip("Show animated model nodes debug view");
-
- _toolstrip.AddButton(editor.Icons.CenterView64, () => _preview.CallSetArcBallView()).LinkTooltip("Show whole model");
-
+ _toolstrip.AddButton(editor.Icons.CenterView64, () => _preview.ResetCamera()).LinkTooltip("Show whole model");
_toolstrip.AddSeparator();
_toolstrip.AddButton(editor.Icons.Docs64, () => Platform.OpenUrl(Utilities.Constants.DocsUrl + "manual/animation/skinned-model/index.html")).LinkTooltip("See documentation to learn more");
From ac54838eea13d6caafb2c3dda75317d0f9becf69 Mon Sep 17 00:00:00 2001
From: Wojtek Figat
Date: Wed, 28 Jun 2023 18:46:46 +0200
Subject: [PATCH 46/65] Fix custom editor window restore after hot-reload
#1208
---
Source/Editor/CustomEditorWindow.cs | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/Source/Editor/CustomEditorWindow.cs b/Source/Editor/CustomEditorWindow.cs
index 2d5293f30..242b4d28d 100644
--- a/Source/Editor/CustomEditorWindow.cs
+++ b/Source/Editor/CustomEditorWindow.cs
@@ -3,7 +3,6 @@
using FlaxEditor.CustomEditors;
using FlaxEditor.Windows;
using FlaxEngine.GUI;
-using FlaxEngine;
using DockState = FlaxEditor.GUI.Docking.DockState;
namespace FlaxEditor
@@ -86,8 +85,12 @@ namespace FlaxEditor
if (!FlaxEngine.Scripting.IsTypeFromGameScripts(type))
return;
- Editor.Instance.Windows.AddToRestore(this);
+ if (!Window.IsHidden)
+ {
+ Editor.Instance.Windows.AddToRestore(this);
+ }
Window.Close();
+ Window.Dispose();
}
///
From 70ab159dd4bc518d41ff5811bdb30840a537ec8f Mon Sep 17 00:00:00 2001
From: Wojtek Figat
Date: Wed, 28 Jun 2023 19:55:10 +0200
Subject: [PATCH 47/65] Fix empty clients mask for
`NetworkReplicationHierarchy` on client to properly replicate client-owned
objects
#1205
---
Source/Engine/Networking/NetworkReplicationHierarchy.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Source/Engine/Networking/NetworkReplicationHierarchy.cpp b/Source/Engine/Networking/NetworkReplicationHierarchy.cpp
index 5097b6a26..6ec5e52c2 100644
--- a/Source/Engine/Networking/NetworkReplicationHierarchy.cpp
+++ b/Source/Engine/Networking/NetworkReplicationHierarchy.cpp
@@ -23,7 +23,7 @@ void NetworkReplicationHierarchyUpdateResult::Init()
{
_clientsHaveLocation = false;
_clients.Resize(NetworkManager::Clients.Count());
- _clientsMask = NetworkClientsMask();
+ _clientsMask = NetworkManager::Mode == NetworkManagerMode::Client ? NetworkClientsMask::All : NetworkClientsMask();
for (int32 i = 0; i < _clients.Count(); i++)
_clientsMask.SetBit(i);
_entries.Clear();
From 04c1cf469d12d86a6f69ce7d70f667adf07cde98 Mon Sep 17 00:00:00 2001
From: Wojtek Figat
Date: Wed, 28 Jun 2023 20:08:35 +0200
Subject: [PATCH 48/65] Fix codegen for C++ RPS with Array ParameterDefinition
#1209
---
Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs | 2 +-
Source/Tools/Flax.Build/Bindings/TypeInfo.cs | 6 +++---
Source/Tools/Flax.Build/Build/Plugins/NetworkingPlugin.cs | 4 ++--
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs
index 0cb8982a2..d69b8dcbf 100644
--- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs
+++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs
@@ -1204,7 +1204,7 @@ namespace Flax.Build.Bindings
if (apiType != null)
{
if (parameterInfo.IsOut)
- contents.Append(indent).AppendFormat("{1} {0}Temp;", parameterInfo.Name, new TypeInfo(parameterInfo.Type) { IsRef = false }.GetFullNameNative(buildData, caller)).AppendLine();
+ contents.Append(indent).AppendFormat("{1} {0}Temp;", parameterInfo.Name, parameterInfo.Type.GetFullNameNative(buildData, caller, false)).AppendLine();
else
contents.Append(indent).AppendFormat("auto {0}Temp = {1};", parameterInfo.Name, param).AppendLine();
if (parameterInfo.Type.IsPtr && !parameterInfo.Type.IsRef)
diff --git a/Source/Tools/Flax.Build/Bindings/TypeInfo.cs b/Source/Tools/Flax.Build/Bindings/TypeInfo.cs
index 7b2326527..df47c85e4 100644
--- a/Source/Tools/Flax.Build/Bindings/TypeInfo.cs
+++ b/Source/Tools/Flax.Build/Bindings/TypeInfo.cs
@@ -144,7 +144,7 @@ namespace Flax.Build.Bindings
GenericArgs = BindingsGenerator.Read(reader, GenericArgs);
}
- public string GetFullNameNative(Builder.BuildData buildData, ApiTypeInfo caller)
+ public string GetFullNameNative(Builder.BuildData buildData, ApiTypeInfo caller, bool canRef = true, bool canConst = true)
{
var type = BindingsGenerator.FindApiTypeInfo(buildData, this, caller);
if (type == null)
@@ -155,7 +155,7 @@ namespace Flax.Build.Bindings
return type.FullNameNative;
var sb = new StringBuilder(64);
- if (IsConst)
+ if (IsConst && canConst)
sb.Append("const ");
sb.Append(type.FullNameNative);
if (GenericArgs != null)
@@ -171,7 +171,7 @@ namespace Flax.Build.Bindings
}
if (IsPtr)
sb.Append('*');
- if (IsRef)
+ if (IsRef && canRef)
sb.Append('&');
return sb.ToString();
}
diff --git a/Source/Tools/Flax.Build/Build/Plugins/NetworkingPlugin.cs b/Source/Tools/Flax.Build/Build/Plugins/NetworkingPlugin.cs
index b24b887b3..d76fc43cc 100644
--- a/Source/Tools/Flax.Build/Build/Plugins/NetworkingPlugin.cs
+++ b/Source/Tools/Flax.Build/Build/Plugins/NetworkingPlugin.cs
@@ -241,7 +241,7 @@ namespace Flax.Build.Plugins
// Deserialize arguments
argNames += arg.Name;
- contents.AppendLine($" {arg.Type.Type} {arg.Name};");
+ contents.AppendLine($" {arg.Type.GetFullNameNative(buildData, typeInfo, false, false)} {arg.Name};");
contents.AppendLine($" stream->Read({arg.Name});");
}
@@ -270,7 +270,7 @@ namespace Flax.Build.Plugins
}
// Serialize arguments
- contents.AppendLine($" stream->Write(*({arg.Type.Type}*)args[{i}]);");
+ contents.AppendLine($" stream->Write(*(const {arg.Type.GetFullNameNative(buildData, typeInfo, false, false)}*)args[{i}]);");
}
// Invoke RPC
From 3119c507899961b7ad141479f7d20b6d07e7d677 Mon Sep 17 00:00:00 2001
From: Wojtek Figat
Date: Wed, 28 Jun 2023 20:09:01 +0200
Subject: [PATCH 49/65] Fix nullable warnings
---
Source/Editor/ProjectInfo.cs | 4 ++--
.../Engine/Engine/NativeInterop.Marshallers.cs | 18 +++++++++---------
Source/Engine/Engine/NativeInterop.cs | 2 +-
Source/Engine/Utilities/Utils.cs | 2 +-
4 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/Source/Editor/ProjectInfo.cs b/Source/Editor/ProjectInfo.cs
index ed9470c35..b00c4e042 100644
--- a/Source/Editor/ProjectInfo.cs
+++ b/Source/Editor/ProjectInfo.cs
@@ -20,7 +20,7 @@ namespace FlaxEditor
/// The to write to.
/// The value.
/// The calling serializer.
- public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
+ public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null)
{
@@ -44,7 +44,7 @@ namespace FlaxEditor
/// The existing property value of the JSON that is being converted.
/// The calling serializer.
/// The object value.
- public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
+ public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
diff --git a/Source/Engine/Engine/NativeInterop.Marshallers.cs b/Source/Engine/Engine/NativeInterop.Marshallers.cs
index a3531d11d..0a23bfcbd 100644
--- a/Source/Engine/Engine/NativeInterop.Marshallers.cs
+++ b/Source/Engine/Engine/NativeInterop.Marshallers.cs
@@ -350,14 +350,14 @@ namespace FlaxEngine.Interop
#endif
public static class NativeToManaged
{
- public static T[]? AllocateContainerForManagedElements(TUnmanagedElement* unmanaged, int numElements)
+ public static T[] AllocateContainerForManagedElements(TUnmanagedElement* unmanaged, int numElements)
{
if (unmanaged is null)
return null;
return new T[numElements];
}
- public static Span GetManagedValuesDestination(T[]? managed) => managed;
+ public static Span GetManagedValuesDestination(T[] managed) => managed;
public static ReadOnlySpan GetUnmanagedValuesSource(TUnmanagedElement* unmanaged, int numElements)
{
@@ -390,7 +390,7 @@ namespace FlaxEngine.Interop
#endif
public static class ManagedToNative
{
- public static TUnmanagedElement* AllocateContainerForUnmanagedElements(T[]? managed, out int numElements)
+ public static TUnmanagedElement* AllocateContainerForUnmanagedElements(T[] managed, out int numElements)
{
if (managed is null)
{
@@ -402,7 +402,7 @@ namespace FlaxEngine.Interop
return (TUnmanagedElement*)ManagedHandle.ToIntPtr(managedArray, GCHandleType.Weak);
}
- public static ReadOnlySpan GetManagedValuesSource(T[]? managed) => managed;
+ public static ReadOnlySpan GetManagedValuesSource(T[] managed) => managed;
public static Span GetUnmanagedValuesDestination(TUnmanagedElement* unmanaged, int numElements)
{
@@ -431,7 +431,7 @@ namespace FlaxEngine.Interop
ManagedArray unmanagedArray;
ManagedHandle handle;
- public void FromManaged(T[]? managed)
+ public void FromManaged(T[] managed)
{
if (managed == null)
return;
@@ -476,7 +476,7 @@ namespace FlaxEngine.Interop
}
}
- public static TUnmanagedElement* AllocateContainerForUnmanagedElements(T[]? managed, out int numElements)
+ public static TUnmanagedElement* AllocateContainerForUnmanagedElements(T[] managed, out int numElements)
{
if (managed is null)
{
@@ -489,7 +489,7 @@ namespace FlaxEngine.Interop
return (TUnmanagedElement*)handle;
}
- public static ReadOnlySpan GetManagedValuesSource(T[]? managed) => managed;
+ public static ReadOnlySpan GetManagedValuesSource(T[] managed) => managed;
public static Span GetUnmanagedValuesDestination(TUnmanagedElement* unmanaged, int numElements)
{
@@ -499,9 +499,9 @@ namespace FlaxEngine.Interop
return unmanagedArray.ToSpan();
}
- public static T[]? AllocateContainerForManagedElements(TUnmanagedElement* unmanaged, int numElements) => unmanaged is null ? null : new T[numElements];
+ public static T[] AllocateContainerForManagedElements(TUnmanagedElement* unmanaged, int numElements) => unmanaged is null ? null : new T[numElements];
- public static Span GetManagedValuesDestination(T[]? managed) => managed;
+ public static Span GetManagedValuesDestination(T[] managed) => managed;
public static ReadOnlySpan GetUnmanagedValuesSource(TUnmanagedElement* unmanaged, int numElements)
{
diff --git a/Source/Engine/Engine/NativeInterop.cs b/Source/Engine/Engine/NativeInterop.cs
index faa19d060..4aedbe171 100644
--- a/Source/Engine/Engine/NativeInterop.cs
+++ b/Source/Engine/Engine/NativeInterop.cs
@@ -96,7 +96,7 @@ namespace FlaxEngine.Interop
}
#if FLAX_EDITOR
- private static Assembly? OnScriptingAssemblyLoadContextResolving(AssemblyLoadContext assemblyLoadContext, AssemblyName assemblyName)
+ private static Assembly OnScriptingAssemblyLoadContextResolving(AssemblyLoadContext assemblyLoadContext, AssemblyName assemblyName)
{
// FIXME: There should be a better way to resolve the path to EditorTargetPath where the dependencies are stored
string editorTargetPath = Path.GetDirectoryName(nativeLibraryPaths.Keys.First(x => x != "FlaxEngine"));
diff --git a/Source/Engine/Utilities/Utils.cs b/Source/Engine/Utilities/Utils.cs
index 5ac43ecd9..cb385efcf 100644
--- a/Source/Engine/Utilities/Utils.cs
+++ b/Source/Engine/Utilities/Utils.cs
@@ -255,7 +255,7 @@ namespace FlaxEngine
#else
private class ExtractArrayFromListContext
{
- public static FieldInfo? itemsField;
+ public static FieldInfo itemsField;
}
internal static T[] ExtractArrayFromList(List list)
{
From 96589557b32f417423a1ea6729dd0aa6586f9e05 Mon Sep 17 00:00:00 2001
From: Wojtek Figat
Date: Wed, 28 Jun 2023 20:09:18 +0200
Subject: [PATCH 50/65] Fix access level
96a1f20bee63c2096c435e75d3a7dd48622aa05e
---
.../Editor/Viewport/Previews/AnimatedModelPreview.cs | 2 +-
Source/Editor/Viewport/Previews/SkinnedModelPreview.cs | 10 +++++-----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/Source/Editor/Viewport/Previews/AnimatedModelPreview.cs b/Source/Editor/Viewport/Previews/AnimatedModelPreview.cs
index 4a1c57757..9a7ec6800 100644
--- a/Source/Editor/Viewport/Previews/AnimatedModelPreview.cs
+++ b/Source/Editor/Viewport/Previews/AnimatedModelPreview.cs
@@ -13,7 +13,7 @@ namespace FlaxEditor.Viewport.Previews
///
public class AnimatedModelPreview : AssetPreview
{
- public AnimatedModel _previewModel;
+ private AnimatedModel _previewModel;
private ContextMenuButton _showNodesButton, _showBoundsButton, _showFloorButton, _showNodesNamesButton;
private bool _showNodes, _showBounds, _showFloor, _showNodesNames;
private StaticModel _floorModel;
diff --git a/Source/Editor/Viewport/Previews/SkinnedModelPreview.cs b/Source/Editor/Viewport/Previews/SkinnedModelPreview.cs
index c11ea9ea4..08f8d8509 100644
--- a/Source/Editor/Viewport/Previews/SkinnedModelPreview.cs
+++ b/Source/Editor/Viewport/Previews/SkinnedModelPreview.cs
@@ -57,7 +57,7 @@ namespace FlaxEditor.Viewport.Previews
{
if (!control.Visible)
return;
- var skinned = _previewModel.SkinnedModel;
+ var skinned = PreviewActor.SkinnedModel;
if (skinned && !skinned.WaitForLoaded())
{
_previewLODsWidgetButtonMenu.ItemsContainer.DisposeChildren();
@@ -66,8 +66,8 @@ namespace FlaxEditor.Viewport.Previews
{
var index = i;
var button = _previewLODsWidgetButtonMenu.AddButton("LOD " + (index == -1 ? "Auto" : index));
- button.ButtonClicked += (button) => _previewModel.ForcedLOD = index;
- button.Checked = _previewModel.ForcedLOD == index;
+ button.ButtonClicked += (button) => PreviewActor.ForcedLOD = index;
+ button.Checked = PreviewActor.ForcedLOD == index;
button.Tag = index;
if (lods <= 1)
break;
@@ -128,7 +128,7 @@ namespace FlaxEditor.Viewport.Previews
{
base.Draw();
- var skinnedModel = _previewModel.SkinnedModel;
+ var skinnedModel = PreviewActor.SkinnedModel;
if (skinnedModel == null || !skinnedModel.IsLoaded)
return;
var lods = skinnedModel.LODs;
@@ -141,7 +141,7 @@ namespace FlaxEditor.Viewport.Previews
if (_showCurrentLOD)
{
var lodIndex = ComputeLODIndex(skinnedModel, out var screenSize);
- var auto = _previewModel.ForcedLOD == -1;
+ var auto = PreviewActor.ForcedLOD == -1;
string text = auto ? "LOD Automatic" : "";
text += auto ? string.Format("\nScreen Size: {0:F2}", screenSize) : "";
text += string.Format("\nCurrent LOD: {0}", lodIndex);
From 0498f1488ebd052110dc3a28b6d094c82ec98e71 Mon Sep 17 00:00:00 2001
From: ExMatics HydrogenC <33123710+HydrogenC@users.noreply.github.com>
Date: Fri, 30 Jun 2023 12:25:58 +0800
Subject: [PATCH 51/65] Fix space conversion issue
---
Source/Engine/Level/Actors/AnimatedModel.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Source/Engine/Level/Actors/AnimatedModel.cpp b/Source/Engine/Level/Actors/AnimatedModel.cpp
index 882026db7..2db3b6fae 100644
--- a/Source/Engine/Level/Actors/AnimatedModel.cpp
+++ b/Source/Engine/Level/Actors/AnimatedModel.cpp
@@ -127,7 +127,7 @@ void AnimatedModel::GetCurrentPose(Array& nodesTransformation, bool worl
Matrix world;
_transform.GetWorld(world);
for (auto& m : nodesTransformation)
- m = m * world;
+ m = world * m;
}
}
From 804826fbc793dbc6bafa931e9789c26150937cfa Mon Sep 17 00:00:00 2001
From: ExMatics HydrogenC <33123710+HydrogenC@users.noreply.github.com>
Date: Fri, 30 Jun 2023 14:06:52 +0800
Subject: [PATCH 52/65] Fix multiplication mistake
---
Source/Engine/Level/Actors/AnimatedModel.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Source/Engine/Level/Actors/AnimatedModel.cpp b/Source/Engine/Level/Actors/AnimatedModel.cpp
index 2db3b6fae..b33878a50 100644
--- a/Source/Engine/Level/Actors/AnimatedModel.cpp
+++ b/Source/Engine/Level/Actors/AnimatedModel.cpp
@@ -127,7 +127,7 @@ void AnimatedModel::GetCurrentPose(Array& nodesTransformation, bool worl
Matrix world;
_transform.GetWorld(world);
for (auto& m : nodesTransformation)
- m = world * m;
+ m = m * world;
}
}
@@ -144,7 +144,7 @@ void AnimatedModel::SetCurrentPose(const Array& nodesTransformation, boo
Matrix invWorld;
Matrix::Invert(world, invWorld);
for (auto& m : GraphInstance.NodesPose)
- m = invWorld * m;
+ m = m * invWorld;
}
OnAnimationUpdated();
}
From 8c006f6e113401ce0aeabb90c5c9e22c87b22064 Mon Sep 17 00:00:00 2001
From: Wojtek Figat
Date: Fri, 30 Jun 2023 10:00:12 +0200
Subject: [PATCH 53/65] Fix crash due to replicated objects leak upon system
destruction
---
Source/Engine/Networking/NetworkReplicator.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/Source/Engine/Networking/NetworkReplicator.cpp b/Source/Engine/Networking/NetworkReplicator.cpp
index daf2537f4..279391e31 100644
--- a/Source/Engine/Networking/NetworkReplicator.cpp
+++ b/Source/Engine/Networking/NetworkReplicator.cpp
@@ -1204,6 +1204,7 @@ void NetworkInternal::NetworkReplicatorClear()
Objects.Remove(it);
}
}
+ Objects.Clear();
RpcQueue.Clear();
SpawnQueue.Clear();
DespawnQueue.Clear();
From d5100373be5ad999626b4f26130b067f9773ec4b Mon Sep 17 00:00:00 2001
From: Wojtek Figat
Date: Fri, 30 Jun 2023 10:38:08 +0200
Subject: [PATCH 54/65] Fix bugs in C# codegen for network data serialization
---
Source/Tools/Flax.Build/Build/Plugins/NetworkingPlugin.cs | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/Source/Tools/Flax.Build/Build/Plugins/NetworkingPlugin.cs b/Source/Tools/Flax.Build/Build/Plugins/NetworkingPlugin.cs
index d76fc43cc..d646a81cd 100644
--- a/Source/Tools/Flax.Build/Build/Plugins/NetworkingPlugin.cs
+++ b/Source/Tools/Flax.Build/Build/Plugins/NetworkingPlugin.cs
@@ -780,7 +780,7 @@ namespace Flax.Build.Plugins
private static void GenerateCallINetworkSerializable(ref DotnetContext context, TypeDefinition type, string name, MethodDefinition method)
{
var m = new MethodDefinition(name, MethodAttributes.Public | MethodAttributes.HideBySig, context.VoidType);
- m.Parameters.Add(new ParameterDefinition("stream", ParameterAttributes.None, context.NetworkStreamType));
+ m.Parameters.Add(new ParameterDefinition("stream", ParameterAttributes.None, type.Module.ImportReference(context.NetworkStreamType)));
ILProcessor il = m.Body.GetILProcessor();
il.Emit(OpCodes.Nop);
il.Emit(OpCodes.Ldarg_0);
@@ -1304,7 +1304,10 @@ namespace Flax.Build.Plugins
il.Emit(jmp4);
valueContext.Load(ref il);
il.Emit(OpCodes.Ldloc, varStart + 1); // idx
- il.Emit(OpCodes.Ldelem_Ref);
+ if (elementType.IsValueType)
+ il.Emit(OpCodes.Ldelem_Any, elementType);
+ else
+ il.Emit(OpCodes.Ldelem_Ref);
il.Emit(OpCodes.Stloc, varStart + 2); //
// Serialize item value
From 2bd2bd508122a9a8ef76606abc700b5cdbafead8 Mon Sep 17 00:00:00 2001
From: Wojtek Figat
Date: Fri, 30 Jun 2023 11:02:58 +0200
Subject: [PATCH 55/65] Fix crash when modifying animated model skeleton pose
from gameplay code during update event
---
Source/Engine/Level/Actors/AnimatedModel.cpp | 8 +++++++-
Source/Engine/Level/Actors/AnimatedModel.h | 1 +
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/Source/Engine/Level/Actors/AnimatedModel.cpp b/Source/Engine/Level/Actors/AnimatedModel.cpp
index 882026db7..148b57682 100644
--- a/Source/Engine/Level/Actors/AnimatedModel.cpp
+++ b/Source/Engine/Level/Actors/AnimatedModel.cpp
@@ -603,7 +603,13 @@ void AnimatedModel::OnAnimationUpdated_Sync()
// Update synchronous stuff
UpdateSockets();
ApplyRootMotion(GraphInstance.RootMotion);
- AnimationUpdated();
+ if (!_isDuringUpdateEvent)
+ {
+ // Prevent stack-overflow when gameplay modifies the pose within the event
+ _isDuringUpdateEvent = true;
+ AnimationUpdated();
+ _isDuringUpdateEvent = false;
+ }
}
void AnimatedModel::OnAnimationUpdated()
diff --git a/Source/Engine/Level/Actors/AnimatedModel.h b/Source/Engine/Level/Actors/AnimatedModel.h
index ccd0ee3b5..33f206580 100644
--- a/Source/Engine/Level/Actors/AnimatedModel.h
+++ b/Source/Engine/Level/Actors/AnimatedModel.h
@@ -60,6 +60,7 @@ private:
AnimationUpdateMode _actualMode;
uint32 _counter;
Real _lastMinDstSqr;
+ bool _isDuringUpdateEvent = false;
uint64 _lastUpdateFrame;
BlendShapesInstance _blendShapes;
ScriptingObjectReference _masterPose;
From 0ee6aad3ec353b0efe8f50207bb66db6c1758707 Mon Sep 17 00:00:00 2001
From: Ari Vuollet
Date: Fri, 30 Jun 2023 13:00:29 +0300
Subject: [PATCH 56/65] Remove old hot-reload files in project references
---
Source/Editor/Scripting/ScriptsBuilder.cpp | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/Source/Editor/Scripting/ScriptsBuilder.cpp b/Source/Editor/Scripting/ScriptsBuilder.cpp
index eaffe5691..3082a531e 100644
--- a/Source/Editor/Scripting/ScriptsBuilder.cpp
+++ b/Source/Editor/Scripting/ScriptsBuilder.cpp
@@ -613,6 +613,28 @@ bool ScriptsBuilderService::Init()
const String targetOutput = Globals::ProjectFolder / TEXT("Binaries") / target / platform / architecture / configuration;
Array files;
FileSystem::DirectoryGetFiles(files, targetOutput, TEXT("*.HotReload.*"), DirectorySearchOption::TopDirectoryOnly);
+
+ for (const auto& reference : Editor::Project->References)
+ {
+ if (reference.Project->Name == TEXT("Flax"))
+ continue;
+
+ String referenceTarget;
+ if (reference.Project->EditorTarget.HasChars())
+ {
+ referenceTarget = reference.Project->EditorTarget.Get();
+ }
+ else if (reference.Project->GameTarget.HasChars())
+ {
+ referenceTarget = reference.Project->GameTarget.Get();
+ }
+ if (referenceTarget.IsEmpty())
+ continue;
+
+ const String referenceTargetOutput = reference.Project->ProjectFolderPath / TEXT("Binaries") / referenceTarget / platform / architecture / configuration;
+ FileSystem::DirectoryGetFiles(files, referenceTargetOutput, TEXT("*.HotReload.*"), DirectorySearchOption::TopDirectoryOnly);
+ }
+
if (files.HasItems())
LOG(Info, "Removing {0} files from previous Editor run hot-reloads", files.Count());
for (auto& file : files)
From 58618bd40260a1329847c90839af9f3f34b775f8 Mon Sep 17 00:00:00 2001
From: Ari Vuollet
Date: Fri, 30 Jun 2023 14:40:49 +0300
Subject: [PATCH 57/65] Fix garbage DefaultScene value in new projects
---
Source/Editor/ProjectInfo.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/Source/Editor/ProjectInfo.h b/Source/Editor/ProjectInfo.h
index 256269cc9..9f52e414f 100644
--- a/Source/Editor/ProjectInfo.h
+++ b/Source/Editor/ProjectInfo.h
@@ -112,6 +112,7 @@ public:
{
Version = ::Version(1, 0);
DefaultSceneSpawn = Ray(Vector3::Zero, Vector3::Forward);
+ DefaultScene = Guid::Empty;
}
///
From 28335478bd9275078fde606f742b1ed1a57403fc Mon Sep 17 00:00:00 2001
From: Ari Vuollet
Date: Sun, 2 Jul 2023 21:55:58 +0300
Subject: [PATCH 58/65] Fix managed library location resolver
---
Source/Engine/Engine/NativeInterop.cs | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/Source/Engine/Engine/NativeInterop.cs b/Source/Engine/Engine/NativeInterop.cs
index 4aedbe171..a6eb5368c 100644
--- a/Source/Engine/Engine/NativeInterop.cs
+++ b/Source/Engine/Engine/NativeInterop.cs
@@ -99,11 +99,14 @@ namespace FlaxEngine.Interop
private static Assembly OnScriptingAssemblyLoadContextResolving(AssemblyLoadContext assemblyLoadContext, AssemblyName assemblyName)
{
// FIXME: There should be a better way to resolve the path to EditorTargetPath where the dependencies are stored
- string editorTargetPath = Path.GetDirectoryName(nativeLibraryPaths.Keys.First(x => x != "FlaxEngine"));
+ foreach (string nativeLibraryPath in nativeLibraryPaths.Values)
+ {
+ string editorTargetPath = Path.GetDirectoryName(nativeLibraryPath);
- var assemblyPath = Path.Combine(editorTargetPath, assemblyName.Name + ".dll");
- if (File.Exists(assemblyPath))
- return assemblyLoadContext.LoadFromAssemblyPath(assemblyPath);
+ var assemblyPath = Path.Combine(editorTargetPath, assemblyName.Name + ".dll");
+ if (File.Exists(assemblyPath))
+ return assemblyLoadContext.LoadFromAssemblyPath(assemblyPath);
+ }
return null;
}
#endif
From 4f78f7920177e068e6606d36427233664563b61f Mon Sep 17 00:00:00 2001
From: Ari Vuollet
Date: Sun, 2 Jul 2023 22:12:18 +0300
Subject: [PATCH 59/65] Support line-breaks in API_INJECT_CODE macro
---
Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs
index b09b0c137..c05ab4e73 100644
--- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs
+++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs
@@ -1417,6 +1417,9 @@ namespace Flax.Build.Bindings
context.Tokenizer.SkipUntil(TokenType.Comma, out desc.Lang);
desc.Code = context.Tokenizer.ExpectToken(TokenType.String).Value.Replace("\\\"", "\"");
desc.Code = desc.Code.Substring(1, desc.Code.Length - 2);
+ desc.Code = desc.Code.Replace("\\\n", "\n");
+ desc.Code = desc.Code.Replace("\\\r\n", "\n");
+ desc.Code = desc.Code.Replace("\t", " ");
context.Tokenizer.ExpectToken(TokenType.RightParent);
return desc;
}
From 9a1fd12a8582afc5529a6667c3046f4da36f3584 Mon Sep 17 00:00:00 2001
From: Wojtek Figat
Date: Mon, 3 Jul 2023 11:42:15 +0200
Subject: [PATCH 60/65] Fix sizeof struct within generic type instance
#1219
---
.../CustomEditors/Dedicated/RagdollEditor.cs | 4 ++--
Source/Engine/Engine/NativeInterop.Managed.cs | 8 +++----
.../Engine/Engine/NativeInterop.Unmanaged.cs | 1 +
Source/Engine/Engine/NativeInterop.cs | 23 ++++++++++++++++++-
Source/Engine/Level/Spline.cs | 4 ++--
5 files changed, 31 insertions(+), 9 deletions(-)
diff --git a/Source/Editor/CustomEditors/Dedicated/RagdollEditor.cs b/Source/Editor/CustomEditors/Dedicated/RagdollEditor.cs
index 28c039dc8..5a10b9a52 100644
--- a/Source/Editor/CustomEditors/Dedicated/RagdollEditor.cs
+++ b/Source/Editor/CustomEditors/Dedicated/RagdollEditor.cs
@@ -167,7 +167,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
Presenter.Undo?.AddAction(new MultiUndoAction(actions));
// Build ragdoll
- SceneGraph.Actors.AnimatedModelNode.BuildRagdoll(animatedModel, options, ragdoll);
+ AnimatedModelNode.BuildRagdoll(animatedModel, options, ragdoll);
}
private void OnRebuildBone(Button button)
@@ -191,7 +191,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
}
// Build ragdoll
- SceneGraph.Actors.AnimatedModelNode.BuildRagdoll(animatedModel, new AnimatedModelNode.RebuildOptions(), ragdoll, name);
+ AnimatedModelNode.BuildRagdoll(animatedModel, new AnimatedModelNode.RebuildOptions(), ragdoll, name);
}
private void OnRemoveBone(Button button)
diff --git a/Source/Engine/Engine/NativeInterop.Managed.cs b/Source/Engine/Engine/NativeInterop.Managed.cs
index 7eda1cdec..797b02d5b 100644
--- a/Source/Engine/Engine/NativeInterop.Managed.cs
+++ b/Source/Engine/Engine/NativeInterop.Managed.cs
@@ -50,13 +50,13 @@ namespace FlaxEngine.Interop
/// The resources must be released by calling FreePooled() instead of Free()-method.
public static ManagedArray WrapPooledArray(Array arr, Type arrayType)
{
- ManagedArray managedArray = ManagedArrayPool.Get(arr.Length * Marshal.SizeOf(arr.GetType().GetElementType()));
+ ManagedArray managedArray = ManagedArrayPool.Get(arr.Length * NativeInterop.GetTypeSize(arr.GetType().GetElementType()));
managedArray.WrapArray(arr, arrayType);
return managedArray;
}
internal static ManagedArray AllocateNewArray(int length, Type arrayType, Type elementType)
- => new ManagedArray((IntPtr)NativeInterop.NativeAlloc(length, Marshal.SizeOf(elementType)), length, arrayType, elementType);
+ => new ManagedArray((IntPtr)NativeInterop.NativeAlloc(length, NativeInterop.GetTypeSize(elementType)), length, arrayType, elementType);
internal static ManagedArray AllocateNewArray(IntPtr ptr, int length, Type arrayType, Type elementType)
=> new ManagedArray(ptr, length, arrayType, elementType);
@@ -86,7 +86,7 @@ namespace FlaxEngine.Interop
_length = arr.Length;
_arrayType = arrayType;
_elementType = arr.GetType().GetElementType();
- _elementSize = Marshal.SizeOf(_elementType);
+ _elementSize = NativeInterop.GetTypeSize(_elementType);
}
internal void Allocate(int length) where T : unmanaged
@@ -117,7 +117,7 @@ namespace FlaxEngine.Interop
_length = length;
_arrayType = arrayType;
_elementType = elementType;
- _elementSize = Marshal.SizeOf(elementType);
+ _elementSize = NativeInterop.GetTypeSize(_elementType);
}
~ManagedArray()
diff --git a/Source/Engine/Engine/NativeInterop.Unmanaged.cs b/Source/Engine/Engine/NativeInterop.Unmanaged.cs
index c079a14e1..d4a8d44f8 100644
--- a/Source/Engine/Engine/NativeInterop.Unmanaged.cs
+++ b/Source/Engine/Engine/NativeInterop.Unmanaged.cs
@@ -885,6 +885,7 @@ namespace FlaxEngine.Interop
handle.Free();
fieldHandleCacheCollectible.Clear();
#endif
+ _typeSizeCache.Clear();
foreach (var pair in classAttributesCacheCollectible)
pair.Value.Free();
diff --git a/Source/Engine/Engine/NativeInterop.cs b/Source/Engine/Engine/NativeInterop.cs
index a6eb5368c..e82cb3858 100644
--- a/Source/Engine/Engine/NativeInterop.cs
+++ b/Source/Engine/Engine/NativeInterop.cs
@@ -46,6 +46,7 @@ namespace FlaxEngine.Interop
#endif
private static Dictionary