From 75f103c372b59521fd3b353d2015d70311f2b7b3 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 15 Nov 2022 15:53:12 +0800 Subject: [PATCH 01/28] Setting pipeline of a material now triggers a reset of all properties for material instances based on the material --- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 5 + .../MiddleEnd/Interface/SHGraphicsSystem.h | 9 +- .../MiddleEnd/Interface/SHMaterial.cpp | 176 ++++++++++-------- .../Graphics/MiddleEnd/Interface/SHMaterial.h | 2 +- .../Interface/SHMaterialInstance.cpp | 1 - .../MiddleEnd/Pipeline/SHPipelineLibrary.cpp | 2 +- SHADE_Engine/src/Resource/SHResourceLibrary.h | 33 ++++ .../src/Resource/SHResourceLibrary.hpp | 22 ++- SHADE_Engine/src/Resource/SHResourceManager.h | 15 +- SHADE_Engine/src/Resource/SparseSet.h | 15 +- SHADE_Engine/src/Resource/SparseSet.hpp | 9 + 11 files changed, 195 insertions(+), 94 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 15c8ec5d..fc157d7d 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -710,6 +710,11 @@ namespace SHADE return resourceManager.Create(materialInst->GetBaseMaterial()); } + std::pair, typename SHResourceHub::dense_iterator> SHGraphicsSystem::GetAllMaterialInstances() + { + return resourceManager.GetDenseAccess(); + } + void SHGraphicsSystem::RemoveMaterialInstance(Handle materialInstance) { resourceManager.Free(materialInstance); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index a5a5ada0..569477d8 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -156,6 +156,7 @@ namespace SHADE Handle AddOrGetBaseMaterialInstance(); Handle AddOrGetBaseMaterialInstance(Handle material); Handle AddMaterialInstanceCopy(Handle materialInst); + std::pair, typename SHResourceHub::dense_iterator> GetAllMaterialInstances(); void RemoveMaterialInstance(Handle materialInstance); Handle GetDefaultMaterial() { return defaultMaterial; } Handle GetDefaultMaterialInstance() { return AddOrGetBaseMaterialInstance(defaultMaterial); } @@ -166,10 +167,10 @@ namespace SHADE /*******************************************************************************/ /*! - \brief - Adds a mesh to the Mesh Library. But this does not mean that the meshes have - been added yet. A call to "BuildBuffers()" is required to transfer all - meshes into the GPU. + \brief + Adds a mesh to the Mesh Library. But this does not mean that the meshes have + been added yet. A call to "BuildBuffers()" is required to transfer all + meshes into the GPU. \param vertexCount Number of vertices in this Mesh. diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.cpp index b27f48b9..528472a7 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.cpp @@ -6,91 +6,113 @@ #include "Graphics/Shaders/BlockInterface/SHShaderBlockInterface.h" #include "Math/Vector/SHVec3.h" #include "Math/Vector/SHVec4.h" +#include "ECS_Base/Managers/SHSystemManager.h" +#include "SHGraphicsSystem.h" +#include "SHMaterialInstance.h" namespace SHADE { - /*---------------------------------------------------------------------------------*/ - /* Pipeline Functions */ - /*---------------------------------------------------------------------------------*/ - void SHMaterial::SetPipeline(Handle _pipeline) - { - pipeline = _pipeline; + /*---------------------------------------------------------------------------------*/ + /* Pipeline Functions */ + /*---------------------------------------------------------------------------------*/ + void SHMaterial::SetPipeline(Handle _pipeline) + { + // Reassignment, we ignore + if (_pipeline == pipeline) + return; - // Set up properties based on the pipeline - if (!pipeline) - { - // Clear memory and all that - propMemory.reset(); - return; - } + pipeline = _pipeline; - // Allocate memory for properties - const Handle SHADER_INFO = GetShaderBlockInterface(); - propMemorySize = SHADER_INFO ? SHADER_INFO->GetBytesRequired() : 0; - if (propMemorySize <= 0) - { - propMemory.reset(); - } - else - { - propMemory.reset(new char[propMemorySize]); - } - ResetProperties(); - } - - Handle SHMaterial::GetPipeline() const - { - return pipeline; - } - - /*---------------------------------------------------------------------------------*/ - /* Property Functions */ - /*---------------------------------------------------------------------------------*/ - void SHMaterial::ResetProperties() + // Set up properties based on the pipeline + if (!pipeline) { - // Reset all the properties to default values - if (propMemory) - memset(propMemory.get(), 0, propMemorySize); - - // Initialize Vectors to all 1.0 by default - const Handle SHADER_INFO = GetShaderBlockInterface(); - for (int i = 0; i < SHADER_INFO->GetVariableCount(); ++i) - { - const auto& VAR = SHADER_INFO->GetVariable(i); - switch (VAR->type) - { - case SHShaderBlockInterface::Variable::Type::VECTOR3: - setPropertyUnsafe(VAR->offset, SHVec3::One); - break; - case SHShaderBlockInterface::Variable::Type::VECTOR4: - setPropertyUnsafe(VAR->offset, SHVec4::One); - break; - } - } + // Clear memory and all that + propMemory.reset(); + return; } - void SHMaterial::ExportProperties(void* dest) const noexcept - { - if (propMemory) - memcpy(dest, propMemory.get(), propMemorySize); - } + // Allocate memory for properties + const Handle SHADER_INFO = GetShaderBlockInterface(); + propMemorySize = SHADER_INFO ? SHADER_INFO->GetBytesRequired() : 0; + if (propMemorySize <= 0) + { + propMemory.reset(); + } + else + { + propMemory.reset(new char[propMemorySize]); + } + ResetProperties(); - size_t SHMaterial::GetPropertiesMemorySize() const noexcept - { - const Handle SHADER_INFO = GetShaderBlockInterface(); - return SHADER_INFO ? SHADER_INFO->GetBytesRequired() : 0; - } + // Search all material instances for instances that use this base material + // to force a reset of properties + auto gfxSystem = SHSystemManager::GetSystem(); + if (gfxSystem) + { + auto [matInstBegin, matInstEnd] = gfxSystem->GetAllMaterialInstances(); + for (auto iter = matInstBegin; iter != matInstEnd; ++iter) + { + if (iter->GetBaseMaterial() == GetHandle()) + { + iter->ResetProperties(); + } + } + } + } - /*---------------------------------------------------------------------------------*/ - /* Helper Functions */ - /*---------------------------------------------------------------------------------*/ - Handle SHMaterial::GetShaderBlockInterface() const noexcept - { - return pipeline->GetPipelineLayout()->GetShaderBlockInterface - ( - SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, - SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA, - vk::ShaderStageFlagBits::eFragment - ); - } + Handle SHMaterial::GetPipeline() const + { + return pipeline; + } + + /*---------------------------------------------------------------------------------*/ + /* Property Functions */ + /*---------------------------------------------------------------------------------*/ + void SHMaterial::ResetProperties() + { + // Reset all the properties to default values + if (propMemory) + memset(propMemory.get(), 0, propMemorySize); + + // Initialize Vectors to all 1.0 by default + const Handle SHADER_INFO = GetShaderBlockInterface(); + for (int i = 0; i < SHADER_INFO->GetVariableCount(); ++i) + { + const auto& VAR = SHADER_INFO->GetVariable(i); + switch (VAR->type) + { + case SHShaderBlockInterface::Variable::Type::VECTOR3: + setPropertyUnsafe(VAR->offset, SHVec3::One); + break; + case SHShaderBlockInterface::Variable::Type::VECTOR4: + setPropertyUnsafe(VAR->offset, SHVec4::One); + break; + } + } + } + + void SHMaterial::ExportProperties(void* dest) const noexcept + { + if (propMemory) + memcpy(dest, propMemory.get(), propMemorySize); + } + + size_t SHMaterial::GetPropertiesMemorySize() const noexcept + { + const Handle SHADER_INFO = GetShaderBlockInterface(); + return SHADER_INFO ? SHADER_INFO->GetBytesRequired() : 0; + } + + /*---------------------------------------------------------------------------------*/ + /* Helper Functions */ + /*---------------------------------------------------------------------------------*/ + Handle SHMaterial::GetShaderBlockInterface() const noexcept + { + return pipeline->GetPipelineLayout()->GetShaderBlockInterface + ( + SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, + SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA, + vk::ShaderStageFlagBits::eFragment + ); + } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.h index 964f9e34..201090b7 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.h @@ -35,7 +35,7 @@ namespace SHADE Describes a Pipeline along with it's associated properties for this instance. */ /***********************************************************************************/ - class SHMaterial + class SHMaterial : public ISelfHandle { public: /*-----------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.cpp index 350580bf..b30acfb8 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.cpp @@ -31,7 +31,6 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ void SHMaterialInstance::ResetProperties() noexcept { - // Reset all the properties to default values memset(dataStore.get(), 0, dataStoreSize); overrideData.clear(); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp index 495a3d37..05bd8813 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp @@ -34,7 +34,7 @@ namespace SHADE { colorBlendState.attachments.push_back(vk::PipelineColorBlendAttachmentState { - .blendEnable = SHVkUtil::IsBlendCompatible (subpass->GetFormatFromAttachmentReference(att.attachment)) ? true : false, + .blendEnable = SHVkUtil::IsBlendCompatible(subpass->GetFormatFromAttachmentReference(att.attachment)), .srcColorBlendFactor = vk::BlendFactor::eSrcAlpha, .dstColorBlendFactor = vk::BlendFactor::eOneMinusSrcAlpha, .colorBlendOp = vk::BlendOp::eAdd, diff --git a/SHADE_Engine/src/Resource/SHResourceLibrary.h b/SHADE_Engine/src/Resource/SHResourceLibrary.h index 46ae4572..a6f772fe 100644 --- a/SHADE_Engine/src/Resource/SHResourceLibrary.h +++ b/SHADE_Engine/src/Resource/SHResourceLibrary.h @@ -38,6 +38,11 @@ namespace SHADE class SHResourceLibrary : public SHResourceLibraryBase { public: + /*-----------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------*/ + using dense_iterator = typename SparseSet::dense_iterator; + /*-----------------------------------------------------------------------------*/ /* Constructor */ /*-----------------------------------------------------------------------------*/ @@ -74,6 +79,16 @@ namespace SHADE /// Read-only reference to the resource object. const T& Get(Handle handle) const; + /*-----------------------------------------------------------------------------*/ + /* Direct Dense Access Functions */ + /*-----------------------------------------------------------------------------*/ + /// + /// Provides access to the dense array of the SparseSet. + /// These iterators should not be used to manipulate the underlying vector. + /// + /// Pair of begin and end iterators to the dense vector. + std::pair GetDenseAccess(); + private: /*-----------------------------------------------------------------------------*/ /* Data Members */ @@ -96,6 +111,12 @@ namespace SHADE class SHResourceHub final { public: + /*-----------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------*/ + template + using dense_iterator = typename SHResourceLibrary::dense_iterator; + /*-----------------------------------------------------------------------------*/ /* Constructors/Destructors */ /*-----------------------------------------------------------------------------*/ @@ -138,6 +159,18 @@ namespace SHADE template const T& Get(Handle handle) const; + /*-----------------------------------------------------------------------------*/ + /* Direct Dense Access Functions */ + /*-----------------------------------------------------------------------------*/ + /// + /// Provides access to the dense array of the SparseSet. + /// These iterators should not be used to manipulate the underlying vector. + /// + /// Type of resource to access. + /// Pair of begin and end iterators to the dense vector. + template + std::pair, dense_iterator> GetDenseAccess(); + private: /*-----------------------------------------------------------------------------*/ /* Type Definition */ diff --git a/SHADE_Engine/src/Resource/SHResourceLibrary.hpp b/SHADE_Engine/src/Resource/SHResourceLibrary.hpp index 411f6bf5..98ad91a3 100644 --- a/SHADE_Engine/src/Resource/SHResourceLibrary.hpp +++ b/SHADE_Engine/src/Resource/SHResourceLibrary.hpp @@ -79,6 +79,15 @@ namespace SHADE return objects[handle.GetId().Data.Index]; } + /*---------------------------------------------------------------------------------*/ + /* ResourceLibrary - Direct Dense Access Functions */ + /*---------------------------------------------------------------------------------*/ + template + std::pair::dense_iterator, typename SHResourceLibrary::dense_iterator> SHResourceLibrary::GetDenseAccess() + { + return objects.GetDenseAccess(); + } + /*---------------------------------------------------------------------------------*/ /* ResourceLibrary - Helper Functions */ /*---------------------------------------------------------------------------------*/ @@ -105,7 +114,7 @@ namespace SHADE } /*---------------------------------------------------------------------------------*/ - /* ResourceManager - Usage Functions */ + /* ResourceHub - Usage Functions */ /*---------------------------------------------------------------------------------*/ template Handle SHResourceHub::Create(Args&&... args) @@ -132,7 +141,7 @@ namespace SHADE } /*-----------------------------------------------------------------------------*/ - /* ResourceManager - Helper Functions */ + /* ResourceHub - Helper Functions */ /*-----------------------------------------------------------------------------*/ template SHResourceLibrary& SHResourceHub::getLibrary() @@ -161,4 +170,13 @@ namespace SHADE { return const_cast(this).getLibrary(); } + + /*---------------------------------------------------------------------------------*/ + /* ResourceHub - Direct Dense Access Functions */ + /*---------------------------------------------------------------------------------*/ + template + std::pair, typename SHResourceHub::dense_iterator> SHResourceHub::GetDenseAccess() + { + return getLibrary().GetDenseAccess(); + } } diff --git a/SHADE_Engine/src/Resource/SHResourceManager.h b/SHADE_Engine/src/Resource/SHResourceManager.h index d660ada7..15c37f83 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.h +++ b/SHADE_Engine/src/Resource/SHResourceManager.h @@ -13,8 +13,6 @@ of DigiPen Institute of Technology is prohibited. // STL Includes #include - -namespace SHADE { class SHMaterial; } // Project Includes #include "SH_API.h" #include "SHResourceLibrary.h" @@ -31,17 +29,26 @@ namespace SHADE { class SHMaterial; } namespace SHADE { + /*-----------------------------------------------------------------------------------*/ + /* Forward Declarations */ + /*-----------------------------------------------------------------------------------*/ + class SHMaterial; + + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ /// /// Template structs that maps a resource to their loaded asset representation type. /// template struct SHResourceLoader { using AssetType = void; }; - template<> struct SHResourceLoader { using AssetType = SHMeshData; }; + template<> struct SHResourceLoader { using AssetType = SHMeshData; }; template<> struct SHResourceLoader { using AssetType = SHTextureAsset; }; template<> struct SHResourceLoader { using AssetType = SHShaderAsset; }; template<> struct SHResourceLoader { using AssetType = SHMaterialAsset; }; template<> struct SHResourceLoader { using AssetType = SHMaterialSpec; }; -/// + + /// /// Static class responsible for loading and caching runtime resources from their /// serialised Asset IDs. /// diff --git a/SHADE_Engine/src/Resource/SparseSet.h b/SHADE_Engine/src/Resource/SparseSet.h index fb4a8311..3d763b01 100644 --- a/SHADE_Engine/src/Resource/SparseSet.h +++ b/SHADE_Engine/src/Resource/SparseSet.h @@ -49,6 +49,7 @@ namespace SHADE using const_pointer = const T*; using reference = T&; using const_reference = const T&; + using dense_iterator = typename std::vector::iterator; /*-----------------------------------------------------------------------------*/ /* Constructors/Destructors */ @@ -59,10 +60,6 @@ namespace SHADE SparseSet(); ~SparseSet() = default; - //// Disallow moving or copying - //SparseSet(const SparseSet&) = delete; - //SparseSet(SparseSet&&) = delete; - /*-----------------------------------------------------------------------------*/ /* Usage Functions */ /*-----------------------------------------------------------------------------*/ @@ -192,6 +189,16 @@ namespace SHADE /// const T& operator[](index_type idx) const; + /*-----------------------------------------------------------------------------*/ + /* Direct Dense Access Functions */ + /*-----------------------------------------------------------------------------*/ + /// + /// Provides access to the dense array of the SparseSet. + /// These iterators should not be used to manipulate the underlying vector. + /// + /// Pair of begin and end iterators to the dense vector. + std::pair GetDenseAccess(); + protected: /*-----------------------------------------------------------------------------*/ /* Constants */ diff --git a/SHADE_Engine/src/Resource/SparseSet.hpp b/SHADE_Engine/src/Resource/SparseSet.hpp index 816ca432..b6c7a511 100644 --- a/SHADE_Engine/src/Resource/SparseSet.hpp +++ b/SHADE_Engine/src/Resource/SparseSet.hpp @@ -143,4 +143,13 @@ namespace SHADE { return at(idx); } + + /*---------------------------------------------------------------------------------*/ + /* Direct Dense Access Functions */ + /*---------------------------------------------------------------------------------*/ + template + std::pair::dense_iterator, typename SparseSet::dense_iterator> SparseSet::GetDenseAccess() + { + return { denseArray.begin(), denseArray.end() }; + } } \ No newline at end of file From c69ad04f1e9643a10f031bec361977428b873beb Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 15 Nov 2022 18:15:49 +0800 Subject: [PATCH 02/28] Added functions to get name of a backing asset from SHResourceManager --- SHADE_Engine/src/Assets/SHAssetManager.cpp | 12 +++++- SHADE_Engine/src/Assets/SHAssetManager.h | 1 + .../src/Resource/SHResourceManager.cpp | 13 ++++++ SHADE_Engine/src/Resource/SHResourceManager.h | 40 +++++++++++++++++-- .../src/Resource/SHResourceManager.hpp | 22 ++++++++++ 5 files changed, 84 insertions(+), 4 deletions(-) diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index b4ea7d35..f9b5cf41 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -143,7 +143,17 @@ namespace SHADE return result; } - /**************************************************************************** + std::optional SHAssetManager::GetAsset(AssetID id) noexcept + { + if (assetCollection.contains(id)) + { + return assetCollection[id]; + } + + return {}; + } + + /**************************************************************************** * \brief Create record for new asset. CAN ONLY CREATE FOR CUSTOM * ASSETS CREATED BY THE ENGINE. * diff --git a/SHADE_Engine/src/Assets/SHAssetManager.h b/SHADE_Engine/src/Assets/SHAssetManager.h index f6ecb3a3..9d0a0bf4 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.h +++ b/SHADE_Engine/src/Assets/SHAssetManager.h @@ -50,6 +50,7 @@ namespace SHADE * \return const& to unordered_map ****************************************************************************/ static std::vector GetAllAssets() noexcept; + static std::optional GetAsset(AssetID id) noexcept; /**************************************************************************** * \brief Create record for new resource. CAN ONLY CREATE FOR CUSTOM diff --git a/SHADE_Engine/src/Resource/SHResourceManager.cpp b/SHADE_Engine/src/Resource/SHResourceManager.cpp index dad9fd9f..077835f5 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.cpp +++ b/SHADE_Engine/src/Resource/SHResourceManager.cpp @@ -103,4 +103,17 @@ namespace SHADE return {}; } + + std::optional SHResourceManager::GetAssetName(Handle handle) + { + const Handle GENERIC_HANDLE = Handle(handle); + auto assetId = GetAssetID(GENERIC_HANDLE); + if (assetId.has_value()) + { + const auto ASSET_INFO = SHAssetManager::GetAsset(assetId.value()); + if (ASSET_INFO.has_value()) + return ASSET_INFO.value().name; + } + return {}; + } } diff --git a/SHADE_Engine/src/Resource/SHResourceManager.h b/SHADE_Engine/src/Resource/SHResourceManager.h index 15c37f83..dae20f99 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.h +++ b/SHADE_Engine/src/Resource/SHResourceManager.h @@ -64,9 +64,7 @@ namespace SHADE /// Note that for specific types, the retrieved Handle may not be valid until after /// FinaliseChanges() is called. /// - /// - /// Type of resource to load. - /// + /// Type of resource to load. /// Asset ID of the resource to load. /// Handle to a loaded runtime asset. template @@ -74,6 +72,17 @@ namespace SHADE template<> static inline Handle LoadOrGet(AssetID assetId); /// + /// Retrieves an existing loaded object of the specified type if it has already been + /// loaded prior. + /// + /// Type of resource to load. + /// Asset ID of the resource to retrieve. + /// + /// Handle to a loaded runtime asset. Null handle if not loaded before. + /// + template + static Handle Get(AssetID assetId); + /// /// Unloads an existing loaded asset. Attempting to unload an invalid Handle will /// simply do nothing except emit a warning. /// Faster than the untemplated version. @@ -121,6 +130,31 @@ namespace SHADE /// value. /// static std::optional GetAssetID(Handle handle); + /// + /// Retrieves the name associated with the AssetID that is associated with the + /// specified Handle. + /// Faster than the untemplated version. + /// + /// Type of resource to get the name of. + /// Handle to get the name of. + /// + /// Name for the specified Handle. If the Handle is invalid, there will be no + /// value. + /// + template + static std::optional GetAssetName(Handle handle); + /// + /// Retrieves the name associated with the AssetID that is associated with the + /// specified Handle. + /// Compared to the templated version, this function is slower as it requires + /// searching through the storage of all resource types. + /// + /// Handle to get the name of. + /// + /// Name for the specified Handle. If the Handle is invalid, there will be no + /// value. + /// + static std::optional GetAssetName(Handle handle); private: /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Resource/SHResourceManager.hpp b/SHADE_Engine/src/Resource/SHResourceManager.hpp index 01d82a7b..76888076 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.hpp +++ b/SHADE_Engine/src/Resource/SHResourceManager.hpp @@ -93,6 +93,16 @@ namespace SHADE return handle; } + template + Handle SHResourceManager::Get(AssetID assetId) + { + auto [typedHandleMap, typedAssetIdMap] = getAssetHandleMap(); + if (typedHandleMap.get().contains(assetId)) + return Handle(typedHandleMap.get()[assetId]); + else + return Handle(); + } + template void SHResourceManager::Unload(Handle asset) { @@ -139,6 +149,18 @@ namespace SHADE return {}; } + template + std::optional SHADE::SHResourceManager::GetAssetName(Handle handle) + { + auto assetId = GetAssetID(handle); + if (assetId.has_value()) + { + const auto ASSET_INFO = SHAssetManager::GetAsset(assetId.value()); + if (ASSET_INFO.has_value()) + return ASSET_INFO.value().name; + } + return {}; + } /*-----------------------------------------------------------------------------------*/ /* Helper Functions */ From 958310a8ea53ebb6bc5055a67c6c390d76761a11 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 15 Nov 2022 18:16:07 +0800 Subject: [PATCH 03/28] Renderable now shows the name of the mesh and material assigned instead of asset IDs --- .../Inspector/SHEditorComponentView.hpp | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index 6091556e..e89c29cc 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -368,8 +368,8 @@ namespace SHADE DrawContextMenu(component); Handle const& mesh = component->GetMesh(); Handle const& mat = component->GetMaterial(); - - SHEditorWidgets::DragDropReadOnlyField("Mesh", std::to_string(SHResourceManager::GetAssetID(mesh).value_or(0)).data(), [component]() + const auto MESH_NAME = SHResourceManager::GetAssetName(mesh).value_or(""); + SHEditorWidgets::DragDropReadOnlyField("Mesh", MESH_NAME, [component]() { Handle const& mesh = component->GetMesh(); return SHResourceManager::GetAssetID(mesh).value_or(0); @@ -380,13 +380,15 @@ namespace SHADE SHResourceManager::FinaliseChanges(); }, SHDragDrop::DRAG_RESOURCE); - SHEditorWidgets::DragDropReadOnlyField("Material", mat ? std::to_string(SHResourceManager::GetAssetID(mat->GetBaseMaterial()).value_or(0)).data() : "", [component]() - { - Handle const& mat = component->GetMaterial(); - if(!mat) - return static_cast(0); - return SHResourceManager::GetAssetID(mat->GetBaseMaterial()).value_or(0); - }, + const auto MAT_NAME = mat ? SHResourceManager::GetAssetName(mat->GetBaseMaterial()).value_or("") : ""; + SHEditorWidgets::DragDropReadOnlyField("Material", MAT_NAME, + [component]() + { + Handle const& mat = component->GetMaterial(); + if (!mat) + return static_cast(0); + return SHResourceManager::GetAssetID(mat->GetBaseMaterial()).value_or(0); + }, [component](AssetID const& id) { auto gfxSystem = SHSystemManager::GetSystem(); From 1b2ff7f4a28526646e990c248e50c02689258971 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Tue, 15 Nov 2022 23:57:38 +0800 Subject: [PATCH 04/28] Expanded Collision Shape C# Interface --- SHADE_Managed/src/Components/Collider.cxx | 135 +++++++++++++++++----- SHADE_Managed/src/Components/Collider.h++ | 6 +- SHADE_Managed/src/Components/Collider.hxx | 76 ++++++++++-- 3 files changed, 179 insertions(+), 38 deletions(-) diff --git a/SHADE_Managed/src/Components/Collider.cxx b/SHADE_Managed/src/Components/Collider.cxx index 1a53f9e1..41910d66 100644 --- a/SHADE_Managed/src/Components/Collider.cxx +++ b/SHADE_Managed/src/Components/Collider.cxx @@ -20,7 +20,7 @@ of DigiPen Institute of Technology is prohibited. namespace SHADE { /*---------------------------------------------------------------------------------*/ - /* ColliderBound - Constructors */ + /* CollisionShape - Constructors */ /*---------------------------------------------------------------------------------*/ CollisionShape::CollisionShape(int arrayIdx, Entity attachedEntity) : arrayIndex { arrayIdx } @@ -28,102 +28,183 @@ namespace SHADE {} /*---------------------------------------------------------------------------------*/ - /* ColliderBound - Setter Functions */ + /* CollisionShape - Properties */ + /*---------------------------------------------------------------------------------*/ + + bool CollisionShape::IsTrigger::get() + { + return getNativeCollisionShape().IsTrigger(); + } + + void CollisionShape::IsTrigger::set(bool value) + { + getNativeCollisionShape().SetIsTrigger(value); + } + + Vector3 CollisionShape::PositionOffset::get() + { + return Convert::ToCLI(getNativeCollisionShape().GetPositionOffset()); + } + + void CollisionShape::PositionOffset::set(Vector3 value) + { + getNativeCollisionShape().SetPositionOffset(Convert::ToNative(value)); + } + + Vector3 CollisionShape::RotationOffset::get() + { + return Convert::ToCLI(getNativeCollisionShape().GetRotationOffset()); + } + + void CollisionShape::RotationOffset::set(Vector3 value) + { + getNativeCollisionShape().SetRotationOffset(Convert::ToNative(value)); + } + + float CollisionShape::Friction::get() + { + return getNativeCollisionShape().GetFriction(); + } + + void CollisionShape::Friction::set(float value) + { + getNativeCollisionShape().SetFriction(value); + } + + float CollisionShape::Bounciness::get() + { + return getNativeCollisionShape().GetBounciness(); + } + + void CollisionShape::Bounciness::set(float value) + { + getNativeCollisionShape().SetBounciness(value); + } + + float CollisionShape::Density::get() + { + return getNativeCollisionShape().GetDensity(); + } + + void CollisionShape::Density::set(float value) + { + getNativeCollisionShape().SetDensity(value); + } + + /*---------------------------------------------------------------------------------*/ + /* CollisionShape - helper Functions */ /*---------------------------------------------------------------------------------*/ void CollisionShape::updateArrayIndex(int index) { arrayIndex = index; } + SHCollisionShape& SHADE::CollisionShape::getNativeCollisionShape() + { + SHColliderComponent* collider = SHComponentManager::GetComponent_s(entity); + if (!collider) + throw gcnew System::InvalidOperationException("Unable to retrieve Collider component!"); + + try + { + auto& shape = collider->GetCollisionShape(arrayIndex); + return shape; + } + catch (std::invalid_argument&) + { + throw gcnew System::IndexOutOfRangeException("Attempted to retrieve out of range CollisionShape!"); + } + } + /*---------------------------------------------------------------------------------*/ - /* BoxColliderBound - Constructors */ + /* BoxCollider - Constructors */ /*---------------------------------------------------------------------------------*/ BoxCollider::BoxCollider(int arrayIdx, Entity attachedEntity) : CollisionShape { arrayIndex, attachedEntity } {} /*---------------------------------------------------------------------------------*/ - /* BoxColliderBound - Properties */ + /* BoxCollider - Properties */ /*---------------------------------------------------------------------------------*/ Vector3 BoxCollider::Center::get() { - return Convert::ToCLI(getNativeBoundObject().GetCenter()); + return Convert::ToCLI(getNativeCollisionShape().GetCenter()); } void BoxCollider::Center::set(Vector3 value) { - getNativeBoundObject().SetCenter(Convert::ToNative(value)); + getNativeCollisionShape().SetCenter(Convert::ToNative(value)); } Vector3 BoxCollider::HalfExtents::get() { - return Convert::ToCLI(getNativeBoundObject().GetWorldExtents()); + return Convert::ToCLI(getNativeCollisionShape().GetWorldExtents()); } void BoxCollider::HalfExtents::set(Vector3 value) { - getNativeBoundObject().SetWorldExtents(Convert::ToNative(value)); + getNativeCollisionShape().SetWorldExtents(Convert::ToNative(value)); } Vector3 BoxCollider::Min::get() { - return Convert::ToCLI(getNativeBoundObject().GetMin()); + return Convert::ToCLI(getNativeCollisionShape().GetMin()); } void BoxCollider::Min::set(Vector3 value) { - getNativeBoundObject().SetMin(Convert::ToNative(value)); + getNativeCollisionShape().SetMin(Convert::ToNative(value)); } Vector3 BoxCollider::Max::get() { - return Convert::ToCLI(getNativeBoundObject().GetMax()); + return Convert::ToCLI(getNativeCollisionShape().GetMax()); } void BoxCollider::Max::set(Vector3 value) { - getNativeBoundObject().SetMax(Convert::ToNative(value)); + getNativeCollisionShape().SetMax(Convert::ToNative(value)); } /*---------------------------------------------------------------------------------*/ - /* BoxColliderBound - Usage Functions */ + /* BoxCollider - Usage Functions */ /*---------------------------------------------------------------------------------*/ bool BoxCollider::TestPoint(Vector3 point) { - return getNativeBoundObject().TestPoint(Convert::ToNative(point)); + return getNativeCollisionShape().TestPoint(Convert::ToNative(point)); } bool BoxCollider::Raycast(Ray ray, float maxDistance) { - return getNativeBoundObject().Raycast(Convert::ToNative(ray), maxDistance); + return getNativeCollisionShape().Raycast(Convert::ToNative(ray), maxDistance); } /*---------------------------------------------------------------------------------*/ - /* BoxColliderBound - Properties */ + /* SphereCollider - Properties */ /*---------------------------------------------------------------------------------*/ Vector3 SphereCollider::Center::get() { - return Convert::ToCLI(getNativeBoundObject().GetCenter()); + return Convert::ToCLI(getNativeCollisionShape().GetCenter()); } void SphereCollider::Center::set(Vector3 value) { - getNativeBoundObject().SetCenter(Convert::ToNative(value)); + getNativeCollisionShape().SetCenter(Convert::ToNative(value)); } float SphereCollider::Radius::get() { - return getNativeBoundObject().GetWorldRadius(); + return getNativeCollisionShape().GetWorldRadius(); } void SphereCollider::Radius::set(float value) { - getNativeBoundObject().SetWorldRadius(value); + getNativeCollisionShape().SetWorldRadius(value); } /*---------------------------------------------------------------------------------*/ - /* SphereColliderBound - Usage Functions */ + /* SphereCollider - Usage Functions */ /*---------------------------------------------------------------------------------*/ bool SphereCollider::TestPoint(Vector3 point) { - return getNativeBoundObject().TestPoint(Convert::ToNative(point)); + return getNativeCollisionShape().TestPoint(Convert::ToNative(point)); } bool SphereCollider::Raycast(Ray ray, float maxDistance) { - return getNativeBoundObject().Raycast(Convert::ToNative(ray), maxDistance); + return getNativeCollisionShape().Raycast(Convert::ToNative(ray), maxDistance); } /*---------------------------------------------------------------------------------*/ - /* SphereColliderBound - Constructors */ + /* SphereCollider - Constructors */ /*---------------------------------------------------------------------------------*/ SphereCollider::SphereCollider(int arrayIndex, Entity attachedEntity) : CollisionShape{ arrayIndex, attachedEntity } @@ -154,7 +235,7 @@ namespace SHADE } /*---------------------------------------------------------------------------------*/ - /* Collider - ColliderBound Functions */ + /* Collider - Collider Functions */ /*---------------------------------------------------------------------------------*/ CollisionShape^ Collider::GetCollisionShape(int index) { @@ -166,7 +247,7 @@ namespace SHADE // Check if valid if (index < 0 || index >= subColliderList->Count) - throw gcnew System::ArgumentException("[Collider] Invalid index for Collider Bound retrieval."); + throw gcnew System::ArgumentException("[Collider] Invalid index for Collision Shape retrieval."); // Return the bound return subColliderList[index]; @@ -217,7 +298,7 @@ namespace SHADE { collidersList->Remove(wr); } - SAFE_NATIVE_CALL_END("Collider.OnColliderBoundChanged") + SAFE_NATIVE_CALL_END("Collider.OnCollisionShapeChanged") } void Collider::updateSubColliderList() diff --git a/SHADE_Managed/src/Components/Collider.h++ b/SHADE_Managed/src/Components/Collider.h++ index 6e165619..8ea648aa 100644 --- a/SHADE_Managed/src/Components/Collider.h++ +++ b/SHADE_Managed/src/Components/Collider.h++ @@ -19,7 +19,7 @@ of DigiPen Institute of Technology is prohibited. namespace SHADE { template - CollisionShapeType& SHADE::CollisionShape::getNativeBoundObject() + CollisionShapeType& SHADE::CollisionShape::getNativeCollisionShape() { SHColliderComponent* collider = SHComponentManager::GetComponent_s(entity); if (!collider) @@ -29,13 +29,13 @@ namespace SHADE { auto& shape = collider->GetCollisionShape(arrayIndex); if (shape.GetType() != SHCollisionShape::Type::BOX) - throw gcnew System::InvalidOperationException("Attempted to retrieve invalid ColliderBound."); + throw gcnew System::InvalidOperationException("Attempted to retrieve invalid CollisionShape."); return reinterpret_cast(shape); } catch (std::invalid_argument&) { - throw gcnew System::IndexOutOfRangeException("Attempted to retrieve out of range ColliderBound!"); + throw gcnew System::IndexOutOfRangeException("Attempted to retrieve out of range CollisionShape!"); } } } diff --git a/SHADE_Managed/src/Components/Collider.hxx b/SHADE_Managed/src/Components/Collider.hxx index 1711e8b9..a649483f 100644 --- a/SHADE_Managed/src/Components/Collider.hxx +++ b/SHADE_Managed/src/Components/Collider.hxx @@ -30,6 +30,61 @@ namespace SHADE public ref class CollisionShape abstract { public: + /*-----------------------------------------------------------------------------*/ + /* Properties */ + /*-----------------------------------------------------------------------------*/ + + /// + /// Whether or not this CollisionShape is a trigger. + /// + property bool IsTrigger + { + bool get(); + void set(bool value); + } + /// + /// The positional offset of this collision shape from the transform's position. + /// + property Vector3 PositionOffset + { + Vector3 get(); + void set(Vector3 value); + } + /// + /// The rotational offset of this collision shape from the transform's rotation. + /// + property Vector3 RotationOffset + { + Vector3 get(); + void set(Vector3 value); + } + + // TODO(Diren): Swap this to Physics Materials once asset implementation for that is done + /// + /// The frictional coefficient of the shape. Clamped between 0 and 1. + /// + property float Friction + { + float get(); + void set(float value); + } + /// + /// The bounciness factor of the shape. Clamped between 0 and 1. + /// + property float Bounciness + { + float get(); + void set(float value); + } + /// + /// The mass density of this shape. Cannot be negative. + /// + property float Density + { + float get(); + void set(float value); + } + /*-----------------------------------------------------------------------------*/ /* Usage Functions */ /*-----------------------------------------------------------------------------*/ @@ -56,20 +111,25 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /* Data Members */ /*-----------------------------------------------------------------------------*/ - int arrayIndex; // Index into the colliders vector on the native object - Entity entity; // Entity holding the collider component that this collider bounds is on + int arrayIndex; // Index into the colliders vector on the native object + Entity entity; // Entity holding the collider component that this collider bounds is on /*-----------------------------------------------------------------------------*/ /* Helper Functions */ /*-----------------------------------------------------------------------------*/ template - CollisionShapeType& getNativeBoundObject(); + CollisionShapeType& getNativeCollisionShape(); internal: /*-----------------------------------------------------------------------------*/ /* Setter Functions */ /*-----------------------------------------------------------------------------*/ void updateArrayIndex(int index); + + /*-----------------------------------------------------------------------------*/ + /* Helper Functions */ + /*-----------------------------------------------------------------------------*/ + SHCollisionShape& getNativeCollisionShape(); }; /// @@ -205,18 +265,18 @@ namespace SHADE /* Usage Functions */ /*-----------------------------------------------------------------------------*/ /// - /// Retrieves a ColliderBound at the specified index in the ColliderBound list. + /// Retrieves a CollisionShape at the specified index in the CollisionShapes list. /// /// Index to retrieve a ColliderBound from. /// ColliderBound for the specified index. CollisionShape^ GetCollisionShape(int index); /// - /// Retrieves a ColliderBound at the specified index in the ColliderBound list + /// Retrieves a CollisionShape at the specified index in the CollisionShapes list /// and casts it to the appropriate type. /// - /// Type of the ColliderBound to cast to. - /// Index to retrieve a ColliderBound from. - /// ColliderBound for the specified index. + /// Type of the CollisionShape to cast to. + /// Index to retrieve a CollisionShape from. + /// CollisionShape for the specified index. generic where T:CollisionShape T GetCollisionShape(int index); From f172ccb74430cd26f24d1246bdd9d2d932f6aa79 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Tue, 15 Nov 2022 23:58:08 +0800 Subject: [PATCH 05/28] Added Automass and Sleep check for Rigidbodies --- .../Interface/SHRigidBodyComponent.cpp | 66 +++++++--- .../Physics/Interface/SHRigidBodyComponent.h | 18 ++- .../Physics/PhysicsObject/SHPhysicsObject.cpp | 14 +- .../src/Physics/System/SHPhysicsSystem.cpp | 123 ++++-------------- .../src/Physics/System/SHPhysicsSystem.h | 36 +++-- .../System/SHPhysicsSystemRoutines.cpp | 90 +++++++++++++ 6 files changed, 203 insertions(+), 144 deletions(-) diff --git a/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.cpp b/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.cpp index 765decd8..e892a5aa 100644 --- a/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.cpp +++ b/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.cpp @@ -29,7 +29,6 @@ namespace SHADE SHRigidBodyComponent::SHRigidBodyComponent() noexcept : type { Type::DYNAMIC } - , interpolate { true } , flags { 0 } , dirtyFlags { std::numeric_limits::max() } , mass { 1.0f } @@ -40,6 +39,7 @@ namespace SHADE // Initialise default flags flags |= 1U << 0; // Gravity set to true flags |= 1U << 1; // Sleeping allowed + flags |= 1U << 8; // Interpolate by default } /*-----------------------------------------------------------------------------------*/ @@ -60,7 +60,16 @@ namespace SHADE bool SHRigidBodyComponent::IsInterpolating() const noexcept { - return interpolate; + static constexpr int FLAG_POS = 8; + return flags & (1U << FLAG_POS); + } + + bool SHRigidBodyComponent::GetIsSleeping() const noexcept + { + if (auto* physicsObject = system->GetPhysicsObject(GetEID()); physicsObject) + return physicsObject->GetRigidBody()->isSleeping(); + + return false; } SHRigidBodyComponent::Type SHRigidBodyComponent::GetType() const noexcept @@ -68,21 +77,6 @@ namespace SHADE return type; } - float SHRigidBodyComponent::GetMass() const noexcept - { - return mass; - } - - float SHRigidBodyComponent::GetDrag() const noexcept - { - return drag; - } - - float SHRigidBodyComponent::GetAngularDrag() const noexcept - { - return angularDrag; - } - bool SHRigidBodyComponent::GetFreezePositionX() const noexcept { static constexpr int FLAG_POS = 2; @@ -119,6 +113,27 @@ namespace SHADE return flags & (1U << FLAG_POS); } + bool SHRigidBodyComponent::GetAutoMass() const noexcept + { + static constexpr int FLAG_POS = 9; + return flags & (1U << FLAG_POS); + } + + float SHRigidBodyComponent::GetMass() const noexcept + { + return mass; + } + + float SHRigidBodyComponent::GetDrag() const noexcept + { + return drag; + } + + float SHRigidBodyComponent::GetAngularDrag() const noexcept + { + return angularDrag; + } + SHVec3 SHRigidBodyComponent::GetForce() const noexcept { if (auto* physicsObject = system->GetPhysicsObject(GetEID()); physicsObject) @@ -295,9 +310,19 @@ namespace SHADE void SHRigidBodyComponent::SetInterpolate(bool allowInterpolation) noexcept { - interpolate = allowInterpolation; + static constexpr int FLAG_POS = 8; + allowInterpolation ? flags |= 1U << FLAG_POS : flags &= ~(1U << FLAG_POS); } + void SHRigidBodyComponent::SetAutoMass(bool autoMass) noexcept + { + static constexpr int FLAG_POS = 9; + autoMass ? flags |= 1U << FLAG_POS : flags &= ~(1U << FLAG_POS); + + dirtyFlags |= 1U << FLAG_POS; + } + + void SHRigidBodyComponent::SetMass(float newMass) noexcept { static constexpr int FLAG_POS = 9; @@ -313,6 +338,9 @@ namespace SHADE dirtyFlags |= 1U << FLAG_POS; mass = newMass; + + // Turn off automass + flags &= ~(1U << FLAG_POS); } void SHRigidBodyComponent::SetDrag(float newDrag) noexcept @@ -467,6 +495,8 @@ RTTR_REGISTRATION .property("Angular Drag" , &SHRigidBodyComponent::GetAngularDrag , &SHRigidBodyComponent::SetAngularDrag ) .property("Use Gravity" , &SHRigidBodyComponent::IsGravityEnabled , &SHRigidBodyComponent::SetGravityEnabled ) .property("Interpolate" , &SHRigidBodyComponent::IsInterpolating , &SHRigidBodyComponent::SetInterpolate ) + .property("Sleeping Enabled" , &SHRigidBodyComponent::IsAllowedToSleep , &SHRigidBodyComponent::SetIsAllowedToSleep) + .property("Auto Mass" , &SHRigidBodyComponent::GetAutoMass , &SHRigidBodyComponent::SetAutoMass ) .property("Freeze Position X" , &SHRigidBodyComponent::GetFreezePositionX , &SHRigidBodyComponent::SetFreezePositionX ) .property("Freeze Position Y" , &SHRigidBodyComponent::GetFreezePositionY , &SHRigidBodyComponent::SetFreezePositionY ) .property("Freeze Position Z" , &SHRigidBodyComponent::GetFreezePositionZ , &SHRigidBodyComponent::SetFreezePositionZ ) diff --git a/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.h b/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.h index f7062f96..658c60e1 100644 --- a/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.h +++ b/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.h @@ -71,19 +71,23 @@ namespace SHADE [[nodiscard]] bool IsAllowedToSleep () const noexcept; [[nodiscard]] bool IsInterpolating () const noexcept; + [[nodiscard]] bool GetIsSleeping () const noexcept; + [[nodiscard]] Type GetType () const noexcept; - [[nodiscard]] float GetMass () const noexcept; - [[nodiscard]] float GetDrag () const noexcept; - [[nodiscard]] float GetAngularDrag () const noexcept; - + [[nodiscard]] bool GetFreezePositionX () const noexcept; [[nodiscard]] bool GetFreezePositionY () const noexcept; [[nodiscard]] bool GetFreezePositionZ () const noexcept; - [[nodiscard]] bool GetFreezeRotationX () const noexcept; [[nodiscard]] bool GetFreezeRotationY () const noexcept; [[nodiscard]] bool GetFreezeRotationZ () const noexcept; + [[nodiscard]] bool GetAutoMass () const noexcept; + + [[nodiscard]] float GetMass () const noexcept; + [[nodiscard]] float GetDrag () const noexcept; + [[nodiscard]] float GetAngularDrag () const noexcept; + [[nodiscard]] SHVec3 GetForce () const noexcept; [[nodiscard]] SHVec3 GetTorque () const noexcept; [[nodiscard]] SHVec3 GetLinearVelocity () const noexcept; @@ -108,6 +112,7 @@ namespace SHADE void SetFreezeRotationY (bool freezeRotationY) noexcept; void SetFreezeRotationZ (bool freezeRotationZ) noexcept; void SetInterpolate (bool allowInterpolation) noexcept; + void SetAutoMass (bool autoMass) noexcept; void SetMass (float newMass) noexcept; void SetDrag (float newDrag) noexcept; @@ -144,8 +149,7 @@ namespace SHADE Type type; - bool interpolate; - uint8_t flags; // aZ aY aX lZ lY lX slp g + uint16_t flags; // 0 0 0 0 0 0 am ip aZ aY aX lZ lY lX slp g uint16_t dirtyFlags; // 0 0 0 0 aD d m t aZ aY aX lZ lY lX slp g float mass; diff --git a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp index a52d3899..eb94aecb 100644 --- a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp @@ -245,9 +245,17 @@ namespace SHADE } case 9: // Mass { - rp3dBody->setMass(component.mass); - rp3dBody->updateLocalCenterOfMassFromColliders(); - rp3dBody->updateLocalInertiaTensorFromColliders(); + if (component.GetAutoMass()) + { + rp3dBody->updateMassPropertiesFromColliders(); + component.mass = rp3dBody->getMass(); + } + else + { + rp3dBody->setMass(component.mass); + rp3dBody->updateLocalCenterOfMassFromColliders(); + rp3dBody->updateLocalInertiaTensorFromColliders(); + } break; } diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp index 33ba88e7..50590e04 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp @@ -154,14 +154,32 @@ namespace SHADE auto* rigidBodyComponent = SHComponentManager::GetComponent_s(entityID); auto* colliderComponent = SHComponentManager::GetComponent_s(entityID); - postUpdateSyncTransforms - ( - physicsObject - , transformComponent - , rigidBodyComponent - , colliderComponent - , 1.0 // We use 1.0 here to avoid any interpolation - ); + const auto& CURRENT_TF = physicsObject.GetRigidBody()->getTransform(); + const auto& RENDER_POS = CURRENT_TF.getPosition(); + const auto& RENDER_ROT = CURRENT_TF.getOrientation(); + + // Cache transform + physicsObject.prevTransform = CURRENT_TF; + + // Sync with physics components + if (rigidBodyComponent && SHSceneManager::CheckNodeAndComponentsActive(entityID)) + { + rigidBodyComponent->position = RENDER_POS; + rigidBodyComponent->orientation = RENDER_ROT; + } + + if (colliderComponent && SHSceneManager::CheckNodeAndComponentsActive(entityID)) + { + colliderComponent->position = RENDER_POS; + colliderComponent->orientation = RENDER_ROT; + } + + // Set transform for rendering + if (transformComponent) + { + transformComponent->SetWorldPosition(RENDER_POS); + transformComponent->SetWorldOrientation(RENDER_ROT); + } } } @@ -337,93 +355,4 @@ namespace SHADE return onStopEvent->handle; } - void SHPhysicsSystem::preUpdateSyncTransform - ( - SHPhysicsObject& physicsObject - , SHTransformComponent* transformComponent - , SHRigidBodyComponent* rigidBodyComponent - , SHColliderComponent* colliderComponent - ) noexcept - { - if (!transformComponent) - return; - - const SHVec3& WORLD_POS = transformComponent->GetWorldPosition(); - const SHQuaternion& WORLD_ROT = transformComponent->GetWorldOrientation(); - const SHVec3& WORLD_SCL = transformComponent->GetWorldScale(); - - const rp3d::Transform RP3D_TRANSFORM { WORLD_POS, WORLD_ROT }; - physicsObject.GetRigidBody()->setTransform(RP3D_TRANSFORM); - - if (rigidBodyComponent && SHSceneManager::CheckNodeAndComponentsActive(physicsObject.entityID)) - { - rigidBodyComponent->position = WORLD_POS; - rigidBodyComponent->orientation = WORLD_ROT; - } - - if (colliderComponent && SHSceneManager::CheckNodeAndComponentsActive(physicsObject.entityID)) - { - colliderComponent->position = WORLD_POS; - colliderComponent->orientation = WORLD_ROT; - colliderComponent->scale = WORLD_SCL; - - colliderComponent->RecomputeCollisionShapes(); - } - } - - void SHPhysicsSystem::postUpdateSyncTransforms - ( - SHPhysicsObject& physicsObject - , SHTransformComponent* transformComponent - , SHRigidBodyComponent* rigidBodyComponent - , SHColliderComponent* colliderComponent - , double interpolationFactor - ) noexcept - { - const rp3d::Transform& CURRENT_TF = physicsObject.GetRigidBody()->getTransform(); - auto renderPos = CURRENT_TF.getPosition(); - auto renderRot = CURRENT_TF.getOrientation(); - - // Cache transforms - if (physicsObject.GetRigidBody()->isActive()) - physicsObject.prevTransform = CURRENT_TF; - - // Sync with rigid bodies - if (rigidBodyComponent && SHSceneManager::CheckNodeAndComponentsActive(physicsObject.entityID)) - { - // Skip static bodies - if (rigidBodyComponent->GetType() == SHRigidBodyComponent::Type::STATIC) - return; - - // Check if transform should be interpolated - if (rigidBodyComponent->IsInterpolating()) - { - // Interpolate transforms between current and predicted next transform - - const rp3d::Transform PREV_TF = physicsObject.prevTransform; - const rp3d::Transform INTERPOLATED_TF = rp3d::Transform::interpolateTransforms(PREV_TF, CURRENT_TF, static_cast(interpolationFactor)); - - renderPos = INTERPOLATED_TF.getPosition(); - renderRot = INTERPOLATED_TF.getOrientation(); - } - - rigidBodyComponent->position = CURRENT_TF.getPosition(); - rigidBodyComponent->orientation = CURRENT_TF.getOrientation(); - } - - // Sync with colliders - if (colliderComponent && SHSceneManager::CheckNodeAndComponentsActive(physicsObject.entityID)) - { - colliderComponent->position = CURRENT_TF.getPosition(); - colliderComponent->orientation = CURRENT_TF.getOrientation(); - } - - // Set transform for rendering - if (transformComponent) - { - transformComponent->SetWorldPosition(renderPos); - transformComponent->SetWorldOrientation(renderRot); - } - } - } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h index 3da7094b..3e6cd622 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h @@ -113,6 +113,23 @@ namespace SHADE void syncRigidBodyActive (EntityID eid, SHPhysicsObject& physicsObject) const noexcept; void syncColliderActive (EntityID eid, SHPhysicsObject& physicsObject) const noexcept; static void syncOnPlay (EntityID eid, SHPhysicsObject& physicsObject) noexcept; + + static void preUpdateSyncTransform + ( + SHPhysicsObject& physicsObject + , SHTransformComponent* transformComponent + , SHRigidBodyComponent* rigidBodyComponent + , SHColliderComponent* colliderComponent + ) noexcept; + + static void postUpdateSyncTransforms + ( + SHPhysicsObject& physicsObject + , SHTransformComponent* transformComponent + , SHRigidBodyComponent* rigidBodyComponent + , SHColliderComponent* colliderComponent + , double interpolationFactor + ) noexcept; }; class SH_API PhysicsFixedUpdate final : public SHFixedSystemRoutine @@ -178,24 +195,5 @@ namespace SHADE SHEventHandle onPlay (SHEventPtr onPlayEvent); SHEventHandle onStop (SHEventPtr onStopEvent); - - - static void preUpdateSyncTransform - ( - SHPhysicsObject& physicsObject - , SHTransformComponent* transformComponent - , SHRigidBodyComponent* rigidBodyComponent - , SHColliderComponent* colliderComponent - ) noexcept; - - static void postUpdateSyncTransforms - ( - SHPhysicsObject& physicsObject - , SHTransformComponent* transformComponent - , SHRigidBodyComponent* rigidBodyComponent - , SHColliderComponent* colliderComponent - , double interpolationFactor - ) noexcept; - }; } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystemRoutines.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsSystemRoutines.cpp index 3e56ca14..f4719056 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystemRoutines.cpp +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystemRoutines.cpp @@ -262,4 +262,94 @@ namespace SHADE if (colliderComponent) physicsObject.SyncColliders(*colliderComponent); } + + void SHPhysicsSystem::PhysicsPreUpdate::preUpdateSyncTransform + ( + SHPhysicsObject& physicsObject + , SHTransformComponent* transformComponent + , SHRigidBodyComponent* rigidBodyComponent + , SHColliderComponent* colliderComponent + ) noexcept + { + if (!transformComponent) + return; + + const SHVec3& WORLD_POS = transformComponent->GetWorldPosition(); + const SHQuaternion& WORLD_ROT = transformComponent->GetWorldOrientation(); + const SHVec3& WORLD_SCL = transformComponent->GetWorldScale(); + + const rp3d::Transform RP3D_TRANSFORM { WORLD_POS, WORLD_ROT }; + physicsObject.GetRigidBody()->setTransform(RP3D_TRANSFORM); + physicsObject.prevTransform = RP3D_TRANSFORM; + + if (rigidBodyComponent && SHSceneManager::CheckNodeAndComponentsActive(physicsObject.entityID)) + { + rigidBodyComponent->position = WORLD_POS; + rigidBodyComponent->orientation = WORLD_ROT; + } + + if (colliderComponent && SHSceneManager::CheckNodeAndComponentsActive(physicsObject.entityID)) + { + colliderComponent->position = WORLD_POS; + colliderComponent->orientation = WORLD_ROT; + colliderComponent->scale = WORLD_SCL; + + colliderComponent->RecomputeCollisionShapes(); + } + } + + void SHPhysicsSystem::PhysicsPreUpdate::postUpdateSyncTransforms + ( + SHPhysicsObject& physicsObject + , SHTransformComponent* transformComponent + , SHRigidBodyComponent* rigidBodyComponent + , SHColliderComponent* colliderComponent + , double interpolationFactor + ) noexcept + { + const rp3d::Transform& CURRENT_TF = physicsObject.GetRigidBody()->getTransform(); + auto renderPos = CURRENT_TF.getPosition(); + auto renderRot = CURRENT_TF.getOrientation(); + + // Cache transforms + if (physicsObject.GetRigidBody()->isActive()) + physicsObject.prevTransform = CURRENT_TF; + + // Sync with rigid bodies + if (rigidBodyComponent && SHSceneManager::CheckNodeAndComponentsActive(physicsObject.entityID)) + { + // Skip static bodies + if (rigidBodyComponent->GetType() == SHRigidBodyComponent::Type::STATIC) + return; + + // Check if transform should be interpolated + if (rigidBodyComponent->IsInterpolating()) + { + // Interpolate transforms between current and predicted next transform + + const rp3d::Transform PREV_TF = physicsObject.prevTransform; + const rp3d::Transform INTERPOLATED_TF = rp3d::Transform::interpolateTransforms(PREV_TF, CURRENT_TF, static_cast(interpolationFactor)); + + renderPos = INTERPOLATED_TF.getPosition(); + renderRot = INTERPOLATED_TF.getOrientation(); + } + + rigidBodyComponent->position = CURRENT_TF.getPosition(); + rigidBodyComponent->orientation = CURRENT_TF.getOrientation(); + } + + // Sync with colliders + if (colliderComponent && SHSceneManager::CheckNodeAndComponentsActive(physicsObject.entityID)) + { + colliderComponent->position = CURRENT_TF.getPosition(); + colliderComponent->orientation = CURRENT_TF.getOrientation(); + } + + // Set transform for rendering + if (transformComponent) + { + transformComponent->SetWorldPosition(renderPos); + transformComponent->SetWorldOrientation(renderRot); + } + } } // namespace SHADE \ No newline at end of file From a9f77d666c2dc88512bbd02d4313e460f2e6bcf7 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Wed, 16 Nov 2022 00:04:56 +0800 Subject: [PATCH 06/28] Fixed compile error --- .../src/Physics/System/SHPhysicsSystem.h | 24 ++++++++++++------- .../System/SHPhysicsSystemRoutines.cpp | 2 +- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h index 3e6cd622..9638e05c 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h @@ -121,15 +121,6 @@ namespace SHADE , SHRigidBodyComponent* rigidBodyComponent , SHColliderComponent* colliderComponent ) noexcept; - - static void postUpdateSyncTransforms - ( - SHPhysicsObject& physicsObject - , SHTransformComponent* transformComponent - , SHRigidBodyComponent* rigidBodyComponent - , SHColliderComponent* colliderComponent - , double interpolationFactor - ) noexcept; }; class SH_API PhysicsFixedUpdate final : public SHFixedSystemRoutine @@ -162,6 +153,21 @@ namespace SHADE /*-------------------------------------------------------------------------------*/ void Execute(double dt) noexcept override; + + private: + + /*-------------------------------------------------------------------------------*/ + /* Function Members */ + /*-------------------------------------------------------------------------------*/ + + static void postUpdateSyncTransforms + ( + SHPhysicsObject& physicsObject + , SHTransformComponent* transformComponent + , SHRigidBodyComponent* rigidBodyComponent + , SHColliderComponent* colliderComponent + , double interpolationFactor + ) noexcept; }; private: diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystemRoutines.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsSystemRoutines.cpp index f4719056..9d860bf9 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystemRoutines.cpp +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystemRoutines.cpp @@ -298,7 +298,7 @@ namespace SHADE } } - void SHPhysicsSystem::PhysicsPreUpdate::postUpdateSyncTransforms + void SHPhysicsSystem::PhysicsPostUpdate::postUpdateSyncTransforms ( SHPhysicsObject& physicsObject , SHTransformComponent* transformComponent From 3affaf426d5d82799f2757792dd73644c4f1240e Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Wed, 16 Nov 2022 09:06:29 +0800 Subject: [PATCH 07/28] WIP Runtime Material Editing support --- Assets/Scenes/M2Scene.shade | 177 ------------------ Assets/Shaders/Normals_FS.glsl | 50 +++++ Assets/Shaders/Normals_FS.shshaderb | Bin 0 -> 2437 bytes Assets/Shaders/Normals_FS.shshaderb.shmeta | 3 + .../MaterialInspector/SHMaterialInspector.cpp | 51 ++++- .../Graphics/Descriptors/SHVkDescriptorPool.h | 10 +- .../Graphics/MiddleEnd/Batching/SHBatch.cpp | 79 ++++++++ .../src/Graphics/MiddleEnd/Batching/SHBatch.h | 5 + .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 16 +- .../Interface/SHMaterialInstance.cpp | 3 +- .../MiddleEnd/Interface/SHMaterialInstance.h | 1 + .../MiddleEnd/Interface/SHRenderable.cpp | 22 +++ .../MiddleEnd/Interface/SHRenderable.h | 6 +- 13 files changed, 230 insertions(+), 193 deletions(-) create mode 100644 Assets/Shaders/Normals_FS.glsl create mode 100644 Assets/Shaders/Normals_FS.shshaderb create mode 100644 Assets/Shaders/Normals_FS.shshaderb.shmeta diff --git a/Assets/Scenes/M2Scene.shade b/Assets/Scenes/M2Scene.shade index bf910737..8b61dc67 100644 --- a/Assets/Scenes/M2Scene.shade +++ b/Assets/Scenes/M2Scene.shade @@ -21,141 +21,6 @@ Layer: 4294967295 Strength: 0 Scripts: ~ -- EID: 1 - Name: Floor - IsActive: true - NumberOfChildren: 0 - Components: - Transform Component: - Translate: {x: -1.440328, y: -4.41369677, z: -5} - Rotate: {x: -0, y: 0, z: -0} - Scale: {x: 49.4798889, y: 0.5, z: 17.5} - Renderable Component: - Mesh: 149697411 - Material: 126974645 - RigidBody Component: - Type: Static - Mass: 1 - Drag: 0.00999999978 - Angular Drag: 0.00999999978 - Use Gravity: true - Interpolate: true - Freeze Position X: false - Freeze Position Y: false - Freeze Position Z: false - Freeze Rotation X: false - Freeze Rotation Y: false - Freeze Rotation Z: false - Collider Component: - Colliders: - - Is Trigger: false - Type: Box - Half Extents: {x: 1, y: 1, z: 1} - Friction: 0.400000006 - Bounciness: 0 - Density: 1 - Position Offset: {x: 0, y: 0, z: 0} - Scripts: ~ -- EID: 10 - Name: Default - IsActive: true - NumberOfChildren: 0 - Components: - Transform Component: - Translate: {x: -4.40482807, y: 2.57871056, z: -5.21213436} - Rotate: {x: -0.361265004, y: 1.11661232, z: -0.626627684} - Scale: {x: 0.999982238, y: 0.999987125, z: 0.999981165} - RigidBody Component: - Type: Dynamic - Mass: 1 - Drag: 0 - Angular Drag: 0 - Use Gravity: true - Interpolate: true - Freeze Position X: false - Freeze Position Y: false - Freeze Position Z: false - Freeze Rotation X: false - Freeze Rotation Y: false - Freeze Rotation Z: false - Collider Component: - Colliders: - - Is Trigger: false - Type: Box - Half Extents: {x: 1, y: 1, z: 1} - Friction: 0.400000006 - Bounciness: 0 - Density: 1 - Position Offset: {x: 0, y: 0, z: 0} - Scripts: ~ -- EID: 3 - Name: Empty - IsActive: true - NumberOfChildren: 0 - Components: - Transform Component: - Translate: {x: -0.0094268322, y: 0, z: 0} - Rotate: {x: -0, y: 0, z: -0} - Scale: {x: 1, y: 1, z: 1} - Scripts: ~ -- EID: 4 - Name: Empty2 - IsActive: true - NumberOfChildren: 0 - Components: - Transform Component: - Translate: {x: 0, y: 0, z: 0} - Rotate: {x: 0, y: 0, z: 0} - Scale: {x: 1, y: 1, z: 1} - Scripts: ~ -- EID: 9 - Name: Bag - IsActive: true - NumberOfChildren: 0 - Components: - Transform Component: - Translate: {x: 0, y: 0, z: 0} - Rotate: {x: 0, y: 0, z: 0} - Scale: {x: 1, y: 1, z: 1} - Renderable Component: - Mesh: 144838771 - Material: 123745521 - Scripts: ~ -- EID: 6 - Name: AI - IsActive: true - NumberOfChildren: 0 - Components: - Transform Component: - Translate: {x: -8, y: -2, z: 2.5} - Rotate: {x: 0, y: 0, z: 0} - Scale: {x: 1, y: 1, z: 1} - Renderable Component: - Mesh: 149697411 - Material: 126974645 - RigidBody Component: - Type: Dynamic - Mass: 1 - Drag: 0 - Angular Drag: 0 - Use Gravity: true - Interpolate: false - Freeze Position X: false - Freeze Position Y: false - Freeze Position Z: false - Freeze Rotation X: true - Freeze Rotation Y: true - Freeze Rotation Z: true - Collider Component: - Colliders: - - Is Trigger: false - Type: Box - Half Extents: {x: 0.5, y: 0.5, z: 0.5} - Friction: 0.400000006 - Bounciness: 0 - Density: 1 - Position Offset: {x: 0, y: 0.5, z: 0} - Scripts: ~ - EID: 7 Name: BigBoi IsActive: true @@ -181,46 +46,4 @@ Color: {x: 1, y: 1, z: 1, w: 1} Layer: 4294967295 Strength: 0.25 - Scripts: ~ -- EID: 5 - Name: item - IsActive: true - NumberOfChildren: 0 - Components: - Transform Component: - Translate: {x: 0, y: -2, z: -5} - Rotate: {x: 0, y: 0, z: 0} - Scale: {x: 2, y: 2, z: 2} - Renderable Component: - Mesh: 144838771 - Material: 123745521 - RigidBody Component: - Type: Dynamic - Mass: 1 - Drag: 0 - Angular Drag: 0 - Use Gravity: true - Interpolate: false - Freeze Position X: false - Freeze Position Y: false - Freeze Position Z: false - Freeze Rotation X: true - Freeze Rotation Y: true - Freeze Rotation Z: true - Collider Component: - Colliders: - - Is Trigger: false - Type: Box - Half Extents: {x: 1, y: 1, z: 1} - Friction: 0.400000006 - Bounciness: 0 - Density: 1 - Position Offset: {x: 0, y: 0.5, z: 0} - - Is Trigger: true - Type: Box - Half Extents: {x: 2, y: 2, z: 2} - Friction: 0.400000006 - Bounciness: 0 - Density: 1 - Position Offset: {x: 0, y: 0.5, z: 0} Scripts: ~ \ No newline at end of file diff --git a/Assets/Shaders/Normals_FS.glsl b/Assets/Shaders/Normals_FS.glsl new file mode 100644 index 00000000..ba260d82 --- /dev/null +++ b/Assets/Shaders/Normals_FS.glsl @@ -0,0 +1,50 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable +#extension GL_EXT_nonuniform_qualifier : require + +struct MatPropData +{ + vec4 color; + int textureIndex; + float alpha; + vec3 beta; +}; + +layout(location = 0) in struct +{ + vec4 vertPos; // location 0 + vec2 uv; // location = 1 + vec4 normal; // location = 2 + +} In; + +// material stuff +layout(location = 3) flat in struct +{ + int materialIndex; + uint eid; + uint lightLayerIndex; +} In2; + +layout (set = 0, binding = 1) uniform sampler2D textures[]; // for textures (global) +layout (std430, set = 3, binding = 0) buffer MaterialProperties // For materials +{ + MatPropData data[]; +} MatProp; + +layout(location = 0) out vec4 position; +layout(location = 1) out uint outEntityID; +layout(location = 2) out uint lightLayerIndices; +layout(location = 3) out vec4 normals; +layout(location = 4) out vec4 albedo; + +void main() +{ + position = In.vertPos; + normals = In.normal; + albedo = normals * texture(textures[nonuniformEXT(MatProp.data[In2.materialIndex].textureIndex)], In.uv) * MatProp.data[In2.materialIndex].color; + + outEntityID = In2.eid; + lightLayerIndices = In2.lightLayerIndex; +} \ No newline at end of file diff --git a/Assets/Shaders/Normals_FS.shshaderb b/Assets/Shaders/Normals_FS.shshaderb new file mode 100644 index 0000000000000000000000000000000000000000..7595ece992210bbf6849ea1b242415990e5f4c3b GIT binary patch literal 2437 zcmZ9MU2_yw5Qb0K-4Mf95CIX18=|730b@WE`3Ol|Q?(W;W2tvjlbu6ybTYHf%%(_{ zxBesb#yfwNH&*#RGv_P=r>eKR-|o|2r)L*_d(G6Rb7J|VF*9b~oH1WFkU4Ko2r)JP z^Noi8<@w*@^JdQM?)(sK{q%j5*m6|3ag`U5%M$zCW&7ronXT^+hP%U+vPxFg?%XEy zS<|UA5c`}tZMx#nVeB#tlypXPL3CMkL-a_rAzIK~d{wNZjw&?f9|h{_)?gT|fA=IR z?Km#t%0}fuoY*4D_kOmcs(jf;CY2baakf8+_iePcdV3s?eo>q`;?Po-XOql5%ZtP4 z*GZhZXU-O~&to4veL5I!MWgXJDy!qvMybnel(<5f+>s?$9mo5*Y?MxtwnI-I?Vfw4 zSNA>6OINwPoX`v=u9KDI^UO-%N0J6l!!UcHC;q}s|VR~>I}3OQNtUZtJ`UI&;9zd!Vx$=)A{u5hv)(f!e=O_V5nOffF$7U<)mb{=oF< zPW{LW))x^UJ}crwCDxKS2OrKrm4a~(e{kw+>){T*%n?;^R8eQrPFWU>o>iAPCAGCya~ST8rTDB2>!egHG~@33+z|4 zQCGyNkr?e0^sDlGO9uR|NxmwMPVTqGIbg&_XU917&uocJu0=`g7j@DTICf(8#j!0) zUJ^$q{&jKc1|vTDvd5UsyOR4N4)f(ZBsO?s>zel^&xo)Q1O0}_$nk-fxfkYjvt|ES zGBq^s(5-h_>U0L5NhUsTO1v+{@el9&P%`~f5Bbp_c?|!@lDXfuZ+QD%^+c?$h(nxz zh4jSN^~>9z7qKtw!~=Pf_jM8YL)~B>(S!d*$@sGq!T*wEaQxXF^k92aG8p%n)rTVH z7xFQek37Dv?9A&E5$}W#Hs(n@d{;!+cfEegW5nlwf^U}{0_P69#y1R(5A$9V(L;#K z?C*H|NBJ;=yCUv^|L(ERCDRYK(9b=|ulDnWFmU?eJ@1P`KiER=0<>vm1@x_-{(5zVKf7Z;8P1XIIew(-z$m{SP7H(sTd- literal 0 HcmV?d00001 diff --git a/Assets/Shaders/Normals_FS.shshaderb.shmeta b/Assets/Shaders/Normals_FS.shshaderb.shmeta new file mode 100644 index 00000000..38544c0a --- /dev/null +++ b/Assets/Shaders/Normals_FS.shshaderb.shmeta @@ -0,0 +1,3 @@ +Name: Normals_FS +ID: 48689301 +Type: 2 diff --git a/SHADE_Engine/src/Editor/EditorWindow/MaterialInspector/SHMaterialInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/MaterialInspector/SHMaterialInspector.cpp index 13ecb9fa..2f87a97c 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/MaterialInspector/SHMaterialInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/MaterialInspector/SHMaterialInspector.cpp @@ -78,7 +78,26 @@ namespace SHADE ImGui::BeginDisabled(!isDirty); if(ImGui::Button(std::format("{} Save", ICON_MD_SAVE).data())) { - //save + // Replace Material if it's been instantiated + auto matHandle = SHResourceManager::Get(currentViewedMaterial); + if (matHandle) + { + // - Get Shader Modules + auto vertShader = SHResourceManager::LoadOrGet(currentMatSpec->vertexShader); + auto fragShader = SHResourceManager::LoadOrGet(currentMatSpec->fragShader); + auto gfxSystem = SHSystemManager::GetSystem(); + if (vertShader && fragShader && gfxSystem) + { + // - Retrieve pipeline from pipeline library + auto renderPass = gfxSystem->GetPrimaryRenderpass(); + auto subPass = renderPass->GetSubpass(currentMatSpec->subpassName); + auto pipeline = renderPass->GetOrCreatePipeline({ vertShader, fragShader }, subPass); + // - Set Pipeline + matHandle->SetPipeline(pipeline); + } + } + + // Save Properties if(auto matAsset = SHAssetManager::GetData(currentViewedMaterial)) { YAML::Emitter out; @@ -136,12 +155,36 @@ namespace SHADE { /*if(!shaderModule) return;*/ - auto gfxSystem = SHSystemManager::GetSystem(); - auto interface = gfxSystem->GetDefaultMaterialInstance()->GetBaseMaterial()->GetShaderBlockInterface(); //auto interface = shaderModule->GetReflectedData().GetDescriptorBindingInfo().GetShaderBlockInterface(SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA); - int const varCount = static_cast(interface->GetVariableCount()); + // Shader + bool shaderChanged = false; + const auto* SHADER_INFO = SHAssetManager::GetData(currentMatSpec->fragShader); + const std::string SHADER_NAME = SHADER_INFO ? SHADER_INFO->name : "Unknown Shader"; + isDirty |= SHEditorWidgets::DragDropReadOnlyField + ( + "Fragment Shader", SHADER_NAME.data(), + [this]() { return currentMatSpec->fragShader; }, + [this](const AssetID& id) { currentMatSpec->fragShader = id; }, + SHDragDrop::DRAG_RESOURCE + ); + // Load the shader to access it's data + auto fragShader = SHResourceManager::LoadOrGet(currentMatSpec->fragShader); + if (!fragShader) + return; + + // Get interface for the shader combination + auto interface = fragShader->GetReflectedData().GetDescriptorBindingInfo().GetShaderBlockInterface + ( + SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, + SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA + ); + if (!interface) + return; + + // Properties + int const varCount = static_cast(interface->GetVariableCount()); for (int i = 0; i < varCount; ++i) { auto variable = interface->GetVariable(i); diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.h b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.h index c822829a..1e8d6a3e 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.h +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.h @@ -38,11 +38,11 @@ namespace SHADE /// std::vector Limits = { - { vk::DescriptorType::eCombinedImageSampler, 100 }, - { vk::DescriptorType::eUniformBuffer, 100 }, - { vk::DescriptorType::eUniformBufferDynamic, 100 }, - { vk::DescriptorType::eStorageImage, 100}, - { vk::DescriptorType::eStorageBufferDynamic, 100 } + { vk::DescriptorType::eCombinedImageSampler, 1000 }, + { vk::DescriptorType::eUniformBuffer, 1000 }, + { vk::DescriptorType::eUniformBufferDynamic, 1000 }, + { vk::DescriptorType::eStorageImage, 1000 }, + { vk::DescriptorType::eStorageBufferDynamic, 1000 } }; /// /// Maximum number of descriptor sets allowed diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index 1829096f..2a2b66d4 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -43,6 +43,85 @@ namespace SHADE setAllDirtyFlags(); } + SHBatch::SHBatch(SHBatch&& rhs) + : device { rhs.device } + , pipeline { rhs.pipeline } + , referencedMatInstances { std::move(rhs.referencedMatInstances) } + , matBufferDirty { std::move(rhs.matBufferDirty) } + , subBatches { std::move(rhs.subBatches) } + , drawData { std::move(drawData) } + , transformData { std::move(rhs.transformData) } + , instancedIntegerData { std::move(rhs.instancedIntegerData) } + , matPropsData { std::move(rhs.matPropsData) } + , matPropsDataSize { rhs.matPropsDataSize } + , singleMatPropAlignedSize { rhs.singleMatPropAlignedSize } + , singleMatPropSize { rhs.singleMatPropSize } + , isCPUBuffersDirty { rhs.isCPUBuffersDirty } + , drawDataBuffer { rhs.drawDataBuffer } + , transformDataBuffer { rhs.transformDataBuffer } + , instancedIntegerBuffer { rhs.instancedIntegerBuffer } + , matPropsBuffer { rhs.matPropsBuffer } + , matPropsDescSet { rhs.matPropsDescSet } + { + rhs.drawDataBuffer = {}; + rhs.transformDataBuffer = {}; + rhs.instancedIntegerBuffer = {}; + rhs.matPropsBuffer = {}; + rhs.matPropsDescSet = {}; + } + + SHBatch& SHBatch::operator=(SHBatch&& rhs) + { + if (this == &rhs) + return *this; + + device = rhs.device ; + pipeline = rhs.pipeline ; + referencedMatInstances = std::move(rhs.referencedMatInstances); + matBufferDirty = std::move(rhs.matBufferDirty) ; + subBatches = std::move(rhs.subBatches) ; + drawData = std::move(drawData) ; + transformData = std::move(rhs.transformData) ; + instancedIntegerData = std::move(rhs.instancedIntegerData) ; + matPropsData = std::move(rhs.matPropsData) ; + matPropsDataSize = rhs.matPropsDataSize ; + singleMatPropAlignedSize = rhs.singleMatPropAlignedSize ; + singleMatPropSize = rhs.singleMatPropSize ; + isCPUBuffersDirty = rhs.isCPUBuffersDirty ; + drawDataBuffer = rhs.drawDataBuffer ; + transformDataBuffer = rhs.transformDataBuffer ; + instancedIntegerBuffer = rhs.instancedIntegerBuffer ; + matPropsBuffer = rhs.matPropsBuffer ; + matPropsDescSet = rhs.matPropsDescSet ; + + // Unset values + rhs.drawDataBuffer = {}; + rhs.transformDataBuffer = {}; + rhs.instancedIntegerBuffer = {}; + rhs.matPropsBuffer = {}; + rhs.matPropsDescSet = {}; + + return *this; + } + + SHBatch::~SHBatch() + { + // Free GPU buffers + for (int i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i) + { + if (drawDataBuffer[i]) + drawDataBuffer[i].Free(); + if (transformDataBuffer[i]) + transformDataBuffer[i].Free(); + if (instancedIntegerBuffer[i]) + instancedIntegerBuffer[i].Free(); + if (matPropsBuffer[i]) + matPropsBuffer[i].Free(); + if (matPropsDescSet[i]) + matPropsDescSet[i].Free(); + } + } + void SHBatch::Add(const SHRenderable* renderable) { // Ignore if null diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h index c9dd4eda..498e807f 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h @@ -71,6 +71,11 @@ namespace SHADE /* Constructor/Destructors */ /*-----------------------------------------------------------------------------*/ SHBatch(Handle pipeline); + SHBatch(const SHBatch&) = delete; + SHBatch(SHBatch&& rhs); + SHBatch& operator=(const SHBatch&) = delete; + SHBatch& operator=(SHBatch&& rhs); + ~SHBatch(); /*-----------------------------------------------------------------------------*/ /* Usage Functions */ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index fc157d7d..3e63eb0d 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -849,11 +849,16 @@ namespace SHADE void SHGraphicsSystem::BatcherDispatcherRoutine::Execute(double) noexcept { - auto& renderables = SHComponentManager::GetDense(); + auto& renderables = SHComponentManager::GetDense(); for (auto& renderable : renderables) { + // Check if the material instance is now unused + renderable.CleanUpMaterials(); + if (!renderable.HasChanged()) - continue; + continue; + + // TODO: Need to account for // Remove from the SuperBatch it is previously in (prevMat if mat has changed) Handle prevMaterial = renderable.HasMaterialChanged() ? renderable.GetPrevMaterial() : renderable.GetMaterial(); @@ -862,9 +867,8 @@ namespace SHADE Handle oldSuperBatch = prevMaterial->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpass()->GetSuperBatch(); oldSuperBatch->Remove(&renderable); } - - // Add to new SuperBatch if there is a material - // Add to new SuperBatch if there is a material and a mesh to render + + // Add to new SuperBatch if there is a material and a mesh to render Handle newMatInstance = renderable.GetMaterial(); if (newMatInstance && renderable.GetMesh()) { @@ -875,6 +879,8 @@ namespace SHADE // Unset change flag renderable.ResetChangedFlag(); } + + // TODO: Also reset all material instances isDrity } #pragma endregion ROUTINES diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.cpp index b30acfb8..a700c4f0 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.cpp @@ -35,6 +35,7 @@ namespace SHADE memset(dataStore.get(), 0, dataStoreSize); overrideData.clear(); dataStore.reset(); + dataWasChanged = true; } void SHMaterialInstance::ExportProperties(void* dest) @@ -61,7 +62,7 @@ namespace SHADE } // Data was exported so unflag - dataWasChanged = false; + //dataWasChanged = false; } /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.h index b6fcc830..ef821a9b 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.h @@ -70,6 +70,7 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ Handle GetBaseMaterial() const noexcept { return baseMaterial; } bool HasChanged() const noexcept { return dataWasChanged; } + bool IsBlank() const noexcept { return overrideData.empty(); } // No overrides private: /*-----------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp index c5511606..8bb98ebb 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp @@ -96,6 +96,14 @@ namespace SHADE return material; } + void SHRenderable::CleanUpMaterials() noexcept + { + if (material && material->IsBlank()) + { + SetMaterial(sharedMaterial); + } + } + /*-----------------------------------------------------------------------------------*/ /* Mesh Functions */ /*-----------------------------------------------------------------------------------*/ @@ -114,6 +122,20 @@ namespace SHADE return lightLayer; } + bool SHRenderable::HasChanged() const noexcept + { + if (matChanged || meshChanged) + return true; + + // If the underlying material has changed + auto mat = GetMaterial(); + if (mat) + { + return mat->HasChanged(); + } + return false; + } + /*-----------------------------------------------------------------------------------*/ /* Batcher Dispatcher Functions */ /*-----------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.h index 8893c43b..f1455ef4 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.h @@ -53,6 +53,10 @@ namespace SHADE Handle GetModifiableMaterial(); Handle GetPrevMaterial() const noexcept { return oldMaterial; } bool HasMaterialChanged() const noexcept { return matChanged; } + /// + /// Clears the modifiable material if it is unused. + /// + void CleanUpMaterials() noexcept; /*-------------------------------------------------------------------------------*/ /* Mesh Functions */ @@ -70,7 +74,7 @@ namespace SHADE /*-------------------------------------------------------------------------------*/ /* Batcher Dispatcher Functions */ /*-------------------------------------------------------------------------------*/ - bool HasChanged() const noexcept { return matChanged || meshChanged; } // Whether or not the mesh or material has changed + bool HasChanged() const noexcept; // Whether or not the mesh or material has changed void ResetChangedFlag(); // TODO: Lock it so that only SHBatcherDispatcher can access this private: From 1bd71832310686f7a7ccd72ad220a7717e2cf4f2 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Wed, 16 Nov 2022 17:30:19 +0800 Subject: [PATCH 08/28] Added validation for Renderable drag drop fields --- SHADE_Engine/src/Assets/SHAssetManager.cpp | 12 +++++ SHADE_Engine/src/Assets/SHAssetManager.h | 2 + .../src/Editor/DragDrop/SHDragDrop.cpp | 7 ++- .../src/Editor/DragDrop/SHDragDrop.hpp | 13 ++++-- .../HierarchyPanel/SHHierarchyPanel.cpp | 46 +++++++++---------- .../HierarchyPanel/SHHierarchyPanel.h | 3 +- .../Inspector/SHEditorComponentView.hpp | 10 ++++ 7 files changed, 64 insertions(+), 29 deletions(-) diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index b4ea7d35..8d2c8dc3 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -143,6 +143,18 @@ namespace SHADE return result; } + AssetType SHAssetManager::GetType(AssetID id) noexcept + { + if (assetCollection.contains(id)) + { + return assetCollection[id].type; + } + + SHLOG_WARNING("AssetID {}, does not belong to an asset", id) + + return AssetType::INVALID; + } + /**************************************************************************** * \brief Create record for new asset. CAN ONLY CREATE FOR CUSTOM * ASSETS CREATED BY THE ENGINE. diff --git a/SHADE_Engine/src/Assets/SHAssetManager.h b/SHADE_Engine/src/Assets/SHAssetManager.h index f6ecb3a3..0962a41f 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.h +++ b/SHADE_Engine/src/Assets/SHAssetManager.h @@ -51,6 +51,8 @@ namespace SHADE ****************************************************************************/ static std::vector GetAllAssets() noexcept; + static AssetType GetType(AssetID id) noexcept; + /**************************************************************************** * \brief Create record for new resource. CAN ONLY CREATE FOR CUSTOM * RESOURCES CREATED BY THE ENGINE. diff --git a/SHADE_Engine/src/Editor/DragDrop/SHDragDrop.cpp b/SHADE_Engine/src/Editor/DragDrop/SHDragDrop.cpp index 97fd8a22..4c56d032 100644 --- a/SHADE_Engine/src/Editor/DragDrop/SHDragDrop.cpp +++ b/SHADE_Engine/src/Editor/DragDrop/SHDragDrop.cpp @@ -5,6 +5,7 @@ namespace SHADE { bool SHDragDrop::hasDragDrop = false; + SHDragDrop::DragDropTag SHDragDrop::currentDragDropTag{}; bool SHDragDrop::BeginSource(ImGuiDragDropFlags const flags) { return ImGui::BeginDragDropSource(flags); } @@ -16,6 +17,10 @@ namespace SHADE { return ImGui::BeginDragDropTarget(); } void SHDragDrop::EndTarget() - { ImGui::EndDragDropTarget(); hasDragDrop = false;} + { + ImGui::EndDragDropTarget(); + hasDragDrop = false; + currentDragDropTag = {}; + } } diff --git a/SHADE_Engine/src/Editor/DragDrop/SHDragDrop.hpp b/SHADE_Engine/src/Editor/DragDrop/SHDragDrop.hpp index ce0615e1..f111eaeb 100644 --- a/SHADE_Engine/src/Editor/DragDrop/SHDragDrop.hpp +++ b/SHADE_Engine/src/Editor/DragDrop/SHDragDrop.hpp @@ -19,9 +19,13 @@ namespace SHADE static void EndSource(); template - static bool SetPayload(std::string_view const type, T* object, ImGuiCond const cond = 0) + static bool SetPayload(DragDropTag const& type, T* object, ImGuiCond const cond = 0) { - hasDragDrop = ImGui::SetDragDropPayload(type.data(), static_cast(object), sizeof(T), cond); + ImGui::SetDragDropPayload(type.data(), static_cast(object), sizeof(T), cond); + + hasDragDrop = true; + currentDragDropTag = type; + return hasDragDrop; } @@ -32,13 +36,16 @@ namespace SHADE static void EndTarget(); template - static T* AcceptPayload(std::string_view const type, ImGuiDragDropFlags const flags = 0) + static T* AcceptPayload(DragDropTag const& type, ImGuiDragDropFlags const flags = 0) { if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload(type.data(), flags)) + { return static_cast(payload->Data); + } return nullptr; } static bool hasDragDrop; + static DragDropTag currentDragDropTag; }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp index cf545223..2235f831 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp @@ -117,9 +117,12 @@ namespace SHADE { if(ImGui::IsDragDropActive()) { - ParentSelectedEntities(MAX_EID, draggingEntities); - draggingEntities.clear(); - ImGui::ClearDragDrop(); + if (SHDragDrop::currentDragDropTag == SHDragDrop::DRAG_EID) + { + ParentSelectedEntities(MAX_EID, draggingEntities); + draggingEntities.clear(); + ImGui::ClearDragDrop(); + } } } ImGui::End(); @@ -233,8 +236,9 @@ namespace SHADE { ParentSelectedEntities(eid, draggingEntities); draggingEntities.clear(); - SHDragDrop::EndTarget(); + //ImGui::ClearDragDrop(); } + SHDragDrop::EndTarget(); } //Context menu @@ -342,17 +346,12 @@ namespace SHADE SHEntityManager::CreateEntity(MAX_EID, "DefaultChild", parentEID); } - void SHHierarchyPanel::ParentSelectedEntities(EntityID parentEID, std::vector const& entities) const noexcept + void SHHierarchyPanel::ParentSelectedEntities(EntityID parentEID, std::vector const& entities) noexcept { auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); - std::vector entitiesToParent{}; - std::ranges::copy_if(entities, std::back_inserter(entitiesToParent), [&sceneGraph](EntityID const& eid) - { - if (sceneGraph.GetParent(eid)->GetEntityID() == MAX_EID) - return true; - return false; - }); + std::vector entitiesToParent = CleanUpEIDList(entities); + //auto const editor = SHSystemManager::GetSystem(); SHEntityParentCommand::EntityParentData entityParentData; std::vector parentedEIDS; @@ -419,14 +418,7 @@ namespace SHADE void SHHierarchyPanel::CopySelectedEntities() { const auto editor = SHSystemManager::GetSystem(); - auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); - std::vector entitiesToCopy{}; - std::ranges::copy_if(editor->selectedEntities, std::back_inserter(entitiesToCopy), [&sceneGraph](EntityID const& eid) - { - if(sceneGraph.GetParent(eid)->GetEntityID() == MAX_EID) - return true; - return false; - }); + std::vector entitiesToCopy = CleanUpEIDList(editor->selectedEntities); SHClipboardUtilities::WriteToClipboard(SHSerialization::SerializeEntitiesToString(entitiesToCopy)); } @@ -439,19 +431,25 @@ namespace SHADE void SHHierarchyPanel::DeleteSelectedEntities() { const auto editor = SHSystemManager::GetSystem(); + std::vector entitiesToDelete = CleanUpEIDList(editor->selectedEntities); + SHCommandManager::PerformCommand(std::make_shared(entitiesToDelete)); + } + + std::vector SHHierarchyPanel::CleanUpEIDList(std::vector const& entities) + { + std::vector result; auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); - std::vector entitiesToDelete{}; - std::ranges::copy_if(editor->selectedEntities, std::back_inserter(entitiesToDelete), [&sceneGraph, &selectedEntities = editor->selectedEntities](EntityID const& eid) + std::ranges::copy_if(entities, std::back_inserter(result), [&sceneGraph, &entities](EntityID const& eid) { EntityID parentEID = sceneGraph.GetParent(eid)->GetEntityID(); if (parentEID == MAX_EID) return true; - else if(std::ranges::find(selectedEntities, parentEID) == selectedEntities.end()) + if (std::ranges::find(entities, parentEID) == entities.end()) return true; return false; }); - SHCommandManager::PerformCommand(std::make_shared(entitiesToDelete)); + return result; } }//namespace SHADE diff --git a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h index 66b9ca2f..9278a0a3 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h +++ b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h @@ -27,12 +27,13 @@ namespace SHADE void DrawMenuBar() const noexcept; ImRect RecursivelyDrawEntityNode(SHSceneNode* const); void CreateChildEntity(EntityID parentEID) const noexcept; - void ParentSelectedEntities(EntityID parentEID, std::vector const& entities) const noexcept; + void ParentSelectedEntities(EntityID parentEID, std::vector const& entities) noexcept; void SelectRangeOfEntities(EntityID beginEID, EntityID EndEID); void SelectAllEntities(); void CopySelectedEntities(); void PasteEntities(EntityID parentEID = MAX_EID); void DeleteSelectedEntities(); + std::vector CleanUpEIDList(std::vector const& entities); bool skipFrame = false; std::string filter; bool isAnyNodeSelected = false; diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index 79891b82..8619e204 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -454,6 +454,11 @@ namespace SHADE }, [component](AssetID const& id) { + if(SHAssetManager::GetType(id) != AssetType::MESH) + { + SHLOG_WARNING("Attempted to assign non mesh asset to Renderable Mesh property!") + return; + } component->SetMesh(SHResourceManager::LoadOrGet(id)); SHResourceManager::FinaliseChanges(); }, SHDragDrop::DRAG_RESOURCE); @@ -467,6 +472,11 @@ namespace SHADE }, [component](AssetID const& id) { + if (SHAssetManager::GetType(id) != AssetType::MATERIAL) + { + SHLOG_WARNING("Attempted to assign non material asset to Renderable Mesh property!") + return; + } auto gfxSystem = SHSystemManager::GetSystem(); component->SetMaterial(gfxSystem->AddOrGetBaseMaterialInstance(SHResourceManager::LoadOrGet(id))); }, SHDragDrop::DRAG_RESOURCE); From 506b8836fedbcdf7c39d8a91ccf5507b477970e5 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Wed, 16 Nov 2022 17:46:36 +0800 Subject: [PATCH 09/28] Materials now keep track of their modified state and associated MaterialInstances keep track of changes to their base --- .../MiddleEnd/Interface/SHMaterial.cpp | 74 +++++++++---------- .../Graphics/MiddleEnd/Interface/SHMaterial.h | 6 ++ .../MiddleEnd/Interface/SHMaterial.hpp | 4 +- .../Interface/SHMaterialInstance.cpp | 16 +++- .../MiddleEnd/Interface/SHMaterialInstance.h | 2 +- 5 files changed, 56 insertions(+), 46 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.cpp index 528472a7..7ca7c394 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.cpp @@ -12,9 +12,9 @@ namespace SHADE { - /*---------------------------------------------------------------------------------*/ - /* Pipeline Functions */ - /*---------------------------------------------------------------------------------*/ + /*-----------------------------------------------------------------------------------*/ + /* Pipeline Functions */ + /*-----------------------------------------------------------------------------------*/ void SHMaterial::SetPipeline(Handle _pipeline) { // Reassignment, we ignore @@ -24,40 +24,26 @@ namespace SHADE pipeline = _pipeline; // Set up properties based on the pipeline - if (!pipeline) + if (pipeline) { - // Clear memory and all that - propMemory.reset(); - return; - } - - // Allocate memory for properties - const Handle SHADER_INFO = GetShaderBlockInterface(); - propMemorySize = SHADER_INFO ? SHADER_INFO->GetBytesRequired() : 0; - if (propMemorySize <= 0) - { - propMemory.reset(); - } - else - { - propMemory.reset(new char[propMemorySize]); - } - ResetProperties(); - - // Search all material instances for instances that use this base material - // to force a reset of properties - auto gfxSystem = SHSystemManager::GetSystem(); - if (gfxSystem) - { - auto [matInstBegin, matInstEnd] = gfxSystem->GetAllMaterialInstances(); - for (auto iter = matInstBegin; iter != matInstEnd; ++iter) + // Allocate memory for properties + const Handle SHADER_INFO = GetShaderBlockInterface(); + propMemorySize = SHADER_INFO ? SHADER_INFO->GetBytesRequired() : 0; + if (propMemorySize <= 0) { - if (iter->GetBaseMaterial() == GetHandle()) - { - iter->ResetProperties(); - } + propMemory.reset(); + } + else + { + propMemory.reset(new char[propMemorySize]); } } + + // Reset since pipeline changed + ResetProperties(); + + // Mark changed so that we know to update dependent material instances + propertiesChanged = true; } Handle SHMaterial::GetPipeline() const @@ -65,9 +51,9 @@ namespace SHADE return pipeline; } - /*---------------------------------------------------------------------------------*/ - /* Property Functions */ - /*---------------------------------------------------------------------------------*/ + /*-----------------------------------------------------------------------------------*/ + /* Property Functions */ + /*-----------------------------------------------------------------------------------*/ void SHMaterial::ResetProperties() { // Reset all the properties to default values @@ -89,6 +75,8 @@ namespace SHADE break; } } + + propertiesChanged = true; } void SHMaterial::ExportProperties(void* dest) const noexcept @@ -103,9 +91,9 @@ namespace SHADE return SHADER_INFO ? SHADER_INFO->GetBytesRequired() : 0; } - /*---------------------------------------------------------------------------------*/ - /* Helper Functions */ - /*---------------------------------------------------------------------------------*/ + /*-----------------------------------------------------------------------------------*/ + /* Helper Functions */ + /*-----------------------------------------------------------------------------------*/ Handle SHMaterial::GetShaderBlockInterface() const noexcept { return pipeline->GetPipelineLayout()->GetShaderBlockInterface @@ -115,4 +103,12 @@ namespace SHADE vk::ShaderStageFlagBits::eFragment ); } + + /*-----------------------------------------------------------------------------------*/ + /* Query Functions */ + /*-----------------------------------------------------------------------------------*/ + void SHMaterial::ClearChangeFlag() noexcept + { + propertiesChanged = false; + } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.h index 15764ae0..c75692f2 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.h @@ -68,6 +68,10 @@ namespace SHADE /* Query Functions */ /*-----------------------------------------------------------------------------*/ Handle GetShaderBlockInterface() const noexcept; + bool HasPipelineChanged() const noexcept { return pipelineChanged; } + bool HasPropertiesChanged() const noexcept { return propertiesChanged; } + bool HasChanged() const noexcept { return pipelineChanged || propertiesChanged; } + void ClearChangeFlag() noexcept; private: /*-----------------------------------------------------------------------------*/ @@ -76,6 +80,8 @@ namespace SHADE Handle pipeline; std::unique_ptr propMemory; Byte propMemorySize = 0; + bool propertiesChanged = true; + bool pipelineChanged = true; /*-----------------------------------------------------------------------------*/ /* Helper Functions */ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.hpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.hpp index f81cfa5c..b74a69b0 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.hpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.hpp @@ -33,8 +33,7 @@ namespace SHADE } // Get offset and modify the memory directly - T* dataPtr = reinterpret_cast(propMemory.get() + PROP_INFO->offset); - *dataPtr = value; + setPropertyUnsafe(PROP_INFO->offset, value); } template @@ -86,5 +85,6 @@ namespace SHADE void SHMaterial::setPropertyUnsafe(uint32_t memOffset, const T& value) { (*reinterpret_cast(propMemory.get() + memOffset)) = value; + propertiesChanged = true; } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.cpp index 44216163..7526538f 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.cpp @@ -62,12 +62,20 @@ namespace SHADE } // Data was exported so unflag - //dataWasChanged = false; + dataWasChanged = false; } - /*---------------------------------------------------------------------------------*/ - /* Helper Functions */ - /*---------------------------------------------------------------------------------*/ + /*-----------------------------------------------------------------------------------*/ + /* Query Functions */ + /*-----------------------------------------------------------------------------------*/ + bool SHMaterialInstance::HasChanged() const noexcept + { + return dataWasChanged || (baseMaterial && baseMaterial->HasChanged()); + } + + /*-----------------------------------------------------------------------------------*/ + /* Helper Functions */ + /*-----------------------------------------------------------------------------------*/ Handle SHMaterialInstance::getShaderBlockInterface() const noexcept { return baseMaterial->GetPipeline()->GetPipelineLayout()->GetShaderBlockInterface diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.h index d09ed097..57e3dfce 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.h @@ -69,7 +69,7 @@ namespace SHADE /* Getter Functions */ /*-----------------------------------------------------------------------------*/ Handle GetBaseMaterial() const noexcept { return baseMaterial; } - bool HasChanged() const noexcept { return dataWasChanged; } + bool HasChanged() const noexcept; bool IsBlank() const noexcept { return overrideData.empty(); } // No overrides private: From 37e845336b6867007db261448061bf9ce7900ee6 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Wed, 16 Nov 2022 17:46:48 +0800 Subject: [PATCH 10/28] Fix line draws for asset browser --- .../Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp index 889c24cc..66b3c962 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp @@ -109,7 +109,7 @@ namespace SHADE ImVec2 vertLineEnd = vertLineStart; for (auto const& subFolder : subFolders) { - const float horizontalLineSize = 8.0f; + const float horizontalLineSize = (subFolder->subFolders.empty() && subFolder->files.empty()) ? 25.0f : 8.0f; const ImRect childRect = RecursivelyDrawTree(subFolder); const float midPoint = (childRect.Min.y + childRect.Max.y) * 0.5f; drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1); @@ -117,7 +117,7 @@ namespace SHADE } for (auto& file : files) { - const float horizontalLineSize = 25.0f; + const float horizontalLineSize = (file.assetMeta && !file.assetMeta->subAssets.empty()) ? 8.0f : 25.0f; const ImRect childRect = DrawFile(file); const float midPoint = (childRect.Min.y + childRect.Max.y) * 0.5f; drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1); @@ -182,7 +182,10 @@ namespace SHADE return nodeRect; } if(file.assetMeta) - DrawAsset(file.assetMeta, file.ext); + { + const ImRect childRect = DrawAsset(file.assetMeta, file.ext); + return childRect; + } } ImRect SHAssetBrowser::DrawAsset(SHAsset const* const asset, FileExt const& ext /*= ""*/) noexcept From 29b4465dfde454bbcb59068619ba6d5e8c62878a Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Wed, 16 Nov 2022 17:48:15 +0800 Subject: [PATCH 11/28] Split pre-rendering tasks to a PrepareRenderRoutine --- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 54 +++++++++++++------ .../MiddleEnd/Interface/SHGraphicsSystem.h | 14 +++-- 2 files changed, 49 insertions(+), 19 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 3e63eb0d..ff265c49 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -570,13 +570,6 @@ namespace SHADE return; } - // Finalise all batches - for (auto vp : viewports) - for (auto renderer : vp->GetRenderers()) - { - renderer->GetRenderGraph()->FinaliseBatch(renderContext.GetCurrentFrame(), descPool); - } - // Resize auto windowDims = window->GetWindowSize(); if (renderContext.GetResizeAndReset()) @@ -591,6 +584,13 @@ namespace SHADE // #BackEndTest: For for the fence initialized by queue submit renderContext.WaitForFence(); + // Finalise all batches + for (auto vp : viewports) + for (auto renderer : vp->GetRenderers()) + { + renderer->GetRenderGraph()->FinaliseBatch(renderContext.GetCurrentFrame(), descPool); + } + // #BackEndTest: Acquire the next image in the swapchain available renderContext.AcquireNextIamge(); const uint32_t CURR_FRAME_IDX_2 = renderContext.GetCurrentFrame(); @@ -602,8 +602,6 @@ namespace SHADE if (currFrameData.cmdPoolHdls.empty()) throw std::runtime_error("No command pools available!"); currFrameData.cmdPoolHdls[0]->Reset(); - - } /***************************************************************************/ @@ -812,7 +810,7 @@ namespace SHADE void SHGraphicsSystem::BeginRoutine::Execute(double) noexcept { - SHResourceManager::FinaliseChanges(); + // Begin rendering reinterpret_cast(system)->BeginRender(); } @@ -838,8 +836,38 @@ namespace SHADE void SHGraphicsSystem::EndRoutine::Execute(double) noexcept { reinterpret_cast(system)->EndRender(); + + // Reset all material isDirty + auto gfxSystem = reinterpret_cast(system); + auto [matBegin, matEnd] = gfxSystem->resourceManager.GetDenseAccess(); + for (auto iter = matBegin; iter != matEnd; ++iter) + { + iter->ClearChangeFlag(); + } } - + + SHGraphicsSystem::PrepareRenderRoutine::PrepareRenderRoutine() + : SHSystemRoutine("Graphics System Pre-Render", true) + {} + + void SHGraphicsSystem::PrepareRenderRoutine::Execute(double) noexcept + { + // Finish up, loading, unloading any resources + SHResourceManager::FinaliseChanges(); + + // Clean up and update all materials + auto gfxSystem = reinterpret_cast(system); + auto [matInstBegin, matInstEnd] = gfxSystem->resourceManager.GetDenseAccess(); + for (auto iter = matInstBegin; iter != matInstEnd; ++iter) + { + auto baseMat = iter->GetBaseMaterial(); + if (baseMat && baseMat->HasPipelineChanged()) + { + iter->ResetProperties(); + } + } + } + /*-----------------------------------------------------------------------------------*/ /* System Routine Functions - BatcherDispatcherRoutine */ /*-----------------------------------------------------------------------------------*/ @@ -858,8 +886,6 @@ namespace SHADE if (!renderable.HasChanged()) continue; - // TODO: Need to account for - // Remove from the SuperBatch it is previously in (prevMat if mat has changed) Handle prevMaterial = renderable.HasMaterialChanged() ? renderable.GetPrevMaterial() : renderable.GetMaterial(); if (prevMaterial) @@ -879,8 +905,6 @@ namespace SHADE // Unset change flag renderable.ResetChangedFlag(); } - - // TODO: Also reset all material instances isDrity } #pragma endregion ROUTINES diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index 569477d8..2a186041 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -95,25 +95,31 @@ namespace SHADE class SH_API BeginRoutine final : public SHSystemRoutine { public: - BeginRoutine(); + BeginRoutine(); virtual void Execute(double dt) noexcept override final; }; class SH_API RenderRoutine final : public SHSystemRoutine { public: - RenderRoutine(); + RenderRoutine(); virtual void Execute(double dt) noexcept override final; }; class SH_API EndRoutine final : public SHSystemRoutine { public: - EndRoutine(); + EndRoutine(); + virtual void Execute(double dt) noexcept override final; + }; + class SH_API PrepareRenderRoutine final : public SHSystemRoutine + { + public: + PrepareRenderRoutine(); virtual void Execute(double dt) noexcept override final; }; class SH_API BatcherDispatcherRoutine final : public SHSystemRoutine { public: - BatcherDispatcherRoutine(); + BatcherDispatcherRoutine(); virtual void Execute(double dt) noexcept override final; }; From f0c09817cedbb5f426a4acc51738da5b5d950cf9 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Wed, 16 Nov 2022 17:48:51 +0800 Subject: [PATCH 12/28] EnsureBufferAndCopy utility functions now avoid resizes if new size is smaller or equal --- .../src/Application/SBApplication.cpp | 1 + SHADE_Engine/src/Graphics/SHVkUtil.cpp | 24 +++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index 1095f965..fdfcc08b 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -115,6 +115,7 @@ namespace Sandbox SHSystemManager::RegisterRoutine(); SHSystemManager::RegisterRoutine(); + SHSystemManager::RegisterRoutine(); SHSystemManager::RegisterRoutine(); SHSystemManager::RegisterRoutine(); diff --git a/SHADE_Engine/src/Graphics/SHVkUtil.cpp b/SHADE_Engine/src/Graphics/SHVkUtil.cpp index a9ac543f..3a405e0d 100644 --- a/SHADE_Engine/src/Graphics/SHVkUtil.cpp +++ b/SHADE_Engine/src/Graphics/SHVkUtil.cpp @@ -86,8 +86,16 @@ namespace SHADE { if (bufferHandle) { - // Resize - bufferHandle->ResizeReplace(size, src, size); + // Resize if we need to resize + if (bufferHandle->GetSizeStored() < size) + { + bufferHandle->ResizeReplace(size, src, size); + } + // Otherwise just copy the data over + else + { + bufferHandle->MapWriteUnmap(src, size, 0, 0); + } } else { @@ -113,8 +121,16 @@ namespace SHADE { if (bufferHandle) { - // Resize - bufferHandle->ResizeReplace(size, src, size); // TODO: Set to host visible method? + // Resize if we need to resize + if (bufferHandle->GetSizeStored() < size) + { + bufferHandle->ResizeReplace(size, src, size); + } + // Otherwise just copy the data over + else + { + bufferHandle->MapWriteUnmap(src, size, 0, 0); + } } else { From c5bca4111bb2d8ebfba97c0ac3cb59603e259f1b Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Wed, 16 Nov 2022 19:23:26 +0800 Subject: [PATCH 13/28] Fixed validation error caused by deleting empty batches --- SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h | 2 +- .../src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h index 498e807f..dd4d33fd 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h @@ -122,7 +122,7 @@ namespace SHADE std::unique_ptr matPropsData; Byte matPropsDataSize = 0; Byte singleMatPropAlignedSize = 0; - Byte singleMatPropSize = 0; + Byte singleMatPropSize = 0; bool isCPUBuffersDirty = true; // GPU Buffers TripleBuffer drawDataBuffer; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp index b827652e..6760d937 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp @@ -69,9 +69,9 @@ namespace SHADE batch->Remove(renderable); - // If batch is empty, remove batch - if (batch->IsEmpty()) - batches.erase(batch); + // TODO: If the pipeline is unloaded, we remove the batch + /*if (batch->IsEmpty() && !batch->GetPipeline()) + batches.erase(batch);*/ } void SHSuperBatch::Clear() noexcept From fe91f58d2809162d8159e9daabc8f016736848bb Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Wed, 16 Nov 2022 19:25:17 +0800 Subject: [PATCH 14/28] Fixed material inspector saving not saving the correct texture ID into the runtime material --- .../MaterialInspector/SHMaterialInspector.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/MaterialInspector/SHMaterialInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/MaterialInspector/SHMaterialInspector.cpp index 2f87a97c..3ffed8e3 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/MaterialInspector/SHMaterialInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/MaterialInspector/SHMaterialInspector.cpp @@ -78,6 +78,7 @@ namespace SHADE ImGui::BeginDisabled(!isDirty); if(ImGui::Button(std::format("{} Save", ICON_MD_SAVE).data())) { + auto gfxSystem = SHSystemManager::GetSystem(); // Replace Material if it's been instantiated auto matHandle = SHResourceManager::Get(currentViewedMaterial); if (matHandle) @@ -85,7 +86,6 @@ namespace SHADE // - Get Shader Modules auto vertShader = SHResourceManager::LoadOrGet(currentMatSpec->vertexShader); auto fragShader = SHResourceManager::LoadOrGet(currentMatSpec->fragShader); - auto gfxSystem = SHSystemManager::GetSystem(); if (vertShader && fragShader && gfxSystem) { // - Retrieve pipeline from pipeline library @@ -121,7 +121,20 @@ namespace SHADE currentMaterial->SetProperty(VARIABLE->offset, PROP_NODE.as()); break; case SHADE::SHShaderBlockInterface::Variable::Type::INT: - currentMaterial->SetProperty(VARIABLE->offset, PROP_NODE.as()); + { + Handle texture = SHResourceManager::LoadOrGet(PROP_NODE.as()); + // HACK: Need to split this out to a separate pass before loading the materials and subsequently, the scenes + gfxSystem->BuildTextures(); + if (texture) + { + matHandle->SetProperty(VARIABLE->offset, texture->TextureArrayIndex); + } + else + { + SHLOG_WARNING("[] Attempted to load invalid texture! Setting to 0."); + matHandle->SetProperty(VARIABLE->offset, 0); + } + } break; case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR2: currentMaterial->SetProperty(VARIABLE->offset, PROP_NODE.as()); From 8869b42db2d93e6df37786a8582c1c6ea9c035d8 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Wed, 16 Nov 2022 21:00:27 +0800 Subject: [PATCH 15/28] Fixed memory corruption in SHSubpass --- SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp | 6 +++--- SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp | 6 +++--- SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h | 2 +- SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index d9c7f17a..e798bfe7 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -129,11 +129,11 @@ namespace SHADE for (auto& predResource : prereq->attResources) { // if a predecessor's resource is used by this node, we want to copy the final layout from the pred to the initial of this node - if (uint64_t resourceID = predResource.GetId().Raw; node->resourceAttachmentMapping.contains(resourceID)) + if (uint64_t resourceID = predResource.GetId().Raw; node->resourceAttachmentMapping->contains(resourceID)) { // Get the resource's attachment index in BOTH the predecessor and the current node - uint32_t prereqResourceAttIndex = prereq->resourceAttachmentMapping[resourceID]; - uint32_t resourceAttIndex = node->resourceAttachmentMapping[resourceID]; + uint32_t prereqResourceAttIndex = prereq->resourceAttachmentMapping->at(resourceID); + uint32_t resourceAttIndex = node->resourceAttachmentMapping->at(resourceID); // Use the resource attachment index to get the attachment description in the renderpass auto& attDesc = node->attachmentDescriptions[resourceAttIndex]; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp index b3b5b58b..3f6be1d9 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp @@ -124,7 +124,7 @@ namespace SHADE , framebuffers{} , prereqNodes{ std::move(predecessors) } , attachmentDescriptions{} - , resourceAttachmentMapping{} + , resourceAttachmentMapping { new std::unordered_map } , attResources{ } , subpasses{} , executed{ false } @@ -163,7 +163,7 @@ namespace SHADE if (attResources[i]->resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) containsSwapchainImage = true; - resourceAttachmentMapping.try_emplace(attResources[i].GetId().Raw, i); + resourceAttachmentMapping->try_emplace(attResources[i].GetId().Raw, i); } if (!containsSwapchainImage) @@ -254,7 +254,7 @@ namespace SHADE ( subpassName, graphStorage, GetHandle(), static_cast(subpasses.size()), - &resourceAttachmentMapping + resourceAttachmentMapping.get() ) ); subpassIndexing.try_emplace(subpassName, static_cast(subpasses.size()) - 1u); diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h index 4fdac45c..299578f2 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h @@ -60,7 +60,7 @@ namespace SHADE std::vector spDeps; //! For indexing resources fast - std::unordered_map resourceAttachmentMapping; + std::unique_ptr> resourceAttachmentMapping; //! For indexing subpasses std::map subpassIndexing; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp index 2ed84d92..dfa5977b 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp @@ -97,7 +97,7 @@ namespace SHADE colorReferences = std::move(rhs.colorReferences); depthReferences = std::move(rhs.depthReferences); inputReferences = std::move(rhs.inputReferences); - resourceAttachmentMapping = rhs.resourceAttachmentMapping; + resourceAttachmentMapping = std::move(rhs.resourceAttachmentMapping); descriptorSetLayout = rhs.descriptorSetLayout; exteriorDrawCalls = std::move(rhs.exteriorDrawCalls); graphStorage = rhs.graphStorage; From 19bc90845ff60f7aecd0442e7621532531faaa06 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Wed, 16 Nov 2022 21:01:51 +0800 Subject: [PATCH 16/28] Added additional checks for SetProperty() of Material and MaterialInstance --- .../src/Graphics/MiddleEnd/Interface/SHMaterial.hpp | 5 +++++ .../src/Graphics/MiddleEnd/Interface/SHMaterialInstance.hpp | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.hpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.hpp index b74a69b0..880fba69 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.hpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.hpp @@ -84,6 +84,11 @@ namespace SHADE template void SHMaterial::setPropertyUnsafe(uint32_t memOffset, const T& value) { + // Size check + if (memOffset + sizeof(T) > propMemorySize) + { + throw std::runtime_error("Attempted to write to out of bounds MaterialInstance properties memory"); + } (*reinterpret_cast(propMemory.get() + memOffset)) = value; propertiesChanged = true; } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.hpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.hpp index 3805cc72..7bd1c106 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.hpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.hpp @@ -59,6 +59,12 @@ namespace SHADE od.StoredDataOffset = lastInsertedData.StoredDataOffset + lastInsertedData.DataSize; } + // Size check + if (od.StoredDataOffset + sizeof(T) > dataStoreSize) + { + throw std::runtime_error("Attempted to write to out of bounds MaterialInstance properties memory"); + } + // Save the override data information overrideData.emplace_back(std::move(od)); existingOverride = overrideData.end() - 1; From b129a6868079d86afb4cb9d4189397aab6dced04 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Wed, 16 Nov 2022 23:19:25 +0800 Subject: [PATCH 17/28] Disabled setting of shader for now as it is buggy --- .../EditorWindow/MaterialInspector/SHMaterialInspector.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SHADE_Engine/src/Editor/EditorWindow/MaterialInspector/SHMaterialInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/MaterialInspector/SHMaterialInspector.cpp index 3ffed8e3..88de7b73 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/MaterialInspector/SHMaterialInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/MaterialInspector/SHMaterialInspector.cpp @@ -174,6 +174,7 @@ namespace SHADE bool shaderChanged = false; const auto* SHADER_INFO = SHAssetManager::GetData(currentMatSpec->fragShader); const std::string SHADER_NAME = SHADER_INFO ? SHADER_INFO->name : "Unknown Shader"; + ImGui::BeginDisabled(); isDirty |= SHEditorWidgets::DragDropReadOnlyField ( "Fragment Shader", SHADER_NAME.data(), @@ -181,6 +182,7 @@ namespace SHADE [this](const AssetID& id) { currentMatSpec->fragShader = id; }, SHDragDrop::DRAG_RESOURCE ); + ImGui::EndDisabled(); // Load the shader to access it's data auto fragShader = SHResourceManager::LoadOrGet(currentMatSpec->fragShader); From 39a8ca131f783a0634a7e9ac7cbced2aa59f8864 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 17 Nov 2022 00:11:55 +0800 Subject: [PATCH 18/28] Fixed Collision & Trigger Messages not being cleared on deactivating objects --- .../src/Physics/Collision/SHCollisionListener.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/SHADE_Engine/src/Physics/Collision/SHCollisionListener.cpp b/SHADE_Engine/src/Physics/Collision/SHCollisionListener.cpp index e8379b09..f16303f4 100644 --- a/SHADE_Engine/src/Physics/Collision/SHCollisionListener.cpp +++ b/SHADE_Engine/src/Physics/Collision/SHCollisionListener.cpp @@ -16,6 +16,7 @@ // Project Headers #include "Physics/PhysicsObject/SHPhysicsObject.h" #include "Physics/System/SHPhysicsSystem.h" +#include "Scene/SHSceneManager.h" /*-------------------------------------------------------------------------------------*/ /* Local Helper Functions */ @@ -80,10 +81,15 @@ namespace SHADE { for (auto eventIter = container.begin(); eventIter != container.end();) { - const bool CLEAR_EVENT = eventIter->GetCollisionState() == SHCollisionInfo::State::EXIT - || eventIter->GetCollisionState() == SHCollisionInfo::State::INVALID; + const SHCollisionInfo& C_INFO = *eventIter; - if (CLEAR_EVENT) + const bool CLEAR_EVENT = C_INFO.GetCollisionState() == SHCollisionInfo::State::EXIT + || C_INFO.GetCollisionState() == SHCollisionInfo::State::INVALID; + + const bool INACTIVE_OBJECT = !SHSceneManager::CheckNodeAndComponentsActive(C_INFO.GetEntityA()) + || !SHSceneManager::CheckNodeAndComponentsActive(C_INFO.GetEntityB()); + + if (CLEAR_EVENT || INACTIVE_OBJECT) eventIter = container.erase(eventIter); else ++eventIter; From 8f9fedff4151e16f5540886e890e82559dc0c1ac Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 17 Nov 2022 01:39:05 +0800 Subject: [PATCH 19/28] Added sleeping debug info to Rigidbody Inspector --- .../src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index 79891b82..895237ad 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -290,6 +290,7 @@ namespace SHADE { SHEditorWidgets::DragVec3("Force", { "X", "Y", "Z" }, [component] {return component->GetForce(); }, [](SHVec3 const& value) {}, false, "Force", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly); SHEditorWidgets::DragVec3("Torque", { "X", "Y", "Z" }, [component] {return component->GetTorque(); }, [](SHVec3 const& value) {}, false, "Torque", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly); + SHEditorWidgets::CheckBox("Is Asleep", [component] {return component->GetIsSleeping(); }, [](bool value) {}, "If the Rigid Body is asleep"); } } From 72888945079268a1b4992b6fbb4647c8a43f0a8a Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 17 Nov 2022 10:42:45 +0800 Subject: [PATCH 20/28] Fixed bug where adding colliders would fail to maintain previous collider sizes --- .../src/Physics/Interface/SHCollisionShape.cpp | 6 ++++++ .../src/Physics/PhysicsObject/SHPhysicsObject.cpp | 15 +++++++++++++-- SHADE_Engine/src/Physics/SHPhysicsWorld.h | 4 ++-- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/SHADE_Engine/src/Physics/Interface/SHCollisionShape.cpp b/SHADE_Engine/src/Physics/Interface/SHCollisionShape.cpp index e63895d5..14743845 100644 --- a/SHADE_Engine/src/Physics/Interface/SHCollisionShape.cpp +++ b/SHADE_Engine/src/Physics/Interface/SHCollisionShape.cpp @@ -304,6 +304,9 @@ namespace SHADE const auto* RHS_BOX = reinterpret_cast(rhs); shape = new SHBox{ positionOffset, RHS_BOX->GetWorldExtents() }; + auto* lhsBox = reinterpret_cast(shape); + lhsBox->SetRelativeExtents(RHS_BOX->GetRelativeExtents()); + break; } case Type::SPHERE: @@ -311,6 +314,9 @@ namespace SHADE const auto* RHS_SPHERE = reinterpret_cast(rhs); shape = new SHSphere{ positionOffset, RHS_SPHERE->GetWorldRadius() }; + auto* lhsSphere = reinterpret_cast(shape); + lhsSphere->SetRelativeRadius(RHS_SPHERE->GetRelativeRadius()); + break; } default: break; diff --git a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp index eb94aecb..67ace078 100644 --- a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp @@ -109,14 +109,25 @@ namespace SHADE { // TODO(Diren): Add more collider shapes - case SHCollisionShape::Type::BOX: addBoxShape(collisionShape); break; - case SHCollisionShape::Type::SPHERE: addSphereShape(collisionShape); break; + case SHCollisionShape::Type::BOX: + { + addBoxShape(collisionShape); + break; + } + + case SHCollisionShape::Type::SPHERE: + { + addSphereShape(collisionShape); + break; + } default: break; } rp3dBody->updateLocalCenterOfMassFromColliders(); rp3dBody->updateLocalInertiaTensorFromColliders(); + SyncColliders(*colliderComponent); + return index; } diff --git a/SHADE_Engine/src/Physics/SHPhysicsWorld.h b/SHADE_Engine/src/Physics/SHPhysicsWorld.h index 091ae062..c5152c44 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsWorld.h +++ b/SHADE_Engine/src/Physics/SHPhysicsWorld.h @@ -38,8 +38,8 @@ namespace SHADE /*-------------------------------------------------------------------------------*/ SHVec3 gravity = SHVec3{ 0.0f, -9.81f, 0.0f }; - uint16_t numVelocitySolverIterations = 15; - uint16_t numPositionSolverIterations = 8; + uint16_t numVelocitySolverIterations = 10; + uint16_t numPositionSolverIterations = 5; bool sleepingEnabled = true; }; From 18218443ec857cd8f275802021466c459f13c98b Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 17 Nov 2022 12:20:28 +0800 Subject: [PATCH 21/28] Fixed a bug --- SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp index 67ace078..67172d8e 100644 --- a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp @@ -126,8 +126,6 @@ namespace SHADE rp3dBody->updateLocalCenterOfMassFromColliders(); rp3dBody->updateLocalInertiaTensorFromColliders(); - SyncColliders(*colliderComponent); - return index; } From 360c55fa2bb80e43b002e43f40353f72b7aba413 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 17 Nov 2022 12:27:00 +0800 Subject: [PATCH 22/28] Disabled automass on rigid bodies --- .../Interface/SHRigidBodyComponent.cpp | 25 +++++++++---------- .../Physics/Interface/SHRigidBodyComponent.h | 4 +-- .../Physics/PhysicsObject/SHPhysicsObject.cpp | 16 ++++++------ 3 files changed, 22 insertions(+), 23 deletions(-) diff --git a/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.cpp b/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.cpp index e892a5aa..28b6f842 100644 --- a/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.cpp +++ b/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.cpp @@ -113,11 +113,11 @@ namespace SHADE return flags & (1U << FLAG_POS); } - bool SHRigidBodyComponent::GetAutoMass() const noexcept - { - static constexpr int FLAG_POS = 9; - return flags & (1U << FLAG_POS); - } + //bool SHRigidBodyComponent::GetAutoMass() const noexcept + //{ + // static constexpr int FLAG_POS = 9; + // return flags & (1U << FLAG_POS); + //} float SHRigidBodyComponent::GetMass() const noexcept { @@ -314,14 +314,13 @@ namespace SHADE allowInterpolation ? flags |= 1U << FLAG_POS : flags &= ~(1U << FLAG_POS); } - void SHRigidBodyComponent::SetAutoMass(bool autoMass) noexcept - { - static constexpr int FLAG_POS = 9; - autoMass ? flags |= 1U << FLAG_POS : flags &= ~(1U << FLAG_POS); - - dirtyFlags |= 1U << FLAG_POS; - } + //void SHRigidBodyComponent::SetAutoMass(bool autoMass) noexcept + //{ + // static constexpr int FLAG_POS = 9; + // autoMass ? flags |= 1U << FLAG_POS : flags &= ~(1U << FLAG_POS); + // dirtyFlags |= 1U << FLAG_POS; + //} void SHRigidBodyComponent::SetMass(float newMass) noexcept { @@ -496,7 +495,7 @@ RTTR_REGISTRATION .property("Use Gravity" , &SHRigidBodyComponent::IsGravityEnabled , &SHRigidBodyComponent::SetGravityEnabled ) .property("Interpolate" , &SHRigidBodyComponent::IsInterpolating , &SHRigidBodyComponent::SetInterpolate ) .property("Sleeping Enabled" , &SHRigidBodyComponent::IsAllowedToSleep , &SHRigidBodyComponent::SetIsAllowedToSleep) - .property("Auto Mass" , &SHRigidBodyComponent::GetAutoMass , &SHRigidBodyComponent::SetAutoMass ) + //.property("Auto Mass" , &SHRigidBodyComponent::GetAutoMass , &SHRigidBodyComponent::SetAutoMass ) .property("Freeze Position X" , &SHRigidBodyComponent::GetFreezePositionX , &SHRigidBodyComponent::SetFreezePositionX ) .property("Freeze Position Y" , &SHRigidBodyComponent::GetFreezePositionY , &SHRigidBodyComponent::SetFreezePositionY ) .property("Freeze Position Z" , &SHRigidBodyComponent::GetFreezePositionZ , &SHRigidBodyComponent::SetFreezePositionZ ) diff --git a/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.h b/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.h index 658c60e1..d5204d94 100644 --- a/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.h +++ b/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.h @@ -82,7 +82,7 @@ namespace SHADE [[nodiscard]] bool GetFreezeRotationY () const noexcept; [[nodiscard]] bool GetFreezeRotationZ () const noexcept; - [[nodiscard]] bool GetAutoMass () const noexcept; + //[[nodiscard]] bool GetAutoMass () const noexcept; [[nodiscard]] float GetMass () const noexcept; [[nodiscard]] float GetDrag () const noexcept; @@ -112,7 +112,7 @@ namespace SHADE void SetFreezeRotationY (bool freezeRotationY) noexcept; void SetFreezeRotationZ (bool freezeRotationZ) noexcept; void SetInterpolate (bool allowInterpolation) noexcept; - void SetAutoMass (bool autoMass) noexcept; + //void SetAutoMass (bool autoMass) noexcept; void SetMass (float newMass) noexcept; void SetDrag (float newDrag) noexcept; diff --git a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp index 67172d8e..0a0ff201 100644 --- a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp @@ -254,17 +254,17 @@ namespace SHADE } case 9: // Mass { - if (component.GetAutoMass()) - { - rp3dBody->updateMassPropertiesFromColliders(); - component.mass = rp3dBody->getMass(); - } - else - { + //if (component.GetAutoMass()) + //{ + // rp3dBody->updateMassPropertiesFromColliders(); + // component.mass = rp3dBody->getMass(); + //} + //else + //{ rp3dBody->setMass(component.mass); rp3dBody->updateLocalCenterOfMassFromColliders(); rp3dBody->updateLocalInertiaTensorFromColliders(); - } + //} break; } From b3fbfce56f2407a136ef77ec582eb947a70ef1fd Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 17 Nov 2022 12:58:01 +0800 Subject: [PATCH 23/28] FIxed debug draw for offset colliders --- SHADE_Engine/src/Math/Geometry/SHBox.cpp | 2 +- SHADE_Engine/src/Math/Geometry/SHBox.h | 14 ++--- .../System/SHPhysicsDebugDrawSystem.cpp | 57 ++++++++++++------- .../Physics/System/SHPhysicsDebugDrawSystem.h | 25 ++++++-- 4 files changed, 62 insertions(+), 36 deletions(-) diff --git a/SHADE_Engine/src/Math/Geometry/SHBox.cpp b/SHADE_Engine/src/Math/Geometry/SHBox.cpp index cf094a9d..a52cf0d2 100644 --- a/SHADE_Engine/src/Math/Geometry/SHBox.cpp +++ b/SHADE_Engine/src/Math/Geometry/SHBox.cpp @@ -1,5 +1,5 @@ /**************************************************************************************** - * \file SHBoundingBox.cpp + * \file SHBox.cpp * \author Diren D Bharwani, diren.dbharwani, 390002520 * \brief Implementation for a 3-Dimensional Axis Aligned Bounding Box * diff --git a/SHADE_Engine/src/Math/Geometry/SHBox.h b/SHADE_Engine/src/Math/Geometry/SHBox.h index 0ea950ab..19c80bd2 100644 --- a/SHADE_Engine/src/Math/Geometry/SHBox.h +++ b/SHADE_Engine/src/Math/Geometry/SHBox.h @@ -1,5 +1,5 @@ /**************************************************************************************** - * \file SHBoundingBox.h + * \file SHBox.h * \author Diren D Bharwani, diren.dbharwani, 390002520 * \brief Interface for a 3-Dimensional Axis Aligned Bounding Box * @@ -79,17 +79,17 @@ namespace SHADE [[nodiscard]] bool TestPoint (const SHVec3& point) noexcept override; [[nodiscard]] bool Raycast (const SHRay& ray, float& distance) noexcept override; - [[nodiscard]] bool Contains (const SHBox& rhs) const noexcept; - [[nodiscard]] float Volume () const noexcept; - [[nodiscard]] float SurfaceArea () const noexcept; + [[nodiscard]] bool Contains (const SHBox& rhs) const noexcept; + [[nodiscard]] float Volume () const noexcept; + [[nodiscard]] float SurfaceArea () const noexcept; /*---------------------------------------------------------------------------------*/ /* Static Function Members */ /*---------------------------------------------------------------------------------*/ - [[nodiscard]] static SHBox Combine (const SHBox& lhs, const SHBox& rhs) noexcept; - [[nodiscard]] static bool Intersect (const SHBox& lhs, const SHBox& rhs) noexcept; - [[nodiscard]] static SHBox BuildFromBoxes (const SHBox* boxes, size_t numBoxes) noexcept; + [[nodiscard]] static SHBox Combine (const SHBox& lhs, const SHBox& rhs) noexcept; + [[nodiscard]] static bool Intersect (const SHBox& lhs, const SHBox& rhs) noexcept; + [[nodiscard]] static SHBox BuildFromBoxes (const SHBox* boxes, size_t numBoxes) noexcept; [[nodiscard]] static SHBox BuildFromVertices (const SHVec3* vertices, size_t numVertices, size_t stride = 0) noexcept; private: diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.cpp index 44875289..7ccfb225 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.cpp +++ b/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.cpp @@ -24,7 +24,7 @@ namespace SHADE /* Static Data Member Definitions */ /*-----------------------------------------------------------------------------------*/ - const SHPhysicsDebugDrawSystem::DebugDrawFunction SHPhysicsDebugDrawSystem::drawFunctions[SHPhysicsDebugDrawSystem::NUM_FLAGS] = + const SHPhysicsDebugDrawSystem::DebugDrawFunction SHPhysicsDebugDrawSystem::drawFunctions[NUM_FLAGS] = { SHPhysicsDebugDrawSystem::drawColliders , SHPhysicsDebugDrawSystem::drawColliderAABBs @@ -33,6 +33,8 @@ namespace SHADE , SHPhysicsDebugDrawSystem::drawContactNormals }; + SHVec3 SHPhysicsDebugDrawSystem::boxVertices[NUM_BOX_VERTICES]; + /*-----------------------------------------------------------------------------------*/ /* Constructors & Destructor Definitions */ /*-----------------------------------------------------------------------------------*/ @@ -42,7 +44,7 @@ namespace SHADE , physicsSystem { nullptr } , rp3dDebugRenderer { nullptr } { - debugColours[SHUtilities::ConvertEnum(DebugDrawFlags::COLLIDER)] = + debugColours[SHUtilities::ConvertEnum(DebugDrawFlags::COLLIDER)] = SHColour::GREEN; debugColours[SHUtilities::ConvertEnum(DebugDrawFlags::COLLIDER_AABB)] = SHColour::YELLOW; debugColours[SHUtilities::ConvertEnum(DebugDrawFlags::BROAD_PHASE_AABB)] = SHColour::CYAN; debugColours[SHUtilities::ConvertEnum(DebugDrawFlags::CONTACT_POINTS)] = SHColour::RED; @@ -95,6 +97,9 @@ namespace SHADE SHASSERT(physicsSystem == nullptr, "Non-existent physics system attached to the physics debug draw system!") physicsSystem = SHSystemManager::GetSystem(); + + // Generate shapes + generateBox(); } void SHPhysicsDebugDrawSystem::Exit() @@ -159,21 +164,20 @@ namespace SHADE } + void SHPhysicsDebugDrawSystem::generateBox() noexcept + { + boxVertices[0] = { 0.5f, 0.5f, -0.5f }; // TOP_RIGHT_BACK + boxVertices[1] = { -0.5f, 0.5f, -0.5f }; // TOP_LEFT_BACK + boxVertices[2] = { 0.5f, -0.5f, -0.5f }; // BTM_RIGHT_BACK + boxVertices[3] = { -0.5f, -0.5f, -0.5f }; // BTM_LEFT_BACK + boxVertices[4] = { 0.5f, 0.5f, 0.5f }; // TOP_RIGHT_FRONT + boxVertices[5] = { -0.5f, 0.5f, 0.5f }; // TOP_LEFT_FRONT + boxVertices[6] = { 0.5f, -0.5f, 0.5f }; // BTM_RIGHT_FRONT + boxVertices[7] = { -0.5f, -0.5f, 0.5f }; // BTM_LEFT_FRONT + } + void SHPhysicsDebugDrawSystem::debugDrawBox(const SHColliderComponent& colliderComponent, const SHCollisionShape& collisionShape) noexcept { - static constexpr uint32_t NUM_BOX_VERTICES = 8; - static const SHVec3 boxVertices[NUM_BOX_VERTICES] - { - { 0.5f, 0.5f, -0.5f } // TOP_RIGHT_BACK - , { -0.5f, 0.5f, -0.5f } // TOP_LEFT_BACK - , { 0.5f, -0.5f, -0.5f } // BTM_RIGHT_BACK - , { -0.5f, -0.5f, -0.5f } // BTM_LEFT_BACK - , { 0.5f, 0.5f, 0.5f } // TOP_RIGHT_FRONT - , { -0.5f, 0.5f, 0.5f } // TOP_LEFT_FRONT - , { 0.5f, -0.5f, 0.5f } // BTM_RIGHT_FRONT - , { -0.5f, -0.5f, 0.5f } // BTM_LEFT_FRONT - }; - auto* debugDrawSystem = SHSystemManager::GetSystem(); if (debugDrawSystem == nullptr) { @@ -184,10 +188,16 @@ namespace SHADE auto* BOX = reinterpret_cast(collisionShape.GetShape()); // Calculate final position & orientation - const SHVec3 FINAL_POS = colliderComponent.GetPosition() + collisionShape.GetPositionOffset(); - const SHQuaternion FINAL_ROT = colliderComponent.GetOrientation() * SHQuaternion::FromEuler(collisionShape.GetRotationOffset()); + const SHVec3 COLLIDER_POS = colliderComponent.GetPosition(); + const SHVec3 BOX_POS = collisionShape.GetPositionOffset(); + const SHQuaternion COLLIDER_ROT = colliderComponent.GetOrientation(); + const SHQuaternion BOX_ROT = SHQuaternion::FromEuler(collisionShape.GetRotationOffset()); - const SHMatrix BOX_TRS = SHMatrix::Scale(BOX->GetWorldExtents() * 2.0f) * SHMatrix::Rotate(FINAL_ROT) * SHMatrix::Translate(FINAL_POS); + + const SHMatrix COLLIDER_TR = SHMatrix::Rotate(COLLIDER_ROT) * SHMatrix::Translate(COLLIDER_POS); + const SHMatrix BOX_TRS = SHMatrix::Scale(BOX->GetWorldExtents() * 2.0f) * SHMatrix::Rotate(BOX_ROT) * SHMatrix::Translate(BOX_POS); + + const SHMatrix FINAL_TRS = BOX_TRS * COLLIDER_TR; const SHColour COLLIDER_COLOUR = collisionShape.IsTrigger() ? SHColour::PURPLE : SHColour::GREEN; @@ -197,8 +207,8 @@ namespace SHADE const uint32_t IDX1 = i; const uint32_t IDX2 = i + NUM_BOX_VERTICES / 2; - transformedVertices[IDX1] = SHVec3::Transform(boxVertices[IDX1], BOX_TRS); - transformedVertices[IDX2] = SHVec3::Transform(boxVertices[IDX2], BOX_TRS); + transformedVertices[IDX1] = SHVec3::Transform(boxVertices[IDX1], FINAL_TRS); + transformedVertices[IDX2] = SHVec3::Transform(boxVertices[IDX2], FINAL_TRS); // Draw 4 line to connect the quads debugDrawSystem->DrawLine(COLLIDER_COLOUR, transformedVertices[IDX1], transformedVertices[IDX2]); @@ -207,6 +217,7 @@ namespace SHADE // A, B, C, D std::array backQuad { transformedVertices[0], transformedVertices[1], transformedVertices[3], transformedVertices[2] }; debugDrawSystem->DrawPoly(COLLIDER_COLOUR, backQuad.begin(), backQuad.end()); + // E, F, G, H std::array frontQuad { transformedVertices[4], transformedVertices[5], transformedVertices[7], transformedVertices[6] }; debugDrawSystem->DrawPoly(COLLIDER_COLOUR, frontQuad.begin(), frontQuad.end()); @@ -226,8 +237,10 @@ namespace SHADE const SHColour COLLIDER_COLOUR = collisionShape.IsTrigger() ? SHColour::PURPLE : SHColour::GREEN; // Calculate final position & orientation - const SHVec3 FINAL_POS = colliderComponent.GetPosition() + collisionShape.GetPositionOffset(); - debugDrawSystem->DrawSphere(COLLIDER_COLOUR, FINAL_POS, SPHERE->GetWorldRadius()); + const SHQuaternion FINAL_ROT = colliderComponent.GetOrientation() * SHQuaternion::FromEuler(collisionShape.GetRotationOffset()); + const SHMatrix TR = SHMatrix::Rotate(FINAL_ROT) * SHMatrix::Translate(colliderComponent.GetPosition()); + + debugDrawSystem->DrawSphere(COLLIDER_COLOUR, SHVec3::Transform(collisionShape.GetPositionOffset(), TR), SPHERE->GetWorldRadius()); } } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.h b/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.h index 390e3d69..149ed6c1 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.h +++ b/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.h @@ -97,25 +97,38 @@ namespace SHADE /* Data Members */ /*---------------------------------------------------------------------------------*/ - static constexpr int NUM_FLAGS = SHUtilities::ConvertEnum(DebugDrawFlags::NUM_FLAGS); - + static constexpr int NUM_FLAGS = SHUtilities::ConvertEnum(DebugDrawFlags::NUM_FLAGS); static const DebugDrawFunction drawFunctions[NUM_FLAGS]; - uint8_t debugDrawFlags; - SHPhysicsSystem* physicsSystem; - rp3d::DebugRenderer* rp3dDebugRenderer; - SHColour debugColours[NUM_FLAGS]; + // SHAPES INFO + + static constexpr size_t NUM_BOX_VERTICES = 8; + static SHVec3 boxVertices[NUM_BOX_VERTICES]; + + + uint8_t debugDrawFlags; + SHPhysicsSystem* physicsSystem; + rp3d::DebugRenderer* rp3dDebugRenderer; + SHColour debugColours[NUM_FLAGS]; /*---------------------------------------------------------------------------------*/ /* Function Members */ /*---------------------------------------------------------------------------------*/ + // Generic Draw Functions + static void drawColliders (rp3d::DebugRenderer* debugRenderer) noexcept; static void drawColliderAABBs (rp3d::DebugRenderer* debugRenderer) noexcept; static void drawBroadPhaseAABBs (rp3d::DebugRenderer* debugRenderer) noexcept; static void drawContactPoints (rp3d::DebugRenderer* debugRenderer) noexcept; static void drawContactNormals (rp3d::DebugRenderer* debugRenderer) noexcept; + // Shape Generation Functions + + static void generateBox () noexcept; + + // Shape Draw Functions + static void debugDrawBox (const SHColliderComponent& colliderComponent, const SHCollisionShape& collisionShape) noexcept; static void debugDrawSphere (const SHColliderComponent& colliderComponent, const SHCollisionShape& collisionShape) noexcept; }; From e170a5fca8b5aab74944e102a11ea01b2f6581b3 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Thu, 17 Nov 2022 13:33:22 +0800 Subject: [PATCH 24/28] Added controls to editor viewport menu bar to adjust movement speed and turn speed for editor camera --- .../ViewportWindow/SHEditorViewport.cpp | 8 ++++++++ SHADE_Engine/src/Editor/SHEditorWidgets.hpp | 15 ++++++++------- .../src/Serialization/SHSerialization.cpp | 2 +- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp index 564731d6..93f4a615 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp @@ -14,6 +14,7 @@ #include "Camera/SHCameraSystem.h" #include "FRC/SHFramerateController.h" +#include "../../SHEditorWidgets.hpp" constexpr std::string_view windowName = "\xef\x80\x95 Viewport"; @@ -193,6 +194,13 @@ namespace SHADE if (isScale) ImGui::PopStyleColor(); ImGui::EndDisabled(); + + auto camSystem = SHSystemManager::GetSystem(); + auto editorCamera = camSystem->GetEditorCamera(); + //ImGui::SetNextItemWidth(10.0f); + SHEditorWidgets::SliderFloat("CamSpeed", 0.0f, 5.0f, [editorCamera] {return editorCamera->movementSpeed; }, [editorCamera](float const& value) {editorCamera->movementSpeed = value; }); + SHEditorWidgets::DragVec3("TurnSpeed", { "X", "Y", "Z" }, [editorCamera] {return editorCamera->turnSpeed; }, [editorCamera](SHVec3 const& value) {editorCamera->turnSpeed = value; }); + ImGui::EndMenuBar(); } } diff --git a/SHADE_Engine/src/Editor/SHEditorWidgets.hpp b/SHADE_Engine/src/Editor/SHEditorWidgets.hpp index bfde7525..2681e916 100644 --- a/SHADE_Engine/src/Editor/SHEditorWidgets.hpp +++ b/SHADE_Engine/src/Editor/SHEditorWidgets.hpp @@ -422,7 +422,7 @@ namespace SHADE ImGui::BeginGroup(); ImGui::PushID(label.data()); TextLabel(label); - bool changed = ImGui::InputText("##", &text, ImGuiInputTextFlags_ReadOnly, nullptr, nullptr); + bool changed = ImGui::InputText("##inputText", &text, ImGuiInputTextFlags_ReadOnly, nullptr, nullptr); if(SHDragDrop::BeginTarget()) { if(T* payload = SHDragDrop::AcceptPayload(dragDropTag)) @@ -454,7 +454,7 @@ namespace SHADE ImGui::BeginGroup(); ImGui::PushID(label.data()); TextLabel(label); - const bool hasChange = ImGui::DragScalar("##", data_type, &value, speed, &p_min, &p_max, displayFormat, flags); + const bool hasChange = ImGui::DragScalar("##dragScalar", data_type, &value, speed, &p_min, &p_max, displayFormat, flags); static bool startRecording = false; if (hasChange) { @@ -487,7 +487,7 @@ namespace SHADE ImGui::BeginGroup(); ImGui::PushID(label.data()); TextLabel(label); - const bool hasChange = ImGui::DragFloat("##", &value, speed, p_min, p_max, displayFormat, flags); + const bool hasChange = ImGui::DragFloat("##dragFloat", &value, speed, p_min, p_max, displayFormat, flags); static bool startRecording = false; if (hasChange) { @@ -520,7 +520,7 @@ namespace SHADE ImGui::BeginGroup(); ImGui::PushID(label.data()); TextLabel(label); - const bool hasChange = ImGui::DragInt("##", &value, speed, p_min, p_max, displayFormat, flags); + const bool hasChange = ImGui::DragInt("##dragInt", &value, speed, p_min, p_max, displayFormat, flags); static bool startRecording = false; if (hasChange) { @@ -553,7 +553,7 @@ namespace SHADE ImGui::BeginGroup(); ImGui::PushID(label.data()); TextLabel(label); - bool const hasChange = ImGui::SliderScalar("##", data_type, &value, &min, &max, displayFormat, flags); + bool const hasChange = ImGui::SliderScalar("##sliderScalar", data_type, &value, &min, &max, displayFormat, flags); static bool startRecording = false; if (hasChange) { @@ -587,7 +587,8 @@ namespace SHADE ImGui::BeginGroup(); ImGui::PushID(label.data()); TextLabel(label); - bool const hasChange = ImGui::SliderFloat("##", &value, min, max, displayFormat, flags); + ImGui::SetNextItemWidth(ImGui::CalcTextSize(displayFormat).x + ImGui::GetStyle().ItemInnerSpacing.x * 2.0f); + bool const hasChange = ImGui::SliderFloat("##sliderFloat", &value, min, max, displayFormat, flags); static bool startRecording = false; if (hasChange) { @@ -621,7 +622,7 @@ namespace SHADE ImGui::BeginGroup(); ImGui::PushID(label.data()); TextLabel(label); - bool const hasChange = ImGui::SliderInt("##", &value, min, max, displayFormat, flags); + bool const hasChange = ImGui::SliderInt("##sliderInt", &value, min, max, displayFormat, flags); static bool startRecording = false; if (hasChange) { diff --git a/SHADE_Engine/src/Serialization/SHSerialization.cpp b/SHADE_Engine/src/Serialization/SHSerialization.cpp index 6933fbb5..3ed96d7d 100644 --- a/SHADE_Engine/src/Serialization/SHSerialization.cpp +++ b/SHADE_Engine/src/Serialization/SHSerialization.cpp @@ -12,8 +12,8 @@ #include "Assets/Asset Types/SHSceneAsset.h" #include "Camera/SHCameraComponent.h" -#include "Graphics/MiddleEnd/Interface/SHRenderable.h" #include "Math/Transform/SHTransformComponent.h" +#include "Graphics/MiddleEnd/Interface/SHRenderable.h" #include "Physics/Interface/SHRigidBodyComponent.h" #include "ECS_Base/Managers/SHSystemManager.h" #include "Graphics/MiddleEnd/Lights/SHLightComponent.h" From 17662abef1fcbffc852ca5d538c9307a5ef15341 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 17 Nov 2022 15:42:40 +0800 Subject: [PATCH 25/28] Fixed bug where certain null objects in deserialization was not handled --- .../Serialisation/SerialisationUtilities.h++ | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/SHADE_Managed/src/Serialisation/SerialisationUtilities.h++ b/SHADE_Managed/src/Serialisation/SerialisationUtilities.h++ index dde6705a..2c943452 100644 --- a/SHADE_Managed/src/Serialisation/SerialisationUtilities.h++ +++ b/SHADE_Managed/src/Serialisation/SerialisationUtilities.h++ @@ -142,6 +142,31 @@ namespace SHADE bool SerialisationUtilities::fieldAssignYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node) { System::Object^ valueObj = fieldInfo->GetValue(object); + if (valueObj == nullptr) + { + if constexpr (std::is_same_v) + { + if (fieldInfo->FieldType->IsSubclassOf(System::Enum::typeid)) + { + valueObj = 0; + } + } + else + { + if (fieldInfo->FieldType == FieldType::typeid) + { + if constexpr (std::is_same_v) + { + valueObj = ""; + } + else + { + valueObj = FieldType(); + } + } + } + } + if (varAssignYamlInternal(valueObj, node)) { fieldInfo->SetValue(object, valueObj); From 6efbea54e169dac2753255e6ac5ee1959b76b237 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 17 Nov 2022 15:43:35 +0800 Subject: [PATCH 26/28] Fixed issue where scripts of Entities destroyed during scene unloading are not properly disposed --- SHADE_Engine/src/Scripting/SHScriptEngine.cpp | 2 +- SHADE_Managed/src/Scripts/ScriptStore.cxx | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp index 0db11c7a..e0b87bea 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp @@ -307,7 +307,7 @@ namespace SHADE SHEventHandle SHScriptEngine::onEntityDestroyed(SHEventPtr eventPtr) { auto eventData = reinterpret_cast*>(eventPtr.get()); - csScriptsRemoveAll(eventData->data->eid); + csScriptsRemoveAllImmediately(eventData->data->eid, true); return eventData->handle; } diff --git a/SHADE_Managed/src/Scripts/ScriptStore.cxx b/SHADE_Managed/src/Scripts/ScriptStore.cxx index d57122ee..29ba6e52 100644 --- a/SHADE_Managed/src/Scripts/ScriptStore.cxx +++ b/SHADE_Managed/src/Scripts/ScriptStore.cxx @@ -402,8 +402,8 @@ namespace SHADE System::Collections::Generic::List^ scriptList = scripts[entity]; for each (Script ^ script in scriptList) { - // Call OnDestroy only if indicated and also in play mode - if (callOnDestroy) + // Call OnDestroy only if indicated and also if the game has run + if (callOnDestroy && Application::IsPlaying || Application::IsPaused) { script->OnDestroy(); } @@ -469,7 +469,7 @@ namespace SHADE script->OnDestroy(); } auto entity = script->Owner.GetEntity(); - auto scriptList = scripts[script->Owner.GetEntity()]; + auto scriptList = scripts[script->Owner.GetEntity()]; // Unable to find here scriptList->Remove(script); if (scriptList->Count <= 0) { From 042bff5c1ad1639e552c82775d5f8d0174096ce9 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 17 Nov 2022 15:49:06 +0800 Subject: [PATCH 27/28] Added additional exception handling for serialization and deserialization failures for scripts to prevent data loss --- .../Serialisation/SerialisationUtilities.cxx | 46 +++++++++++++------ 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/SHADE_Managed/src/Serialisation/SerialisationUtilities.cxx b/SHADE_Managed/src/Serialisation/SerialisationUtilities.cxx index 147591a5..cfa94540 100644 --- a/SHADE_Managed/src/Serialisation/SerialisationUtilities.cxx +++ b/SHADE_Managed/src/Serialisation/SerialisationUtilities.cxx @@ -45,12 +45,22 @@ namespace SHADE System::Collections::Generic::IEnumerable^ fields = ReflectionUtilities::GetInstanceFields(object); for each (FieldInfo^ field in fields) { - // Ignore private and non-SerialiseField - if (!ReflectionUtilities::FieldIsSerialisable(field)) - continue; + try + { + // Ignore private and non-SerialiseField + if (!ReflectionUtilities::FieldIsSerialisable(field)) + continue; - // Serialise - writeFieldIntoYaml(field, object, scriptNode); + // Serialise + writeFieldIntoYaml(field, object, scriptNode); + } + catch (System::Exception^ e) + { + Debug::LogError + ( + System::String::Format("[SerialisationUtilities] Failed to serialise field ({0}): {1}", field->Name, e->ToString()) + ); + } } scriptListNode.push_back(scriptNode); @@ -74,15 +84,25 @@ namespace SHADE System::Collections::Generic::IEnumerable^ fields = ReflectionUtilities::GetInstanceFields(object); for each (FieldInfo^ field in fields) { - // Ignore private and non-SerialiseField - if (!ReflectionUtilities::FieldIsSerialisable(field)) - continue; - - // Deserialise - const std::string FIELD_NAME = Convert::ToNative(field->Name); - if (yamlNode[FIELD_NAME]) + try { - writeYamlIntoField(field, object, yamlNode[FIELD_NAME]); + // Ignore private and non-SerialiseField + if (!ReflectionUtilities::FieldIsSerialisable(field)) + continue; + + // Deserialise + const std::string FIELD_NAME = Convert::ToNative(field->Name); + if (yamlNode[FIELD_NAME]) + { + writeYamlIntoField(field, object, yamlNode[FIELD_NAME]); + } + } + catch (System::Exception^ e) + { + Debug::LogError + ( + System::String::Format("[SerialisationUtilities] Failed to deserialise field ({0}): {1}", field->Name, e->ToString()) + ); } } } From e8bd33ec9e037dc744026dbc79e3d52cf2f102ee Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 17 Nov 2022 17:36:35 +0800 Subject: [PATCH 28/28] Scripts are now always built on engine launch --- SHADE_Engine/src/Scripting/SHScriptEngine.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp index e0b87bea..84b50373 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp @@ -58,10 +58,9 @@ namespace SHADE loadFunctions(); // Generate script assembly if it hasn't been before - if (!fileExists(std::string(MANAGED_SCRIPT_LIB_NAME) + ".dll")) - { - BuildScriptAssembly(); - } +#ifndef _PUBLISH + BuildScriptAssembly(); +#endif // Initialise the CSharp Engine csEngineInit();