diff --git a/Source/Editor/Content/Proxy/ShaderProxy.cs b/Source/Editor/Content/Proxy/ShaderProxy.cs
index 2f5c6fe42..98d4eaa2d 100644
--- a/Source/Editor/Content/Proxy/ShaderProxy.cs
+++ b/Source/Editor/Content/Proxy/ShaderProxy.cs
@@ -29,7 +29,7 @@ namespace FlaxEditor.Content
if (asset)
{
var source = Editor.GetShaderSourceCode(asset);
- Utilities.Utils.ShowSourceCodeWindow(source, "Shader Source", item.RootWindow.Window);
+ Utilities.Utils.ShowSourceCodeWindow(source, "Shader Source", item.RootWindow?.Window);
}
return null;
}
diff --git a/Source/Editor/Editor.Build.cs b/Source/Editor/Editor.Build.cs
index 2e769f431..cc7c48d23 100644
--- a/Source/Editor/Editor.Build.cs
+++ b/Source/Editor/Editor.Build.cs
@@ -102,5 +102,7 @@ public class Editor : EditorModule
files.Add(Path.Combine(FolderPath, "Cooker/GameCooker.h"));
files.Add(Path.Combine(FolderPath, "Cooker/PlatformTools.h"));
files.Add(Path.Combine(FolderPath, "Cooker/Steps/CookAssetsStep.h"));
+ files.Add(Path.Combine(FolderPath, "Utilities/ScreenUtilities.h"));
+ files.Add(Path.Combine(FolderPath, "Utilities/ViewportIconsRenderer.h"));
}
}
diff --git a/Source/Editor/Viewport/Previews/AnimatedModelPreview.cs b/Source/Editor/Viewport/Previews/AnimatedModelPreview.cs
index 9a7ec6800..12371f947 100644
--- a/Source/Editor/Viewport/Previews/AnimatedModelPreview.cs
+++ b/Source/Editor/Viewport/Previews/AnimatedModelPreview.cs
@@ -185,8 +185,8 @@ namespace FlaxEditor.Viewport.Previews
{
UseTimeScale = false,
UpdateWhenOffscreen = true,
- //_previewModel.BoundsScale = 1000.0f;
- UpdateMode = AnimatedModel.AnimationUpdateMode.Manual
+ BoundsScale = 100.0f,
+ UpdateMode = AnimatedModel.AnimationUpdateMode.Manual,
};
Task.AddCustomActor(_previewModel);
diff --git a/Source/Engine/Animations/Graph/AnimGroup.Animation.cpp b/Source/Engine/Animations/Graph/AnimGroup.Animation.cpp
index c508ab3c8..31b97fb52 100644
--- a/Source/Engine/Animations/Graph/AnimGroup.Animation.cpp
+++ b/Source/Engine/Animations/Graph/AnimGroup.Animation.cpp
@@ -217,6 +217,7 @@ void AnimGraphExecutor::ProcessAnimation(AnimGraphImpulse* nodes, AnimGraphNode*
const float animPrevPos = GetAnimSamplePos(length, anim, prevPos, speed);
// Evaluate nested animations
+ bool hasNested = false;
if (anim->NestedAnims.Count() != 0)
{
for (auto& e : anim->NestedAnims)
@@ -239,6 +240,7 @@ void AnimGraphExecutor::ProcessAnimation(AnimGraphImpulse* nodes, AnimGraphNode*
GetAnimSamplePos(nestedAnim.Loop, nestedAnimLength, nestedAnim.StartTime, nestedAnimPrevPos, nestedAnimPos, nestedAnimPos, nestedAnimPrevPos);
ProcessAnimation(nodes, node, true, nestedAnimLength, nestedAnimPos, nestedAnimPrevPos, nestedAnim.Anim, 1.0f, weight, mode);
+ hasNested = true;
}
}
}
@@ -291,7 +293,7 @@ void AnimGraphExecutor::ProcessAnimation(AnimGraphImpulse* nodes, AnimGraphNode*
dstNode.Scale = srcNode.Scale * weight;
dstNode.Orientation = srcNode.Orientation * weight;
}
- else
+ else if (!hasNested)
{
dstNode = srcNode;
}
diff --git a/Source/Engine/Content/Content.Build.cs b/Source/Engine/Content/Content.Build.cs
index f89ad6277..6bfc3ee22 100644
--- a/Source/Engine/Content/Content.Build.cs
+++ b/Source/Engine/Content/Content.Build.cs
@@ -37,6 +37,9 @@ public class Content : EngineModule
files.AddRange(Directory.GetFiles(FolderPath, "*.h", SearchOption.TopDirectoryOnly));
files.AddRange(Directory.GetFiles(Path.Combine(FolderPath, "Assets"), "*.h", SearchOption.TopDirectoryOnly));
files.AddRange(Directory.GetFiles(Path.Combine(FolderPath, "Cache"), "*.h", SearchOption.TopDirectoryOnly));
+ files.AddRange(Directory.GetFiles(Path.Combine(FolderPath, "Factories"), "*.h", SearchOption.TopDirectoryOnly));
files.AddRange(Directory.GetFiles(Path.Combine(FolderPath, "Storage"), "*.h", SearchOption.TopDirectoryOnly));
+ files.Add(Path.Combine(FolderPath, "Upgraders/BinaryAssetUpgrader.h"));
+ files.Add(Path.Combine(FolderPath, "Upgraders/IAssetUpgrader.h"));
}
}
diff --git a/Source/Engine/ContentExporters/ContentExporters.Build.cs b/Source/Engine/ContentExporters/ContentExporters.Build.cs
index 6721d43a9..a118022b2 100644
--- a/Source/Engine/ContentExporters/ContentExporters.Build.cs
+++ b/Source/Engine/ContentExporters/ContentExporters.Build.cs
@@ -1,6 +1,7 @@
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
using System.Collections.Generic;
+using System.IO;
using Flax.Build;
using Flax.Build.NativeCpp;
@@ -23,5 +24,7 @@ public class ContentExporters : EngineModule
///
public override void GetFilesToDeploy(List files)
{
+ files.Add(Path.Combine(FolderPath, "AssetsExportingManager.h"));
+ files.Add(Path.Combine(FolderPath, "Types.h"));
}
}
diff --git a/Source/Engine/ContentImporters/ContentImporters.Build.cs b/Source/Engine/ContentImporters/ContentImporters.Build.cs
index 8c4614cd5..f404037a6 100644
--- a/Source/Engine/ContentImporters/ContentImporters.Build.cs
+++ b/Source/Engine/ContentImporters/ContentImporters.Build.cs
@@ -1,6 +1,7 @@
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
using System.Collections.Generic;
+using System.IO;
using Flax.Build;
using Flax.Build.NativeCpp;
@@ -31,5 +32,7 @@ public class ContentImporters : EngineModule
///
public override void GetFilesToDeploy(List files)
{
+ files.Add(Path.Combine(FolderPath, "AssetsImportingManager.h"));
+ files.Add(Path.Combine(FolderPath, "Types.h"));
}
}
diff --git a/Source/Engine/Level/Actors/AnimatedModel.cpp b/Source/Engine/Level/Actors/AnimatedModel.cpp
index 4c1d32b77..b3904f653 100644
--- a/Source/Engine/Level/Actors/AnimatedModel.cpp
+++ b/Source/Engine/Level/Actors/AnimatedModel.cpp
@@ -1066,6 +1066,23 @@ void AnimatedModel::Deserialize(DeserializeStream& stream, ISerializeModifier* m
DrawModes |= DrawPass::GlobalSurfaceAtlas;
}
+MaterialBase* AnimatedModel::GetMaterial(int32 entryIndex)
+{
+ if (SkinnedModel)
+ SkinnedModel->WaitForLoaded();
+ else
+ return nullptr;
+ CHECK_RETURN(entryIndex >= 0 && entryIndex < Entries.Count(), nullptr);
+ MaterialBase* material = Entries[entryIndex].Material.Get();
+ if (!material)
+ {
+ material = SkinnedModel->MaterialSlots[entryIndex].Material.Get();
+ if (!material)
+ material = GPUDevice::Instance->GetDefaultMaterial();
+ }
+ return material;
+}
+
bool AnimatedModel::IntersectsEntry(int32 entryIndex, const Ray& ray, Real& distance, Vector3& normal)
{
auto model = SkinnedModel.Get();
diff --git a/Source/Engine/Level/Actors/AnimatedModel.h b/Source/Engine/Level/Actors/AnimatedModel.h
index 18b16c150..8fe85d114 100644
--- a/Source/Engine/Level/Actors/AnimatedModel.h
+++ b/Source/Engine/Level/Actors/AnimatedModel.h
@@ -384,6 +384,7 @@ public:
bool IntersectsItself(const Ray& ray, Real& distance, Vector3& normal) override;
void Serialize(SerializeStream& stream, const void* otherObj) override;
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
+ MaterialBase* GetMaterial(int32 entryIndex) override;
bool IntersectsEntry(int32 entryIndex, const Ray& ray, Real& distance, Vector3& normal) override;
bool IntersectsEntry(const Ray& ray, Real& distance, Vector3& normal, int32& entryIndex) override;
bool GetMeshData(const MeshReference& mesh, MeshBufferType type, BytesContainer& result, int32& count) const override;
diff --git a/Source/Engine/Level/Actors/ModelInstanceActor.cpp b/Source/Engine/Level/Actors/ModelInstanceActor.cpp
index 9209f6af0..8077197c6 100644
--- a/Source/Engine/Level/Actors/ModelInstanceActor.cpp
+++ b/Source/Engine/Level/Actors/ModelInstanceActor.cpp
@@ -39,10 +39,9 @@ void ModelInstanceActor::SetMaterial(int32 entryIndex, MaterialBase* material)
MaterialInstance* ModelInstanceActor::CreateAndSetVirtualMaterialInstance(int32 entryIndex)
{
WaitForModelLoad();
- CHECK_RETURN(entryIndex >= 0 && entryIndex < Entries.Count(), nullptr);
- auto material = Entries[entryIndex].Material.Get();
+ MaterialBase* material = GetMaterial(entryIndex);
CHECK_RETURN(material && !material->WaitForLoaded(), nullptr);
- const auto result = material->CreateVirtualInstance();
+ MaterialInstance* result = material->CreateVirtualInstance();
Entries[entryIndex].Material = result;
if (_sceneRenderingKey != -1)
GetSceneRendering()->UpdateActor(this, _sceneRenderingKey);
diff --git a/Source/Engine/Level/Actors/ModelInstanceActor.h b/Source/Engine/Level/Actors/ModelInstanceActor.h
index e72d790d8..346a13b0d 100644
--- a/Source/Engine/Level/Actors/ModelInstanceActor.h
+++ b/Source/Engine/Level/Actors/ModelInstanceActor.h
@@ -52,6 +52,12 @@ public:
///
API_PROPERTY() void SetEntries(const Array& value);
+ ///
+ /// Gets the material used to draw the meshes which are assigned to that slot (set in Entries or model's default).
+ ///
+ /// The material slot entry index.
+ API_FUNCTION(Sealed) virtual MaterialBase* GetMaterial(int32 entryIndex) = 0;
+
///
/// Sets the material to the entry slot. Can be used to override the material of the meshes using this slot.
///
diff --git a/Source/Engine/Level/Actors/SplineModel.cpp b/Source/Engine/Level/Actors/SplineModel.cpp
index 99c691ce9..44f0676d4 100644
--- a/Source/Engine/Level/Actors/SplineModel.cpp
+++ b/Source/Engine/Level/Actors/SplineModel.cpp
@@ -341,6 +341,23 @@ void SplineModel::OnParentChanged()
OnSplineUpdated();
}
+MaterialBase* SplineModel::GetMaterial(int32 entryIndex)
+{
+ if (Model)
+ Model->WaitForLoaded();
+ else
+ return nullptr;
+ CHECK_RETURN(entryIndex >= 0 && entryIndex < Entries.Count(), nullptr);
+ MaterialBase* material = Entries[entryIndex].Material.Get();
+ if (!material)
+ {
+ material = Model->MaterialSlots[entryIndex].Material.Get();
+ if (!material)
+ material = GPUDevice::Instance->GetDefaultDeformableMaterial();
+ }
+ return material;
+}
+
void SplineModel::UpdateBounds()
{
OnSplineUpdated();
diff --git a/Source/Engine/Level/Actors/SplineModel.h b/Source/Engine/Level/Actors/SplineModel.h
index 312da07d6..238e1cc5a 100644
--- a/Source/Engine/Level/Actors/SplineModel.h
+++ b/Source/Engine/Level/Actors/SplineModel.h
@@ -115,6 +115,7 @@ public:
void Serialize(SerializeStream& stream, const void* otherObj) override;
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
void OnParentChanged() override;
+ MaterialBase* GetMaterial(int32 entryIndex) override;
void UpdateBounds() override;
protected:
diff --git a/Source/Engine/Level/Actors/StaticModel.cpp b/Source/Engine/Level/Actors/StaticModel.cpp
index 3ab88cdce..75c272cce 100644
--- a/Source/Engine/Level/Actors/StaticModel.cpp
+++ b/Source/Engine/Level/Actors/StaticModel.cpp
@@ -543,6 +543,23 @@ void StaticModel::Deserialize(DeserializeStream& stream, ISerializeModifier* mod
}
}
+MaterialBase* StaticModel::GetMaterial(int32 entryIndex)
+{
+ if (Model)
+ Model->WaitForLoaded();
+ else
+ return nullptr;
+ CHECK_RETURN(entryIndex >= 0 && entryIndex < Entries.Count(), nullptr);
+ MaterialBase* material = Entries[entryIndex].Material.Get();
+ if (!material)
+ {
+ material = Model->MaterialSlots[entryIndex].Material.Get();
+ if (!material)
+ material = GPUDevice::Instance->GetDefaultMaterial();
+ }
+ return material;
+}
+
bool StaticModel::IntersectsEntry(int32 entryIndex, const Ray& ray, Real& distance, Vector3& normal)
{
auto model = Model.Get();
diff --git a/Source/Engine/Level/Actors/StaticModel.h b/Source/Engine/Level/Actors/StaticModel.h
index 8ce945316..78a0440fd 100644
--- a/Source/Engine/Level/Actors/StaticModel.h
+++ b/Source/Engine/Level/Actors/StaticModel.h
@@ -122,7 +122,7 @@ public:
/// The zero-based mesh index.
/// The LOD index.
/// Material or null if not assigned.
- API_FUNCTION() MaterialBase* GetMaterial(int32 meshIndex, int32 lodIndex = 0) const;
+ API_FUNCTION() MaterialBase* GetMaterial(int32 meshIndex, int32 lodIndex) const;
///
/// Gets the color of the painter vertex (this model instance).
@@ -166,6 +166,7 @@ public:
bool IntersectsItself(const Ray& ray, Real& distance, Vector3& normal) override;
void Serialize(SerializeStream& stream, const void* otherObj) override;
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
+ MaterialBase* GetMaterial(int32 entryIndex) override;
bool IntersectsEntry(int32 entryIndex, const Ray& ray, Real& distance, Vector3& normal) override;
bool IntersectsEntry(const Ray& ray, Real& distance, Vector3& normal, int32& entryIndex) override;
bool GetMeshData(const MeshReference& mesh, MeshBufferType type, BytesContainer& result, int32& count) const override;
diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs
index c05ab4e73..1eeefaf27 100644
--- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs
+++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs
@@ -847,6 +847,9 @@ namespace Flax.Build.Bindings
case "hidden":
desc.IsHidden = true;
break;
+ case "sealed":
+ desc.IsVirtual = false;
+ break;
case "tag":
ParseTag(ref desc.Tags, tag);
break;