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;