From d8ee9912130d29fe714308192ddd825afcb2d638 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Fri, 4 Nov 2022 18:39:45 +0800 Subject: [PATCH 01/59] Steps in the rendering process are now highlighted and named for debugging tools --- SHADE_Engine/src/Editor/SHEditor.cpp | 7 +++- .../Graphics/Commands/SHVkCommandBuffer.cpp | 38 +++++++++++++++++++ .../src/Graphics/Commands/SHVkCommandBuffer.h | 13 ++++++- .../Graphics/MiddleEnd/Batching/SHBatch.cpp | 2 + .../MiddleEnd/Interface/SHDebugDrawSystem.cpp | 3 ++ .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 6 +-- .../Graphics/RenderGraph/SHRenderGraph.cpp | 8 +++- .../src/Graphics/RenderGraph/SHRenderGraph.h | 5 ++- .../src/Graphics/RenderGraph/SHSubpass.cpp | 3 +- 9 files changed, 75 insertions(+), 10 deletions(-) diff --git a/SHADE_Engine/src/Editor/SHEditor.cpp b/SHADE_Engine/src/Editor/SHEditor.cpp index 6974d213..86987479 100644 --- a/SHADE_Engine/src/Editor/SHEditor.cpp +++ b/SHADE_Engine/src/Editor/SHEditor.cpp @@ -441,9 +441,12 @@ namespace SHADE ImGui_ImplVulkan_DestroyFontUploadObjects(); - renderGraph->GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle& cmd) { + renderGraph->GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle& cmd) + { + cmd->BeginLabeledSegment("ImGui Draw"); ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->GetVkCommandBuffer()); - }); + cmd->EndLabeledSegment(); + }); #endif } diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp index fb64bcc2..cc35303b 100644 --- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp +++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp @@ -105,6 +105,9 @@ namespace SHADE // Set the state to recording if the call above succeeded. cmdBufferState = SH_CMD_BUFFER_STATE::RECORDING; + + // Reset segment count + segmentDepth = 0; } /***************************************************************************/ @@ -507,6 +510,41 @@ namespace SHADE SetState(SH_CMD_BUFFER_STATE::PENDING); } + void SHVkCommandBuffer::BeginLabeledSegment(const std::string& label) noexcept + { +#ifdef _DEBUG + static const std::array SEGMENT_COLOURS = + { + SHColour::LIGHTPINK, + SHColour::LIGHTBLUE, + SHColour::LIGHTGREEN, + SHColour::YELLOW, + SHColour::PINK, + SHColour::TEAL, + SHColour::LIME, + SHColour::ORANGE, + SHColour::VIOLET, + SHColour::MAROON, + SHColour::DARKGREEN, + SHColour::SANDYBROWN + }; + + const SHColour COLOR = SEGMENT_COLOURS[segmentDepth]; + ++segmentDepth; + if (segmentDepth >= static_cast(SEGMENT_COLOURS.size())) + segmentDepth = 0; + vkCommandBuffer.beginDebugUtilsLabelEXT(vk::DebugUtilsLabelEXT().setPLabelName(label.data()).setColor({ COLOR.x, COLOR.y, COLOR.z, COLOR.w })); +#endif + } + + void SHVkCommandBuffer::EndLabeledSegment() noexcept + { +#ifdef _DEBUG + vkCommandBuffer.endDebugUtilsLabelEXT(); + segmentDepth = std::max(segmentDepth - 1, 0); +#endif + } + //void SHVkCommandBuffer::PipelineBarrier(vk::PipelineStageFlags ) const noexcept //{ // //vkCommandBuffer.pipelineBarrier() diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h index bc0d4b04..022d4b62 100644 --- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h +++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h @@ -7,6 +7,7 @@ #include "Resource/SHResourceLibrary.h" #include "Graphics/Pipeline/SHVkPipelineLayout.h" #include "Graphics/Pipeline/SHPipelineType.h" +#include "Math/SHColour.h" namespace SHADE { @@ -78,7 +79,11 @@ namespace SHADE std::array(SH_PIPELINE_TYPE::NUM_TYPES)> bindPointData; //! The push constant data for the command buffer - uint8_t pushConstantData[PUSH_CONSTANT_SIZE]; + uint8_t pushConstantData[PUSH_CONSTANT_SIZE]; + +#ifdef _DEBUG + int segmentDepth; +#endif /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER FUNCTIONS */ @@ -107,7 +112,7 @@ namespace SHADE void Reset(void); // Begins and Ends - void BeginRecording (void) noexcept; + void BeginRecording () noexcept; void EndRecording (void) noexcept; void BeginRenderpass (Handle const& renderpassHdl, Handle const& framebufferHdl, vk::Offset2D offset = {0, 0}, vk::Extent2D extent = {0, 0}) noexcept; void EndRenderpass (void) noexcept; @@ -148,6 +153,10 @@ namespace SHADE bool IsReadyToSubmit (void) const noexcept; void HandlePostSubmit (void) noexcept; + // Debugging + void BeginLabeledSegment(const std::string& label) noexcept; + void EndLabeledSegment() noexcept; + // Push Constant variable setting template void SetPushConstantVariable(std::string variableName, T const& data, SH_PIPELINE_TYPE bindPoint) noexcept diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index 22d1875b..c2471f79 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -427,6 +427,7 @@ namespace SHADE // Bind all required objects before drawing static std::array dynamicOffset{ 0 }; + cmdBuffer->BeginLabeledSegment("SHBatch"); cmdBuffer->BindPipeline(pipeline); cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0); cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::INTEGER_DATA, instancedIntegerBuffer[frameIndex], 0); @@ -441,6 +442,7 @@ namespace SHADE ); } cmdBuffer->DrawMultiIndirect(drawDataBuffer[frameIndex], static_cast(drawData.size())); + cmdBuffer->EndLabeledSegment(); } /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.cpp index 37d15808..c4dc2c8f 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.cpp @@ -98,6 +98,7 @@ namespace SHADE // Don't draw if no points if (numPoints[FRAME_IDX] > 0) { + cmdBuffer->BeginLabeledSegment("SHDebugDraw"); cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawPipeline()); cmdBuffer->SetLineWidth(LineWidth); cmdBuffer->BindVertexBuffer(0, vertexBuffers[FRAME_IDX], 0); @@ -113,10 +114,12 @@ namespace SHADE // Don't draw if no points if (numPersistentPoints[FRAME_IDX] > 0) { + cmdBuffer->BeginLabeledSegment("SHDebugDraw (Persistent)"); cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawDepthPipeline()); cmdBuffer->SetLineWidth(LineWidth); cmdBuffer->BindVertexBuffer(0, persistentVertexBuffers[FRAME_IDX], 0); cmdBuffer->DrawArrays(numPersistentPoints[FRAME_IDX], 1, 0, 0); + cmdBuffer->EndLabeledSegment(); } }); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index be67f1b3..1884fa57 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -1,5 +1,5 @@ /************************************************************************************//*! -\file SHGraphicsSystem.cpp +\file SHGrphicsSystem.cpp \author Tng Kah Wei, kahwei.tng, 390009620 \par email: kahwei.tng\@digipen.edu \date Aug 21, 2022 @@ -164,7 +164,7 @@ namespace SHADE /* SCENE RENDER GRAPH RESOURCES */ /*-----------------------------------------------------------------------*/ // Initialize world render graph - worldRenderGraph->Init(device, swapchain); + worldRenderGraph->Init("World Render Graph", device, swapchain); worldRenderGraph->AddResource("Position", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat); worldRenderGraph->AddResource("Normals", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat); //worldRenderGraph->AddResource("Tangents", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat); @@ -331,7 +331,7 @@ namespace SHADE for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i) renderContextCmdPools[i] = renderContext.GetFrameData(i).cmdPoolHdls[0]; - editorRenderGraph->Init(device, swapchain); + editorRenderGraph->Init("Editor Render Graph", device, swapchain); editorRenderGraph->AddResource("Present", { SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second); diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index 93be2413..66dc6a0f 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -353,7 +353,7 @@ namespace SHADE */ /***************************************************************************/ - void SHRenderGraph::Init(Handle logicalDevice, Handle swapchain) noexcept + void SHRenderGraph::Init(std::string graphName, Handle logicalDevice, Handle swapchain) noexcept { resourceManager = std::make_shared(); @@ -365,6 +365,8 @@ namespace SHADE renderGraphStorage->resourceManager = resourceManager; renderGraphStorage->descriptorPool = logicalDevice->CreateDescriptorPools(); + + name = std::move(graphName); } /***************************************************************************/ @@ -390,6 +392,7 @@ namespace SHADE , nodeIndexing{ std::move(rhs.nodeIndexing) } , nodes{ std::move(rhs.nodes) } , resourceManager{ std::move(rhs.resourceManager) } + , name { std::move(rhs.name) } { } @@ -403,6 +406,7 @@ namespace SHADE nodeIndexing = std::move(rhs.nodeIndexing); nodes = std::move(rhs.nodes); resourceManager = std::move(rhs.resourceManager); + name = std::move(rhs.name); return *this; } @@ -516,8 +520,10 @@ namespace SHADE // better way to manage these void SHRenderGraph::Execute(uint32_t frameIndex, Handle cmdBuffer, Handle descPool) noexcept { + cmdBuffer->BeginLabeledSegment(name); for (auto& node : nodes) node->Execute(cmdBuffer, descPool, frameIndex); + cmdBuffer->EndLabeledSegment(); } void SHRenderGraph::FinaliseBatch(uint32_t frameIndex, Handle descPool) diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h index d90b66df..741cc522 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h @@ -69,6 +69,9 @@ namespace SHADE //! Resource library for graph handles std::shared_ptr resourceManager; + //! Name of the RenderGraph + std::string name; + public: /*-----------------------------------------------------------------------*/ /* CTORS AND DTORS */ @@ -81,7 +84,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* PUBLIC MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ - void Init (Handle logicalDevice, Handle swapchain) noexcept; + void Init (std::string graphName, Handle logicalDevice, Handle swapchain) noexcept; void AddResource(std::string resourceName, std::initializer_list typeFlags, uint32_t w = static_cast(-1), uint32_t h = static_cast(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageUsageFlagBits usageFlags = {}, vk::ImageCreateFlagBits createFlags = {}); Handle AddNode (std::string nodeName, std::initializer_list resourceInstruction, std::initializer_list predecessorNodes) noexcept; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp index 6e78eb9f..23dbbde3 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp @@ -201,6 +201,7 @@ namespace SHADE void SHSubpass::Execute(Handle& commandBuffer, Handle descPool, uint32_t frameIndex) noexcept { + commandBuffer->BeginLabeledSegment(name); // Ensure correct transforms are provided superBatch->UpdateBuffers(frameIndex, descPool); @@ -212,7 +213,7 @@ namespace SHADE { drawCall(commandBuffer); } - + commandBuffer->EndLabeledSegment(); } void SHSubpass::HandleResize(void) noexcept From b5bc64456c52930f75ca7eff8b177faea7e7f6d4 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Fri, 4 Nov 2022 19:16:57 +0800 Subject: [PATCH 02/59] Added debug names for some SHVkBuffers --- .../src/Graphics/Buffers/SHVkBuffer.cpp | 13 +++++- .../src/Graphics/Buffers/SHVkBuffer.h | 14 ++++-- .../Graphics/Devices/SHVkLogicalDevice.cpp | 5 +- .../src/Graphics/Devices/SHVkLogicalDevice.h | 27 ++++++++--- .../Graphics/Devices/SHVkLogicalDevice.hpp | 46 +++++++++++++++++++ .../Graphics/MiddleEnd/Batching/SHBatch.cpp | 9 ++-- .../MiddleEnd/Interface/SHDebugDrawSystem.cpp | 6 ++- SHADE_Engine/src/Graphics/SHVkUtil.cpp | 10 ++-- SHADE_Engine/src/Graphics/SHVkUtil.h | 4 +- 9 files changed, 110 insertions(+), 24 deletions(-) create mode 100644 SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.hpp diff --git a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp index 08481483..63f580b9 100644 --- a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp +++ b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp @@ -269,7 +269,7 @@ namespace SHADE */ /***************************************************************************/ - SHVkBuffer::SHVkBuffer(std::reference_wrapper allocator) noexcept + SHVkBuffer::SHVkBuffer(Handle logicalDevice, std::reference_wrapper allocator) noexcept : vkBuffer{} , stagingBuffer{} , sizeStored{ 0 } @@ -277,19 +277,23 @@ namespace SHADE , alloc {nullptr} , randomAccessOptimized{false} , vmaAllocator{allocator} + , device { logicalDevice } {} SHVkBuffer::SHVkBuffer( + Handle logicalDevice, uint32_t inSize, void* data, uint32_t srcSize, std::reference_wrapper allocator, vk::BufferUsageFlags bufferUsage, + const std::string& name, VmaMemoryUsage memUsage, VmaAllocationCreateFlags allocFlags ) noexcept - : SHVkBuffer(allocator) + : SHVkBuffer(logicalDevice, allocator) { + this->name = name; Init(inSize, data, srcSize, bufferUsage, memUsage, allocFlags); } @@ -304,6 +308,8 @@ namespace SHADE , bufferUsageFlags {rhs.bufferUsageFlags} , bufferCreateInfo { rhs.bufferCreateInfo } , allocCreateInfo { rhs.allocCreateInfo } + , name { std::move(rhs.name) } + , device { rhs.device } { rhs.vkBuffer = VK_NULL_HANDLE; @@ -325,6 +331,8 @@ namespace SHADE bufferCreateInfo = rhs.bufferCreateInfo; allocCreateInfo = rhs.allocCreateInfo; bufferUsageFlags = rhs.bufferUsageFlags; + name = std::move(rhs.name); + device = rhs.device; return *this; } @@ -402,6 +410,7 @@ namespace SHADE auto [tempBuffer, allocInfo] = createBuffer(sizeStored); vkBuffer = tempBuffer; + SET_VK_OBJ_NAME(*device, vk::ObjectType::eBuffer, vkBuffer, name); // This probably means that a HOST_CACHED memory type is used on allocation if (allocFlags & VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT) diff --git a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.h b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.h index eb24d161..1119342c 100644 --- a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.h +++ b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.h @@ -12,6 +12,7 @@ namespace SHADE //using SHVkBufferUsageBits = vk::BufferUsageFlagBits; class SHVkCommandBuffer; + class SHVkLogicalDevice; class SHVkBuffer { @@ -51,6 +52,11 @@ namespace SHADE //VmaAllocator const& vmaAllocator; std::reference_wrapper vmaAllocator; + //! Name of this buffer if any + std::string name; + //! Handle to the logical device that created this buffer + Handle device; + /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ @@ -62,13 +68,15 @@ namespace SHADE /* CTORS AND DTORS */ /*-----------------------------------------------------------------------*/ SHVkBuffer (void) noexcept = delete; - SHVkBuffer (std::reference_wrapper allocator) noexcept; + SHVkBuffer (Handle logicalDevice, std::reference_wrapper allocator) noexcept; SHVkBuffer ( + Handle logicalDevice, uint32_t inSize, void* data, uint32_t srcSize, std::reference_wrapper allocator, - vk::BufferUsageFlags bufferUsage, + vk::BufferUsageFlags bufferUsage, + const std::string& name = "", VmaMemoryUsage memUsage = VMA_MEMORY_USAGE_AUTO, VmaAllocationCreateFlags allocFlags = {} ) noexcept; @@ -84,7 +92,7 @@ namespace SHADE uint32_t inSize, void* data, uint32_t srcSize, - vk::BufferUsageFlags bufferUsage, + vk::BufferUsageFlags bufferUsage, VmaMemoryUsage memUsage, VmaAllocationCreateFlags allocFlags ) noexcept; diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp index 6bf2e731..35c104ee 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp @@ -220,6 +220,7 @@ namespace SHADE else { SHVulkanDebugUtil::ReportVkSuccess("Successfully created a Logical Device. "); + SET_VK_OBJ_NAME((*this), vk::ObjectType::eDevice, vkLogicalDevice, "Logical Device"); } InitializeVMA(); @@ -419,9 +420,9 @@ namespace SHADE */ /***************************************************************************/ - Handle SHVkLogicalDevice::CreateBuffer(uint32_t inSize, void* data, uint32_t srcSize, vk::BufferUsageFlags bufferUsage, VmaMemoryUsage memUsage, VmaAllocationCreateFlags allocFlags) const noexcept + Handle SHVkLogicalDevice::CreateBuffer(uint32_t inSize, void* data, uint32_t srcSize, vk::BufferUsageFlags bufferUsage, VmaMemoryUsage memUsage, VmaAllocationCreateFlags allocFlags, const std::string& name) const noexcept { - return SHVkInstance::GetResourceManager().Create(inSize, data, srcSize, std::cref(vmaAllocator), bufferUsage, memUsage, allocFlags); + return SHVkInstance::GetResourceManager().Create(GetHandle(), inSize, data, srcSize, std::cref(vmaAllocator), bufferUsage, name, memUsage, allocFlags); } /***************************************************************************/ diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h index 2aa59941..827f12b3 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h @@ -1,5 +1,4 @@ -#ifndef SH_LOGICAL_DEVICE_H -#define SH_LOGICAL_DEVICE_H +#pragma once #include #include @@ -67,7 +66,6 @@ namespace SHADE class SHVkLogicalDevice : public ISelfHandle { private: - /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER VARIABLES */ /*-----------------------------------------------------------------------*/ @@ -147,7 +145,8 @@ namespace SHADE uint32_t srcSize, vk::BufferUsageFlags bufferUsage, VmaMemoryUsage memUsage, - VmaAllocationCreateFlags allocFlags + VmaAllocationCreateFlags allocFlags, + const std::string& name = "" ) const noexcept; Handle CreateImage ( @@ -202,7 +201,23 @@ namespace SHADE Handle CreateSemaphore (void) const noexcept; void UpdateDescriptorSets(std::vector const& writeDescSets) noexcept; - void UpdateDescriptorSet (vk::WriteDescriptorSet const& writeDescSet) noexcept; + void UpdateDescriptorSet(vk::WriteDescriptorSet const& writeDescSet) noexcept; + + /*-----------------------------------------------------------------------*/ + /* Debug Tools */ + /*-----------------------------------------------------------------------*/ +#ifdef _DEBUG + /// + /// Sets a Vulkan object's name for debugging purposes. This function will not be + /// compiled outsied of Debug configurations. Hence, it is advised to use provided + /// macro function SET_VK_OBJ_NAME() instead of using this function directly. + /// + /// Type of the object. + /// Handle to the Vulkan Object to name. + /// Object's name. + template + inline void SetVulkanObjectName(vk::ObjectType objType, T objHandle, const std::string& objName); +#endif /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ @@ -220,4 +235,4 @@ namespace SHADE }; } -#endif +#include "SHVkLogicalDevice.hpp" diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.hpp b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.hpp new file mode 100644 index 00000000..dd7ff609 --- /dev/null +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.hpp @@ -0,0 +1,46 @@ +/************************************************************************************//*! +\file SHVkLogicalDevice.hpp +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Nov 4, 2022 +\brief Contains implementation of inline and template functions of + SHVkLogicalDevice. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#pragma once + +#include "SHVkLogicalDevice.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Debug Tools */ + /*-----------------------------------------------------------------------------------*/ +#ifdef _DEBUG + template + void SHVkLogicalDevice::SetVulkanObjectName(vk::ObjectType objType, T objHandle, const std::string& objName) + { + if (objName.empty()) + return; + + vk::DebugUtilsObjectNameInfoEXT info; + info.objectType = objType; + info.objectHandle = (uint64_t) static_cast(objHandle); + info.pObjectName = objName.data(); + vkLogicalDevice.setDebugUtilsObjectNameEXT(info); + } +#endif +} + +/*-------------------------------------------------------------------------------------*/ +/* Macro Definitions */ +/*-------------------------------------------------------------------------------------*/ +#ifdef _DEBUG +#define SET_VK_OBJ_NAME(DEVICE, OBJ_TYPE, OBJ_HDL, OBJ_NAME) \ + (DEVICE).SetVulkanObjectName(OBJ_TYPE, OBJ_HDL, OBJ_NAME); +#else +#define SET_VK_OBJ_NAME(DEVICE, OBJ_TYPE, OBJ_HDL, OBJ_NAME) +#endif diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index c2471f79..3f9b6fa2 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -392,20 +392,23 @@ namespace SHADE SHVkUtil::EnsureBufferAndCopyHostVisibleData ( device, drawDataBuffer[frameIndex], drawData.data(), DRAW_DATA_BYTES, - BuffUsage::eIndirectBuffer + BuffUsage::eIndirectBuffer, + "Batch Draw Data Buffer" ); // - Transform Buffer const uint32_t TF_DATA_BYTES = static_cast(transformData.size() * sizeof(SHMatrix)); SHVkUtil::EnsureBufferAndCopyHostVisibleData ( device, transformDataBuffer[frameIndex], transformData.data(), TF_DATA_BYTES, - BuffUsage::eVertexBuffer + BuffUsage::eVertexBuffer, + "Batch Transform Buffer" ); const uint32_t EID_DATA_BYTES = static_cast(instancedIntegerData.size() * sizeof(SHInstancedIntegerData)); SHVkUtil::EnsureBufferAndCopyHostVisibleData ( device, instancedIntegerBuffer[frameIndex], instancedIntegerData.data(), EID_DATA_BYTES, - BuffUsage::eVertexBuffer + BuffUsage::eVertexBuffer, + "Batch Instance Data Buffer" ); // - Material Properties Buffer rebuildMaterialBuffers(frameIndex, descPool); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.cpp index c4dc2c8f..48e46a40 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.cpp @@ -141,7 +141,8 @@ namespace SHADE 0, vk::BufferUsageFlagBits::eVertexBuffer, VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO, - VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT + VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT, + "Debug Draw Non-Persistent Vertex Buffer" ); } // - Persistent Draws @@ -154,7 +155,8 @@ namespace SHADE 0, vk::BufferUsageFlagBits::eVertexBuffer, VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO, - VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT + VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT, + "Debug Draw Persistent Vertex Buffer" ); } } diff --git a/SHADE_Engine/src/Graphics/SHVkUtil.cpp b/SHADE_Engine/src/Graphics/SHVkUtil.cpp index 8b21e7d1..a9ac543f 100644 --- a/SHADE_Engine/src/Graphics/SHVkUtil.cpp +++ b/SHADE_Engine/src/Graphics/SHVkUtil.cpp @@ -82,7 +82,7 @@ namespace SHADE } } - void SHVkUtil::EnsureBufferAndCopyData(Handle device, Handle cmdBuffer, Handle& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage) + void SHVkUtil::EnsureBufferAndCopyData(Handle device, Handle cmdBuffer, Handle& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage, const std::string& name) { if (bufferHandle) { @@ -100,7 +100,8 @@ namespace SHADE size, usage | BuffUsage::eTransferDst, VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO, - VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT + VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT, + name ); } @@ -108,7 +109,7 @@ namespace SHADE bufferHandle->TransferToDeviceResource(cmdBuffer); } - void SHVkUtil::EnsureBufferAndCopyHostVisibleData(Handle device, Handle& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage) + void SHVkUtil::EnsureBufferAndCopyHostVisibleData(Handle device, Handle& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage, const std::string& name) { if (bufferHandle) { @@ -126,7 +127,8 @@ namespace SHADE size, usage, VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO, - VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT + VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT, + name ); } } diff --git a/SHADE_Engine/src/Graphics/SHVkUtil.h b/SHADE_Engine/src/Graphics/SHVkUtil.h index de700ea5..07e8f02e 100644 --- a/SHADE_Engine/src/Graphics/SHVkUtil.h +++ b/SHADE_Engine/src/Graphics/SHVkUtil.h @@ -54,7 +54,7 @@ namespace SHADE */ /***********************************************************************************/ - static void EnsureBufferAndCopyData(Handle device, Handle cmdBuffer, Handle& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage); + static void EnsureBufferAndCopyData(Handle device, Handle cmdBuffer, Handle& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage, const std::string& name = ""); /***********************************************************************************/ /*! @@ -80,7 +80,7 @@ namespace SHADE */ /***********************************************************************************/ - static void EnsureBufferAndCopyHostVisibleData(Handle device, Handle& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage); + static void EnsureBufferAndCopyHostVisibleData(Handle device, Handle& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage, const std::string& name = ""); static BindingAndSetHash GenBindingSetHash (uint32_t set, uint32_t binding) noexcept; }; From ab17d577560706321699e6cd7424e3c58455c6e2 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Fri, 4 Nov 2022 23:32:29 +0800 Subject: [PATCH 03/59] Asset browser now recurses down subassets --- Assets/Materials/BagMaterial.shmat | 8 +++ Assets/Materials/BagMaterial.shmat.shmeta | 3 + Assets/Scenes/M2Scene.shade | 27 +++++-- Assets/Scenes/Scene2.shade | 72 +++++++++++++++++++ Assets/Scenes/Scene2.shade.shmeta | 3 + .../AssetBrowser/SHAssetBrowser.cpp | 57 ++++++++++----- .../AssetBrowser/SHAssetBrowser.h | 2 +- 7 files changed, 147 insertions(+), 25 deletions(-) create mode 100644 Assets/Materials/BagMaterial.shmat create mode 100644 Assets/Materials/BagMaterial.shmat.shmeta create mode 100644 Assets/Scenes/Scene2.shade create mode 100644 Assets/Scenes/Scene2.shade.shmeta diff --git a/Assets/Materials/BagMaterial.shmat b/Assets/Materials/BagMaterial.shmat new file mode 100644 index 00000000..e538b834 --- /dev/null +++ b/Assets/Materials/BagMaterial.shmat @@ -0,0 +1,8 @@ +- VertexShader: 39210065 + FragmentShader: 46377769 + SubPass: G-Buffer Write + Properties: + data.color: {x: 1, y: 1, z: 1, w: 1} + data.textureIndex: 58303057 + data.alpha: 0 + data.beta: {x: 1, y: 1, z: 1} \ No newline at end of file diff --git a/Assets/Materials/BagMaterial.shmat.shmeta b/Assets/Materials/BagMaterial.shmat.shmeta new file mode 100644 index 00000000..b903a854 --- /dev/null +++ b/Assets/Materials/BagMaterial.shmat.shmeta @@ -0,0 +1,3 @@ +Name: BagMaterial +ID: 123745521 +Type: 7 diff --git a/Assets/Scenes/M2Scene.shade b/Assets/Scenes/M2Scene.shade index 38c0a523..60dbb5f9 100644 --- a/Assets/Scenes/M2Scene.shade +++ b/Assets/Scenes/M2Scene.shade @@ -50,7 +50,7 @@ Colliders: - Is Trigger: false Type: Box - Half Extents: {x: 0.0170898438, y: 0.00048828125, z: 0.0170898438} + Half Extents: {x: 0.00427246094, y: 0.000122070312, z: 0.00427246094} Friction: 0.400000006 Bounciness: 0 Density: 1 @@ -59,7 +59,7 @@ - EID: 2 Name: Player IsActive: true - NumberOfChildren: 2 + NumberOfChildren: 3 Components: Transform Component: Translate: {x: -3.06177855, y: -2, z: -5} @@ -85,7 +85,7 @@ Colliders: - Is Trigger: false Type: Box - Half Extents: {x: 0.0009765625, y: 0.0009765625, z: 0.0009765625} + Half Extents: {x: 0.000244140625, y: 0.000244140625, z: 0.000244140625} Friction: 0.400000006 Bounciness: 0 Density: 1 @@ -111,6 +111,19 @@ Rotate: {x: 0, y: 0, z: 0} Scale: {x: 1, y: 1, z: 1} Scripts: ~ +- EID: 9 + Name: Default + 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: 5 Name: item IsActive: true @@ -121,7 +134,7 @@ Rotate: {x: 0, y: 0, z: 0} Scale: {x: 2, y: 2, z: 2} Renderable Component: - Mesh: 149697411 + Mesh: 144838771 Material: 126974645 RigidBody Component: Type: Dynamic @@ -140,14 +153,14 @@ Colliders: - Is Trigger: false Type: Box - Half Extents: {x: 0.0009765625, y: 0.0009765625, z: 0.0009765625} + Half Extents: {x: 0.000244140625, y: 0.000244140625, z: 0.000244140625} Friction: 0.400000006 Bounciness: 0 Density: 1 Position Offset: {x: 0, y: 0.5, z: 0} - Is Trigger: true Type: Box - Half Extents: {x: 0.001953125, y: 0.001953125, z: 0.001953125} + Half Extents: {x: 0.00048828125, y: 0.00048828125, z: 0.00048828125} Friction: 0.400000006 Bounciness: 0 Density: 1 @@ -182,7 +195,7 @@ Colliders: - Is Trigger: false Type: Box - Half Extents: {x: 0.0009765625, y: 0.0009765625, z: 0.0009765625} + Half Extents: {x: 0.000244140625, y: 0.000244140625, z: 0.000244140625} Friction: 0.400000006 Bounciness: 0 Density: 1 diff --git a/Assets/Scenes/Scene2.shade b/Assets/Scenes/Scene2.shade new file mode 100644 index 00000000..2f38a933 --- /dev/null +++ b/Assets/Scenes/Scene2.shade @@ -0,0 +1,72 @@ +- EID: 0 + Name: Default + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0, y: 0.304069757, z: 1.73034382} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + Camera Component: + Position: {x: 0, y: 0.304069757, z: 1.73034382} + Pitch: 0 + Yaw: 0 + Roll: 0 + Width: 1200 + Height: 1080 + Near: 0.00999999978 + Far: 10000 + Perspective: true + Scripts: ~ +- EID: 1 + Name: Raccoon + IsActive: true + NumberOfChildren: 1 + 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: 149697411 + Material: 126974645 + Scripts: ~ +- EID: 3 + Name: Bag + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0.006237939, y: -0.000393368304, z: 0} + Rotate: {x: -0, y: 2.79945588, z: 0} + Scale: {x: 1.0000881, y: 1, z: 1.0000881} + Renderable Component: + Mesh: 144838771 + Material: 123745521 + Scripts: ~ +- EID: 2 + Name: DirectionalLight + IsActive: true + NumberOfChildren: 0 + Components: + Light Component: + Position: {x: 0, y: 0, z: 0} + Type: Directional + Direction: {x: 0, y: 0, z: 1} + Color: {x: 1, y: 1, z: 1, w: 1} + Layer: 4294967295 + Strength: 0 + Scripts: ~ +- EID: 4 + Name: AmbientLight + IsActive: true + NumberOfChildren: 0 + Components: + Light Component: + Position: {x: 0, y: 0, z: 0} + Type: Ambient + Direction: {x: 0, y: 0, z: 1} + Color: {x: 1, y: 1, z: 1, w: 1} + Layer: 4294967295 + Strength: 0.600000024 + Scripts: ~ \ No newline at end of file diff --git a/Assets/Scenes/Scene2.shade.shmeta b/Assets/Scenes/Scene2.shade.shmeta new file mode 100644 index 00000000..bbcbc66c --- /dev/null +++ b/Assets/Scenes/Scene2.shade.shmeta @@ -0,0 +1,3 @@ +Name: Scene2 +ID: 87285316 +Type: 5 diff --git a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp index d875d743..37b8ecd4 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp @@ -102,8 +102,10 @@ namespace SHADE } for (auto const& file : files) { + if(file.assetMeta == nullptr) + continue; const float horizontalLineSize = 25.0f; - const ImRect childRect = DrawFile(file); + const ImRect childRect = DrawFile(file.assetMeta); const float midPoint = (childRect.Min.y + childRect.Max.y) * 0.5f; drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1); vertLineEnd.y = midPoint; @@ -146,47 +148,48 @@ namespace SHADE //} } - ImRect SHAssetBrowser::DrawFile(SHFile const& file) noexcept + ImRect SHAssetBrowser::DrawFile(SHAsset const* const asset) noexcept { - if (file.assetMeta == nullptr) + if (asset == nullptr) return ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax()); - const bool isSelected = std::ranges::find(selectedAssets, file.assetMeta->id) != selectedAssets.end(); - ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_Leaf; + const bool isSelected = std::ranges::find(selectedAssets, asset->id) != selectedAssets.end(); + ImGuiTreeNodeFlags flags = (!asset->subAssets.empty()) ? ImGuiTreeNodeFlags_OpenOnArrow : ImGuiTreeNodeFlags_Leaf; if (isSelected) flags |= ImGuiTreeNodeFlags_Selected; std::string icon{}; - switch (file.assetMeta->type) + switch (asset->type) { case AssetType::INVALID: break; case AssetType::SHADER: icon = ICON_FA_FILE_CODE; break; case AssetType::SHADER_BUILT_IN: icon = ICON_FA_FILE_CODE; break; case AssetType::TEXTURE: icon = ICON_FA_IMAGES; break; - case AssetType::MESH: icon = ICON_FA_CUBES; break; + case AssetType::MODEL: icon = ICON_FA_CUBES_STACKED; break; case AssetType::SCENE: icon = ICON_MD_IMAGE; break; case AssetType::PREFAB: icon = ICON_FA_BOX_OPEN; break; case AssetType::MATERIAL: break; + case AssetType::MESH: icon = ICON_FA_CUBES; break; case AssetType::MAX_COUNT: break; default:; } - - ImGui::TreeNodeEx(file.assetMeta, flags, "%s %s", icon.data(), file.assetMeta->name.data()); + + bool const isOpen = ImGui::TreeNodeEx(asset, flags, "%s %s", icon.data(), asset->name.data()); const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax()); if (SHDragDrop::BeginSource()) { - auto id = file.assetMeta->id; - ImGui::Text("Moving Asset: %s [%zu]", file.name.data(), file.assetMeta->id); + auto id = asset->id; + ImGui::Text("Moving Asset: %s [%zu]", asset->name.data(), asset->id); SHDragDrop::SetPayload(SHDragDrop::DRAG_RESOURCE, &id); SHDragDrop::EndSource(); } if (ImGui::IsItemClicked()) { selectedAssets.clear(); - selectedAssets.push_back(file.assetMeta->id); + selectedAssets.push_back(asset->id); } if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) { - switch (file.assetMeta->type) + switch (asset->type) { case AssetType::INVALID: break; case AssetType::SHADER: break; @@ -196,14 +199,14 @@ namespace SHADE case AssetType::SCENE: if(auto editor = SHSystemManager::GetSystem()) { - editor->LoadScene(file.assetMeta->id); + editor->LoadScene(asset->id); } break; case AssetType::PREFAB: break; case AssetType::MATERIAL: if (auto matInspector = SHEditorWindowManager::GetEditorWindow()) { - matInspector->OpenMaterial(file.assetMeta->id); + matInspector->OpenMaterial(asset->id); } break; case AssetType::MAX_COUNT: break; @@ -211,7 +214,27 @@ namespace SHADE } } - ImGui::TreePop(); + + //TODO: Combine Draw asset and Draw Folder recursive drawing + const ImColor treeLineColor = ImGui::GetColorU32(ImGuiCol_CheckMark); + const float horizontalOffset = 0.0f; + ImDrawList* drawList = ImGui::GetWindowDrawList(); + ImVec2 vertLineStart = ImGui::GetCursorScreenPos(); + vertLineStart.x += horizontalOffset; + ImVec2 vertLineEnd = vertLineStart; + if(isOpen) + { + for(auto const& subAsset : asset->subAssets) + { + const float horizontalLineSize = 25.0f; + const ImRect childRect = DrawFile(subAsset); + const float midPoint = (childRect.Min.y + childRect.Max.y) * 0.5f; + drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1); + vertLineEnd.y = midPoint; + } + drawList->AddLine(vertLineStart, vertLineEnd, treeLineColor, 1); + ImGui::TreePop(); + } return nodeRect; } @@ -222,7 +245,7 @@ namespace SHADE auto& path = std::get<0>(assetBeingCreated.value()); auto& type = std::get<1>(assetBeingCreated.value()); auto& assetName = std::get<2>(assetBeingCreated.value()); - if (ImGui::InputText("##newAssetname", &assetName, ImGuiInputTextFlags_EnterReturnsTrue)) + if (ImGui::InputText("##newAssetName", &assetName, ImGuiInputTextFlags_EnterReturnsTrue)) { AssetID assetId = SHAssetManager::CreateNewAsset(type, assetName); if (auto matInspector = SHEditorWindowManager::GetEditorWindow()) diff --git a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h index eec40262..00023ebe 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h +++ b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h @@ -21,7 +21,7 @@ namespace SHADE void DrawMenuBar(); ImRect RecursivelyDrawTree(FolderPointer folder); void DrawCurrentFolder(); - ImRect DrawFile(SHFile const& file) noexcept; + ImRect DrawFile(SHAsset const* const asset) noexcept; void DrawAssetBeingCreated() noexcept; FolderPointer rootFolder, prevFolder, currentFolder; From 40422a6d23c44c35221473ebdd017d6623daa10d Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Sat, 5 Nov 2022 00:00:45 +0800 Subject: [PATCH 04/59] Added built-in primitives --- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 66 ++++++++---- .../MiddleEnd/Interface/SHGraphicsSystem.h | 102 +++++++++++++----- 2 files changed, 119 insertions(+), 49 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 43de46bb..573c7f7f 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -41,6 +41,7 @@ of DigiPen Institute of Technology is prohibited. #include "Resource/SHResourceManager.h" #include "Graphics/SHVkUtil.h" #include "Graphics/RenderGraph/SHRenderGraphNodeCompute.h" +#include "../Meshes/SHPrimitiveGenerator.h" namespace SHADE { @@ -259,7 +260,6 @@ namespace SHADE // Generate world render graph worldRenderGraph->Generate(); - /*-----------------------------------------------------------------------*/ /* BIND RENDER GRAPH TO RENDERER */ /*-----------------------------------------------------------------------*/ @@ -269,17 +269,6 @@ namespace SHADE worldRenderer->SetCameraDirector(cameraSystem->CreateDirector()); - // Create default materials - std::array defaultTexture = { 255, 255, 255, 255 }; - std::vector mipOffsets{}; - mipOffsets.push_back(0); - auto tex = AddTexture(4, defaultTexture.data(), 1, 1, SHTexture::TextureFormat::eR8G8B8A8Unorm, mipOffsets); - BuildTextures(); - - defaultMaterial = AddMaterial(defaultVertShader, defaultFragShader, gBufferSubpass); - defaultMaterial->SetProperty("data.textureIndex", tex->TextureArrayIndex); - - // Create debug draw pipeline debugDrawPipeline = createDebugDrawPipeline(debugDrawNode->GetRenderpass(), debugDrawSubpass); debugDrawDepthPipeline = createDebugDrawPipeline(debugDrawNodeDepth->GetRenderpass(), debugDrawDepthSubpass); @@ -321,7 +310,29 @@ namespace SHADE lightingSubSystem = resourceManager.Create(); lightingSubSystem->Init(device, descPool); + } + void SHGraphicsSystem::InitBuiltInResources(void) + { + // Create default texture + std::array defaultTextureData = { 255, 255, 255, 255 }; + std::vector mipOffsets{}; + mipOffsets.push_back(0); + defaultTexture = AddTexture(4, defaultTextureData.data(), 1, 1, SHTexture::TextureFormat::eR8G8B8A8Unorm, mipOffsets); + BuildTextures(); + + // Create default meshes + primitiveMeshes[static_cast(PrimitiveType::Cube)] = SHPrimitiveGenerator::Cube(meshLibrary); + primitiveMeshes[static_cast(PrimitiveType::Sphere)] = SHPrimitiveGenerator::Sphere(meshLibrary); + BuildMeshBuffers(); + + // Create default materials + defaultMaterial = AddMaterial + ( + defaultVertShader, defaultFragShader, + worldRenderGraph->GetNode("G-Buffer")->GetSubpass("G-Buffer Write") + ); + defaultMaterial->SetProperty("data.textureIndex", defaultTexture->TextureArrayIndex); } #ifdef SHEDITOR @@ -364,8 +375,7 @@ namespace SHADE InitBoilerplate(); InitMiddleEnd(); InitSubsystems(); - - + InitBuiltInResources(); } void SHGraphicsSystem::Exit(void) @@ -690,7 +700,7 @@ namespace SHADE SHADE::Handle SHGraphicsSystem::AddMaterialInstanceCopy(Handle materialInst) { - return resourceManager.Create(materialInst->GetBaseMaterial()); + return resourceManager.Create(materialInst->GetBaseMaterial()); } void SHGraphicsSystem::RemoveMaterialInstance(Handle materialInstance) @@ -703,26 +713,38 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ SHADE::Handle SHGraphicsSystem::AddMesh(uint32_t vertexCount, const SHMesh::VertexPosition* const positions, const SHMesh::VertexTexCoord* const texCoords, const SHMesh::VertexTangent* const tangents, const SHMesh::VertexNormal* const normals, uint32_t indexCount, const SHMesh::Index* const indices) { - return meshLibrary.AddMesh(vertexCount, positions, texCoords, tangents, normals, indexCount, indices); + return meshLibrary.AddMesh(vertexCount, positions, texCoords, tangents, normals, indexCount, indices); } void SHGraphicsSystem::RemoveMesh(Handle mesh) { - meshLibrary.RemoveMesh(mesh); + meshLibrary.RemoveMesh(mesh); } void SHGraphicsSystem::BuildMeshBuffers() { transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); device->WaitIdle(); - transferCmdBuffer->BeginRecording(); - meshLibrary.BuildBuffers(device, transferCmdBuffer); - transferCmdBuffer->EndRecording(); - graphicsQueue->SubmitCommandBuffer({ transferCmdBuffer }); + transferCmdBuffer->BeginRecording(); + meshLibrary.BuildBuffers(device, transferCmdBuffer); + transferCmdBuffer->EndRecording(); + graphicsQueue->SubmitCommandBuffer({ transferCmdBuffer }); device->WaitIdle(); transferCmdBuffer.Free(); transferCmdBuffer = {}; } + Handle SHGraphicsSystem::GetMeshPrimitive(PrimitiveType type) const noexcept + { + switch (type) + { + case PrimitiveType::Cube: + case PrimitiveType::Sphere: + return primitiveMeshes[static_cast(type)]; + default: + return {}; + } + } + /*---------------------------------------------------------------------------------*/ /* Texture Registration Functions */ /*---------------------------------------------------------------------------------*/ @@ -809,7 +831,7 @@ namespace SHADE void SHGraphicsSystem::BatcherDispatcherRoutine::Execute(double) noexcept { - auto& renderables = SHComponentManager::GetDense(); + auto& renderables = SHComponentManager::GetDense(); for (auto& renderable : renderables) { if (!renderable.HasChanged()) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index 90299444..a5a5ada0 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -58,6 +58,19 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Type Definitions */ /*---------------------------------------------------------------------------------*/ + /***********************************************************************************/ + /*! + \brief + Type of built-in primitive meshes that are available. + */ + /***********************************************************************************/ + enum class PrimitiveType + { + Cube, + Sphere + }; + static constexpr int MAX_PRIMITIVE_TYPES = 2; + /***********************************************************************************/ /*! \brief @@ -72,6 +85,7 @@ namespace SHADE void InitSceneRenderGraph (void) noexcept; void InitMiddleEnd (void) noexcept; void InitSubsystems (void) noexcept; + void InitBuiltInResources (void); #ifdef SHEDITOR void InitEditorRenderGraph (void) noexcept; @@ -81,25 +95,25 @@ 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 BatcherDispatcherRoutine final : public SHSystemRoutine { public: - BatcherDispatcherRoutine(); + BatcherDispatcherRoutine(); virtual void Execute(double dt) noexcept override final; }; @@ -152,34 +166,34 @@ 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. \param positions - Pointer to the first in a contiguous array of SHMathVec3s that define vertex - positions. - \param texCoords - Pointer to the first in a contiguous array of SHMathVec2s that define vertex - texture coordinates. - \param tangents - Pointer to the first in a contiguous array of SHMathVec3s that define vertex - tangents. - \param normals - Pointer to the first in a contiguous array of SHMathVec3s that define vertex - normals. + Pointer to the first in a contiguous array of SHMathVec3s that define vertex + positions. + \param texCoords + Pointer to the first in a contiguous array of SHMathVec2s that define vertex + texture coordinates. + \param tangents + Pointer to the first in a contiguous array of SHMathVec3s that define vertex + tangents. + \param normals + Pointer to the first in a contiguous array of SHMathVec3s that define vertex + normals. \param indexCount Number of indices in this mesh. \param indices - Pointer to the first in a contiguous array of uint32_ts that define mesh - indices. + Pointer to the first in a contiguous array of uint32_ts that define mesh + indices. - \return - Handle to the created Mesh. This is not valid to be used until a call to - BuildBuffers(). + \return + Handle to the created Mesh. This is not valid to be used until a call to + BuildBuffers(). */ /*******************************************************************************/ @@ -188,9 +202,9 @@ namespace SHADE /*! \brief - Removes a mesh from the MeshLibrary. But this does not mean that the meshes - have been removed yet. A call to "BuildBuffers()" is required to finalise all - changes. + Removes a mesh from the MeshLibrary. But this does not mean that the meshes + have been removed yet. A call to "BuildBuffers()" is required to finalise all + changes. \param mesh Handle to the mesh to remove. @@ -207,6 +221,21 @@ namespace SHADE */ /***************************************************************************/ void BuildMeshBuffers(); + /*******************************************************************************/ + /*! + + \brief + Retrieves the built-in mesh specified. + + \param type + Type of built-in mesh to retrieve. + + \returns + Handle to the mesh that was specfied. However, if an invalid type is specified, + a null Handle will be returned. + */ + /*******************************************************************************/ + Handle GetMeshPrimitive(PrimitiveType type) const noexcept; /*-----------------------------------------------------------------------------*/ /* Texture Registration Functions */ @@ -278,6 +307,18 @@ namespace SHADE */ /***************************************************************************/ Handle GetTextureHandle(SHTexture::Index textureId) const; + /***************************************************************************/ + /*! + * + \brief + Retrieves the handle to the default texture. A white 1x1 texture. + + \returns + Handle to the default texture. + + */ + /***************************************************************************/ + Handle GetDefaultTexture() const noexcept { return defaultTexture; } void PrepareResize(uint32_t newWidth, uint32_t newHeight) noexcept; void HandleResize(void) noexcept; @@ -378,6 +419,13 @@ namespace SHADE Handle debugDrawPipeline; Handle debugDrawDepthPipeline; + // Built-In Textures + Handle defaultTexture; + + // Built-In Meshes + std::array, MAX_PRIMITIVE_TYPES> primitiveMeshes; + + // Render Graphs Handle worldRenderGraph; // Sub systems From 7bfe459c02638d86674624078550fc96d4e08508 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Sat, 5 Nov 2022 00:13:24 +0800 Subject: [PATCH 05/59] Called assimp git pull from root bat directly instead of calling bat inside dependency --- Dependencies.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dependencies.bat b/Dependencies.bat index dcd4750e..44185ff8 100644 --- a/Dependencies.bat +++ b/Dependencies.bat @@ -59,7 +59,7 @@ if %_e%==3 (goto :done) else (goto :ModelCompiler) echo -----------------------ModelCompiler---------------------------- rmdir "Dependencies/ModelCompiler" /S /Q git clone https://github.com/SHADE-DP/ModelCompiler.git "Dependencies/ModelCompiler" -Dependencies/ModelCompiler/Dependencies.bat +git clone https://github.com/SHADE-DP/assimp.git "Dependencies/ModelCompiler/Dependencies/assimp" if %_e%==4 (goto :done) else (goto :spdlog) @REM :ktx From 06afd384af2cb63da4373947971ee84d8dffac31 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Sat, 5 Nov 2022 14:56:52 +0800 Subject: [PATCH 06/59] Scenes are now reloaded and scripts are no longer lost when building scripts --- .../src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp index af2d5517..d1e359b6 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp @@ -120,12 +120,16 @@ namespace SHADE if (ImGui::Selectable("Build Scripts - Debug")) { auto* scriptEngine = static_cast(SHSystemManager::GetSystem()); + SHSerialization::SerializeSceneToFile(SHSceneManager::GetCurrentSceneAssetID()); scriptEngine->BuildScriptAssembly(true, true); + SHSceneManager::RestartScene(SHSceneManager::GetCurrentSceneAssetID()); } if (ImGui::Selectable("Build Scripts - Release")) { auto* scriptEngine = static_cast(SHSystemManager::GetSystem()); - scriptEngine->BuildScriptAssembly(false, true); + SHSerialization::SerializeSceneToFile(SHSceneManager::GetCurrentSceneAssetID()); + scriptEngine->BuildScriptAssembly(false, true); + SHSceneManager::RestartScene(SHSceneManager::GetCurrentSceneAssetID()); } ImGui::EndMenu(); } From 04e2c255b0d6c8f3baa82ca7db7ade914906edc5 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Sat, 5 Nov 2022 15:34:56 +0800 Subject: [PATCH 07/59] Build script options are now disabled when in play or pause mode --- .../src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp index d1e359b6..c18f0c8c 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp @@ -117,6 +117,7 @@ namespace SHADE auto* scriptEngine = static_cast(SHSystemManager::GetSystem()); scriptEngine->GenerateScriptsCsProjFile(); } + ImGui::BeginDisabled(SHSystemManager::GetSystem()->editorState != SHEditor::State::STOP); if (ImGui::Selectable("Build Scripts - Debug")) { auto* scriptEngine = static_cast(SHSystemManager::GetSystem()); @@ -131,6 +132,7 @@ namespace SHADE scriptEngine->BuildScriptAssembly(false, true); SHSceneManager::RestartScene(SHSceneManager::GetCurrentSceneAssetID()); } + ImGui::EndDisabled(); ImGui::EndMenu(); } From b9996c7b51bf73f7108c362bf5d7b15583c4b4bb Mon Sep 17 00:00:00 2001 From: Glence Date: Sat, 5 Nov 2022 17:44:34 +0800 Subject: [PATCH 08/59] made rb a properties --- TempScriptsFolder/PlayerController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TempScriptsFolder/PlayerController.cs b/TempScriptsFolder/PlayerController.cs index bcdf24d1..86ba7c98 100644 --- a/TempScriptsFolder/PlayerController.cs +++ b/TempScriptsFolder/PlayerController.cs @@ -15,7 +15,7 @@ public class PlayerController : Script TOTAL } - public RigidBody rb; + public RigidBody rb { get; set; } private Transform tranform; private Camera cam; private PickAndThrow pat; From de38b29f250f3628a6979dfb583a9b86724975b8 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Sat, 5 Nov 2022 18:15:18 +0800 Subject: [PATCH 09/59] small fixes for ms2 submission --- Assets/Scenes/M2Scene.shade | 58 ++++++++++++++----- .../src/Serialization/SHYAMLConverters.h | 2 +- 2 files changed, 45 insertions(+), 15 deletions(-) diff --git a/Assets/Scenes/M2Scene.shade b/Assets/Scenes/M2Scene.shade index 60dbb5f9..443d4a87 100644 --- a/Assets/Scenes/M2Scene.shade +++ b/Assets/Scenes/M2Scene.shade @@ -50,7 +50,7 @@ Colliders: - Is Trigger: false Type: Box - Half Extents: {x: 0.00427246094, y: 0.000122070312, z: 0.00427246094} + Half Extents: {x: 24.7399445, y: 0.25, z: 8.75} Friction: 0.400000006 Bounciness: 0 Density: 1 @@ -85,12 +85,28 @@ Colliders: - Is Trigger: false Type: Box - Half Extents: {x: 0.000244140625, y: 0.000244140625, z: 0.000244140625} + Half Extents: {x: 1, y: 1, z: 1} Friction: 0.400000006 Bounciness: 0 Density: 1 Position Offset: {x: 0, y: 0.5, z: 0} - Scripts: ~ + Scripts: + - Type: PlayerController + drag: 2 + currentState: 0 + maxMoveVel: 2 + moveForce: 50 + sprintMultiplier: 2 + rotationFactorPerFrame: 1 + maxJumpHeight: 4 + maxJumpTime: 0.75 + fallMultipler: 2 + lightMultiper: 0.75 + mediumMultiper: 0.5 + heavyMultiper: 0.25 + - Type: PickAndThrow + throwForce: [200, 300, 200] + item: 5 - EID: 3 Name: Default IsActive: true @@ -110,7 +126,12 @@ Translate: {x: 0, y: 0, z: 0} Rotate: {x: 0, y: 0, z: 0} Scale: {x: 1, y: 1, z: 1} - Scripts: ~ + Scripts: + - Type: SHADE_Scripting.ThirdPersonCamera + armLength: 2 + turnSpeedPitch: 0.300000012 + turnSpeedYaw: 0.5 + pitchClamp: 45 - EID: 9 Name: Default IsActive: true @@ -135,7 +156,7 @@ Scale: {x: 2, y: 2, z: 2} Renderable Component: Mesh: 144838771 - Material: 126974645 + Material: 123745521 RigidBody Component: Type: Dynamic Mass: 1 @@ -153,19 +174,21 @@ Colliders: - Is Trigger: false Type: Box - Half Extents: {x: 0.000244140625, y: 0.000244140625, z: 0.000244140625} + 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: 0.00048828125, y: 0.00048828125, z: 0.00048828125} + 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: ~ + Scripts: + - Type: Item + currCategory: 0 - EID: 6 Name: AI IsActive: true @@ -174,7 +197,7 @@ Transform Component: Translate: {x: -8, y: -2, z: 2.5} Rotate: {x: 0, y: 0, z: 0} - Scale: {x: 2, y: 2, z: 2} + Scale: {x: 1, y: 1, z: 1} Renderable Component: Mesh: 149697411 Material: 126974645 @@ -195,21 +218,28 @@ Colliders: - Is Trigger: false Type: Box - Half Extents: {x: 0.000244140625, y: 0.000244140625, z: 0.000244140625} + 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: ~ + Scripts: + - Type: AIPrototype + movementForceMultiplier: 100 + patrolSpeed: 0.400000006 + chaseSpeed: 0.800000012 + distanceToCapture: 1.20000005 + distanceToStartChase: 2 + distanceToEndChase: 2.5 - EID: 7 Name: Default IsActive: true NumberOfChildren: 0 Components: Transform Component: - Translate: {x: 3, y: -1, z: -1} - Rotate: {x: 0, y: 0, z: 0} - Scale: {x: 5, y: 5, z: 5} + Translate: {x: 0, y: -16.8647861, z: -14.039052} + Rotate: {x: -0, y: 0, z: -0} + Scale: {x: 28.1434975, y: 28.1434975, z: 28.1434975} Renderable Component: Mesh: 149697411 Material: 126974645 diff --git a/SHADE_Engine/src/Serialization/SHYAMLConverters.h b/SHADE_Engine/src/Serialization/SHYAMLConverters.h index af0b280b..d4b97244 100644 --- a/SHADE_Engine/src/Serialization/SHYAMLConverters.h +++ b/SHADE_Engine/src/Serialization/SHYAMLConverters.h @@ -168,7 +168,7 @@ namespace YAML case SHCollider::Type::BOX: { if (node[HalfExtents].IsDefined()) - rhs.SetBoundingBox(node[HalfExtents].as()); + rhs.SetBoundingBox(node[HalfExtents].as() * 2.0f); } break; case SHCollider::Type::SPHERE: From 4bd9f0817a9b59b545908857f4feeea1ce5d3adf Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 7 Nov 2022 12:55:18 +0800 Subject: [PATCH 10/59] Buffers are now tagged as buffers for debug labels --- SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp | 3 ++- SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp | 2 +- SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.hpp | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp index 63f580b9..37dd2c74 100644 --- a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp +++ b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp @@ -410,7 +410,8 @@ namespace SHADE auto [tempBuffer, allocInfo] = createBuffer(sizeStored); vkBuffer = tempBuffer; - SET_VK_OBJ_NAME(*device, vk::ObjectType::eBuffer, vkBuffer, name); + if (!name.empty()) + SET_VK_OBJ_NAME(device, vk::ObjectType::eBuffer, vkBuffer, "[Buffer] " + name); // This probably means that a HOST_CACHED memory type is used on allocation if (allocFlags & VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT) diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp index 35c104ee..20332f1d 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp @@ -220,7 +220,7 @@ namespace SHADE else { SHVulkanDebugUtil::ReportVkSuccess("Successfully created a Logical Device. "); - SET_VK_OBJ_NAME((*this), vk::ObjectType::eDevice, vkLogicalDevice, "Logical Device"); + SET_VK_OBJ_NAME(this, vk::ObjectType::eDevice, vkLogicalDevice, "Logical Device"); } InitializeVMA(); diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.hpp b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.hpp index dd7ff609..d72ab09e 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.hpp +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.hpp @@ -40,7 +40,7 @@ namespace SHADE /*-------------------------------------------------------------------------------------*/ #ifdef _DEBUG #define SET_VK_OBJ_NAME(DEVICE, OBJ_TYPE, OBJ_HDL, OBJ_NAME) \ - (DEVICE).SetVulkanObjectName(OBJ_TYPE, OBJ_HDL, OBJ_NAME); + DEVICE->SetVulkanObjectName(OBJ_TYPE, OBJ_HDL, OBJ_NAME); #else #define SET_VK_OBJ_NAME(DEVICE, OBJ_TYPE, OBJ_HDL, OBJ_NAME) #endif From 782db1e2a428aed9f794c3b6aed29c253e145e58 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 7 Nov 2022 13:22:16 +0800 Subject: [PATCH 11/59] Added debug labels for Renderpasses --- SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp | 6 +++--- .../src/Graphics/RenderGraph/SHRenderGraphNode.cpp | 7 +++++-- SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h | 5 ++++- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index 66dc6a0f..9c4e0d65 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -471,9 +471,9 @@ namespace SHADE } } - nodes.emplace_back(resourceManager->Create(renderGraphStorage, std::move(descInitParams), std::move(predecessors))); - nodeIndexing.emplace(nodeName, static_cast(nodes.size()) - 1u); - return nodes.at(nodeIndexing[nodeName]); + auto node = nodes.emplace_back(resourceManager->Create(nodeName, renderGraphStorage, std::move(descInitParams), std::move(predecessors))); + nodeIndexing.emplace(std::move(nodeName), static_cast(nodes.size()) - 1u); + return node; } /***************************************************************************/ diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp index 12f0e246..9aa42c0a 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp @@ -25,6 +25,7 @@ namespace SHADE void SHRenderGraphNode::CreateRenderpass(void) noexcept { renderpass = graphStorage->logicalDevice->CreateRenderpass(attachmentDescriptions, spDescs, spDeps); + SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eRenderPass, renderpass->GetVkRenderpass(), "[RenderPass] " + name); } /***************************************************************************/ @@ -116,7 +117,7 @@ namespace SHADE */ /***************************************************************************/ - SHRenderGraphNode::SHRenderGraphNode(Handle renderGraphStorage, std::vector attDescInitParams, std::vector> predecessors) noexcept + SHRenderGraphNode::SHRenderGraphNode(std::string nodeName, Handle renderGraphStorage, std::vector attDescInitParams, std::vector> predecessors) noexcept : graphStorage{ renderGraphStorage} , renderpass{} , framebuffers{} @@ -128,6 +129,7 @@ namespace SHADE , executed{ false } , configured{ false } , nodeComputes{} + , name { std::move(nodeName) } { // pipeline library initialization pipelineLibrary.Init(graphStorage->logicalDevice); @@ -189,6 +191,7 @@ namespace SHADE , spDescs{ std::move(rhs.spDescs) } , spDeps{ std::move(rhs.spDeps) } , nodeComputes{ std::move(rhs.nodeComputes) } + , name { std::move(rhs.name) } { rhs.renderpass = {}; @@ -213,7 +216,7 @@ namespace SHADE spDescs = std::move(rhs.spDescs); spDeps = std::move(rhs.spDeps); nodeComputes = std::move(rhs.nodeComputes); - + name = std::move(rhs.name); rhs.renderpass = {}; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h index 695d1c31..33868f5e 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h @@ -78,8 +78,11 @@ namespace SHADE //! Whether or not the node has been configured already or not bool configured; + //! Manages batching for this RenderPass SHBatcher batcher; + //! Name of this node + std::string name; /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER FUNCTIONS */ @@ -92,7 +95,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* CTORS AND DTORS */ /*-----------------------------------------------------------------------*/ - SHRenderGraphNode(Handle renderGraphStorage, std::vector attDescInitParams, std::vector> predecessors) noexcept; + SHRenderGraphNode(std::string nodeName, Handle renderGraphStorage, std::vector attDescInitParams, std::vector> predecessors) noexcept; SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept; SHRenderGraphNode& operator= (SHRenderGraphNode&& rhs) noexcept; From fb37742ee0e31c8e291a46805750279c0b81a7d8 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 7 Nov 2022 13:28:49 +0800 Subject: [PATCH 12/59] Staging Buffers are now labeled --- SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp index 37dd2c74..803c53be 100644 --- a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp +++ b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp @@ -220,6 +220,7 @@ namespace SHADE // then assign it to the hpp version stagingBuffer = tempBuffer; + SET_VK_OBJ_NAME(device, vk::ObjectType::eBuffer, stagingBuffer, "[Buffer] Staging - " + name); // Just map, copy then unmap void* stagingBufferMappedPtr = nullptr; From 0bda3d515188bd81b810ae11bf3c8d73e0b3e0fe Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 7 Nov 2022 14:08:19 +0800 Subject: [PATCH 13/59] Added labels for resources of Mesh and Texture libraries --- .../src/Graphics/Devices/SHVkLogicalDevice.h | 14 ++++++++++++-- .../src/Graphics/Devices/SHVkLogicalDevice.hpp | 15 +++++++++++++++ .../MiddleEnd/Interface/SHMeshLibrary.cpp | 15 ++++++++++----- .../MiddleEnd/Textures/SHTextureLibrary.cpp | 4 ++++ 4 files changed, 41 insertions(+), 7 deletions(-) diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h index 827f12b3..158c20b2 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h @@ -208,8 +208,8 @@ namespace SHADE /*-----------------------------------------------------------------------*/ #ifdef _DEBUG /// - /// Sets a Vulkan object's name for debugging purposes. This function will not be - /// compiled outsied of Debug configurations. Hence, it is advised to use provided + /// Sets a Vulkan HPP object's name for debugging purposes. This function will not be + /// compiled outside of Debug configurations. Hence, it is advised to use provided /// macro function SET_VK_OBJ_NAME() instead of using this function directly. /// /// Type of the object. @@ -217,6 +217,16 @@ namespace SHADE /// Object's name. template inline void SetVulkanObjectName(vk::ObjectType objType, T objHandle, const std::string& objName); + /// + /// Sets a Vulkan object's name for debugging purposes. This function will not be + /// compiled outside of Debug configurations. Hence, it is advised to use provided + /// macro function SET_VK_OBJ_NAME_VK() instead of using this function directly. + /// + /// Type of the object. + /// Handle to the Vulkan Object to name. + /// Object's name. + template + inline void SetVulkanObjectNameVk(vk::ObjectType objType, T objVkHandle, const std::string& objName); #endif /*-----------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.hpp b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.hpp index d72ab09e..e8de27fb 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.hpp +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.hpp @@ -32,6 +32,18 @@ namespace SHADE info.pObjectName = objName.data(); vkLogicalDevice.setDebugUtilsObjectNameEXT(info); } + template + void SHVkLogicalDevice::SetVulkanObjectNameVk(vk::ObjectType objType, T objVkHandle, const std::string& objName) + { + if (objName.empty()) + return; + + vk::DebugUtilsObjectNameInfoEXT info; + info.objectType = objType; + info.objectHandle = (uint64_t) objVkHandle; + info.pObjectName = objName.data(); + vkLogicalDevice.setDebugUtilsObjectNameEXT(info); + } #endif } @@ -41,6 +53,9 @@ namespace SHADE #ifdef _DEBUG #define SET_VK_OBJ_NAME(DEVICE, OBJ_TYPE, OBJ_HDL, OBJ_NAME) \ DEVICE->SetVulkanObjectName(OBJ_TYPE, OBJ_HDL, OBJ_NAME); +#define SET_VK_OBJ_NAME_VK(DEVICE, OBJ_TYPE, OBJ_HDL, OBJ_NAME) \ + DEVICE->SetVulkanObjectNameVk(OBJ_TYPE, OBJ_HDL, OBJ_NAME); #else #define SET_VK_OBJ_NAME(DEVICE, OBJ_TYPE, OBJ_HDL, OBJ_NAME) +#define SET_VK_OBJ_NAME_VK(DEVICE, OBJ_TYPE, OBJ_HDL, OBJ_NAME) #endif diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMeshLibrary.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMeshLibrary.cpp index 3474fea3..d34c1b7d 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMeshLibrary.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMeshLibrary.cpp @@ -165,35 +165,40 @@ namespace SHADE device, cmdBuffer, vertPosBuffer, vertPosStorage.data(), static_cast(vertPosStorage.size()) * sizeof(SHMesh::VertexPosition), - BuffUsage::eVertexBuffer + BuffUsage::eVertexBuffer, + "Mesh Library Vertex Positions" ); SHVkUtil::EnsureBufferAndCopyData ( device, cmdBuffer, vertTexCoordBuffer, vertTexCoordStorage.data(), static_cast(vertTexCoordStorage.size()) * sizeof(SHMesh::VertexTexCoord), - BuffUsage::eVertexBuffer + BuffUsage::eVertexBuffer, + "Mesh Library Vertex TexCoords" ); SHVkUtil::EnsureBufferAndCopyData ( device, cmdBuffer, vertTangentBuffer, vertTangentStorage.data(), static_cast(vertTangentStorage.size()) * sizeof(SHMesh::VertexTangent), - BuffUsage::eVertexBuffer + BuffUsage::eVertexBuffer, + "Mesh Library Vertex Tangents" ); SHVkUtil::EnsureBufferAndCopyData ( device, cmdBuffer, vertNormalBuffer, vertNormalStorage.data(), static_cast(vertNormalStorage.size()) * sizeof(SHMesh::VertexNormal), - BuffUsage::eVertexBuffer + BuffUsage::eVertexBuffer, + "Mesh Library Vertex Normals" ); SHVkUtil::EnsureBufferAndCopyData ( device, cmdBuffer, indexBuffer, indexStorage.data(), static_cast(indexStorage.size()) * sizeof(SHMesh::Index), - BuffUsage::eIndexBuffer + BuffUsage::eIndexBuffer, + "Mesh Library Indices" ); isDirty = false; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp index 3b6448fa..9c330b9f 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp @@ -23,6 +23,7 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h" #include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" #include "Graphics/Images/SHVkImage.h" +#include "Graphics/Images/SHVkImageView.h" #include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" #include "Assets/Asset Types/SHTextureAsset.h" @@ -150,6 +151,9 @@ namespace SHADE texOrder.emplace_back(job.TextureHandle); combinedImageSamplers.emplace_back(std::make_tuple(job.TextureHandle->ImageView, job.Sampler, vk::ImageLayout::eShaderReadOnlyOptimal)); job.TextureHandle->TextureArrayIndex = static_cast(texOrder.size()) - 1U; + + SET_VK_OBJ_NAME(device, vk::ObjectType::eImage, job.Image->GetVkImage(), "[Image] Texture Library Texture #" + std::to_string(job.TextureHandle->TextureArrayIndex)); + SET_VK_OBJ_NAME(device, vk::ObjectType::eImageView, job.TextureHandle->ImageView->GetImageView(), "[ImageView] Texture Library Texture #" + std::to_string(job.TextureHandle->TextureArrayIndex)); } addJobs.clear(); From 44ae6d0a8f6138de1f033fd48520323652a311de Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 7 Nov 2022 17:28:03 +0800 Subject: [PATCH 14/59] Removed unused descriptor sets in SHGraphicsGlobalData --- .../src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp | 1 - .../src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h | 3 --- 2 files changed, 4 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp index 9717889d..155097a5 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp @@ -13,7 +13,6 @@ namespace SHADE /* Static Definitions */ /*-----------------------------------------------------------------------------------*/ std::vector> SHGraphicsGlobalData::globalDescSetLayouts; - Handle SHGraphicsGlobalData::globalDescSets; SHVertexInputState SHGraphicsGlobalData::defaultVertexInputState; Handle SHGraphicsGlobalData::dummyPipelineLayout; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h index 344c2616..439acba5 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h @@ -17,9 +17,6 @@ namespace SHADE //! Global descriptor set layouts. Used to allocate descriptor sets static std::vector> globalDescSetLayouts; - //! Global Descriptor sets - static Handle globalDescSets; - //! Default vertex input state (used by everything). static SHVertexInputState defaultVertexInputState; From 4e02f6413338dce0472737549a1a140b4af7ec79 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Mon, 7 Nov 2022 18:06:43 +0800 Subject: [PATCH 15/59] Fixed bug where duplicate triggers were caught due to swapped entity IDs --- .../src/Math/Transform/SHTransformSystem.cpp | 6 ++--- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 7 +++--- SHADE_Engine/src/Physics/SHPhysicsSystem.h | 22 +++++++++---------- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp index f000aa5b..94c133dd 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp +++ b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp @@ -231,12 +231,12 @@ namespace SHADE tf.worldRotation = tf.localRotation + (parent ? parent->GetLocalRotation() : SHVec3::Zero); // Set the orientation - // Wrap rotations between -360 and 360 and convert to radians + // Wrap rotations between -720 and 720 and convert to radians SHVec3 worldRotRad, localRotRad; for (size_t i = 0; i < SHVec3::SIZE; ++i) { - worldRotRad[i] = SHMath::Wrap(tf.worldRotation[i], -SHMath::TWO_PI, SHMath::TWO_PI); - localRotRad[i] = SHMath::Wrap(tf.localRotation[i], -SHMath::TWO_PI, SHMath::TWO_PI); + worldRotRad[i] = SHMath::Wrap(tf.worldRotation[i], -2.0f * SHMath::TWO_PI, 2.0f * SHMath::TWO_PI); + localRotRad[i] = SHMath::Wrap(tf.localRotation[i], -2.0f * SHMath::TWO_PI, 2.0f * SHMath::TWO_PI); } tf.world.orientation = SHQuaternion::FromEuler(worldRotRad); diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index bdee8ba1..66c28958 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -605,7 +605,6 @@ namespace SHADE if (rigidBodyComponent != nullptr) { - if (rigidBodyComponent->GetType() == SHRigidBodyComponent::Type::STATIC) continue; @@ -658,8 +657,10 @@ namespace SHADE { const auto IT = std::ranges::find_if(container.begin(), container.end(), [&](const SHCollisionEvent& e) { - const bool ENTITY_MATCH = e.value[0] == collisionEvent.value[0]; - const bool COLLIDERS_MATCH = e.value[1] == collisionEvent.value[1]; + const bool ENTITY_MATCH = (e.ids[0] == collisionEvent.ids[0] && e.ids[1] == collisionEvent.ids[1]) + || (e.ids[0] == collisionEvent.ids[1] && e.ids[1] == collisionEvent.ids[0]); + const bool COLLIDERS_MATCH = (e.ids[2] == collisionEvent.ids[2] && e.ids[3] == collisionEvent.ids[3]) + || (e.ids[2] == collisionEvent.ids[3] && e.ids[3] == collisionEvent.ids[2]); return ENTITY_MATCH && COLLIDERS_MATCH; }); diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/SHPhysicsSystem.h index 05e6e57e..0dd2754e 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.h @@ -183,24 +183,24 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ - SHPhysicsObject* EnsurePhysicsObject (EntityID entityID) noexcept; - SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept; - void DestroyPhysicsObject (EntityID entityID) noexcept; + SHPhysicsObject* EnsurePhysicsObject (EntityID entityID) noexcept; + SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept; + void DestroyPhysicsObject (EntityID entityID) noexcept; - static void SyncActiveStates (SHPhysicsObject& physicsObject, bool componentActive) noexcept; - void SyncTransforms () noexcept; + static void SyncActiveStates (SHPhysicsObject& physicsObject, bool componentActive) noexcept; + void SyncTransforms () noexcept; - static void UpdateEventContainers (const SHCollisionEvent& collisionEvent, CollisionEvents& container) noexcept; - void ClearInvalidCollisions () noexcept; + static void UpdateEventContainers (const SHCollisionEvent& collisionEvent, CollisionEvents& container) noexcept; + void ClearInvalidCollisions () noexcept; - SHEventHandle AddPhysicsComponent (SHEventPtr addComponentEvent); - SHEventHandle RemovePhysicsComponent (SHEventPtr removeComponentEvent); - SHEventHandle ResetWorld (SHEventPtr editorStopEvent); + SHEventHandle AddPhysicsComponent (SHEventPtr addComponentEvent); + SHEventHandle RemovePhysicsComponent (SHEventPtr removeComponentEvent); + SHEventHandle ResetWorld (SHEventPtr editorStopEvent); template || std::is_same_v>> - SHCollisionEvent GenerateCollisionEvent (const RP3DCollisionPair& cp) noexcept; + SHCollisionEvent GenerateCollisionEvent (const RP3DCollisionPair& cp) noexcept; }; } // namespace SHADE From 70dcad13138a186353d988d950612af720d4f133 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Mon, 7 Nov 2022 18:19:39 +0800 Subject: [PATCH 16/59] Changed Collider to CollisionShape for improved clarity --- SHADE_Application/src/Scenes/SBTestScene.cpp | 18 ++--- .../Inspector/SHEditorComponentView.hpp | 16 ++--- .../Components/SHColliderComponent.cpp | 26 ++++---- .../Physics/Components/SHColliderComponent.h | 18 ++--- .../{SHCollider.cpp => SHCollisionShape.cpp} | 66 +++++++++---------- .../{SHCollider.h => SHCollisionShape.h} | 14 ++-- SHADE_Engine/src/Physics/SHPhysicsObject.cpp | 12 ++-- SHADE_Engine/src/Physics/SHPhysicsObject.h | 2 +- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 8 +-- SHADE_Engine/src/Physics/SHPhysicsSystem.h | 2 +- SHADE_Engine/src/Physics/SHPhysicsUtils.cpp | 8 +-- SHADE_Engine/src/Physics/SHPhysicsUtils.h | 6 +- .../src/Serialization/SHYAMLConverters.h | 46 ++++++------- SHADE_Managed/src/Components/Collider.cxx | 10 +-- SHADE_Managed/src/Components/Collider.h++ | 6 +- 15 files changed, 129 insertions(+), 129 deletions(-) rename SHADE_Engine/src/Physics/{SHCollider.cpp => SHCollisionShape.cpp} (75%) rename SHADE_Engine/src/Physics/{SHCollider.h => SHCollisionShape.h} (91%) diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index 02977f19..ecacdc79 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -114,8 +114,8 @@ namespace Sandbox racoonTransform.SetWorldPosition({ -3.0f, -2.0f, -5.0f }); racoonCollider.AddBoundingBox(); - racoonCollider.GetCollider(0).SetPositionOffset(SHVec3(0.0f,0.5f,0.0f)); - racoonCollider.GetCollider(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f)); + racoonCollider.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f,0.5f,0.0f)); + racoonCollider.GetCollisionShape(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f)); auto racoonItemLocation = SHEntityManager::CreateEntity(); auto& racoonItemLocationTransform = *SHComponentManager::GetComponent_s(racoonItemLocation); @@ -140,13 +140,13 @@ namespace Sandbox itemCollider.AddBoundingBox(); itemCollider.AddBoundingBox(SHVec3(2.0f,2.0f,2.0f)); - itemCollider.GetCollider(1).SetIsTrigger(true); + itemCollider.GetCollisionShape(1).SetIsTrigger(true); - itemCollider.GetCollider(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f)); - itemCollider.GetCollider(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f)); + itemCollider.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f)); + itemCollider.GetCollisionShape(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f)); - itemCollider.GetCollider(1).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f)); - itemCollider.GetCollider(1).SetBoundingBox(SHVec3(1.0f, 1.0f, 1.0f)); + itemCollider.GetCollisionShape(1).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f)); + itemCollider.GetCollisionShape(1).SetBoundingBox(SHVec3(1.0f, 1.0f, 1.0f)); itemRigidBody.SetInterpolate(false); itemRigidBody.SetFreezeRotationX(true); @@ -168,8 +168,8 @@ namespace Sandbox AITransform.SetWorldPosition({ -8.0f, -2.0f, 2.5f }); AICollider.AddBoundingBox(); - AICollider.GetCollider(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f)); - AICollider.GetCollider(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f)); + AICollider.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f)); + AICollider.GetCollisionShape(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f)); AIRigidBody.SetInterpolate(false); AIRigidBody.SetFreezeRotationX(true); diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index 72c38d6f..d7ae56c1 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -234,21 +234,21 @@ namespace SHADE { DrawContextMenu(component); - auto& colliders = component->GetColliders(); + auto& colliders = component->GetCollisionShapes(); int const size = static_cast(colliders.size()); - ImGui::BeginChild("Colliders", { 0.0f, colliders.empty() ? 1.0f : 250.0f }, true); + ImGui::BeginChild("Collision Shapes", { 0.0f, colliders.empty() ? 1.0f : 250.0f }, true); std::optional colliderToDelete{ std::nullopt }; for (int i{}; i < size; ++i) { ImGui::PushID(i); - SHCollider* collider = &component->GetCollider(i); + SHCollisionShape* collider = &component->GetCollisionShape(i); auto cursorPos = ImGui::GetCursorPos(); //collider->IsTrigger - if (collider->GetType() == SHCollider::Type::BOX) + if (collider->GetType() == SHCollisionShape::Type::BOX) { - SHEditorWidgets::BeginPanel(std::format("{} Box Collider #{}", ICON_FA_CUBE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y }); + SHEditorWidgets::BeginPanel(std::format("{} Box #{}", ICON_FA_CUBE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y }); SHEditorWidgets::CheckBox("Is Trigger", [collider]() {return collider->IsTrigger(); }, [collider](bool const& value) {collider->SetIsTrigger(value); }, "Is Trigger"); auto box = reinterpret_cast(collider->GetShape()); SHEditorWidgets::DragVec3 @@ -257,9 +257,9 @@ namespace SHADE [box, transformComponent] { return (box->GetHalfExtents() * 2.0f) / transformComponent->GetWorldScale(); }, [collider](SHVec3 const& vec) { collider->SetBoundingBox(vec); }); } - else if (collider->GetType() == SHCollider::Type::SPHERE) + else if (collider->GetType() == SHCollisionShape::Type::SPHERE) { - SHEditorWidgets::BeginPanel(std::format("{} Sphere Collider #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y }); + SHEditorWidgets::BeginPanel(std::format("{} Sphere #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y }); SHEditorWidgets::CheckBox("Is Trigger", [collider]() {return collider->IsTrigger(); }, [collider](bool const& value) {collider->SetIsTrigger(value); }, "Is Trigger"); auto sphere = reinterpret_cast(collider->GetShape()); SHEditorWidgets::DragFloat @@ -273,7 +273,7 @@ namespace SHADE }, [collider](float const& value) { collider->SetBoundingSphere(value); }); } - else if (collider->GetType() == SHCollider::Type::CAPSULE) + else if (collider->GetType() == SHCollisionShape::Type::CAPSULE) { } diff --git a/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp b/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp index c7e327fa..af3965fb 100644 --- a/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp +++ b/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp @@ -48,17 +48,17 @@ namespace SHADE return orientation.ToEuler(); } - const SHColliderComponent::Colliders& SHColliderComponent::GetColliders() const noexcept + const SHColliderComponent::CollisionShapes& SHColliderComponent::GetCollisionShapes() const noexcept { - return colliders; + return collisionShapes; } - SHCollider& SHColliderComponent::GetCollider(int index) + SHCollisionShape& SHColliderComponent::GetCollisionShape(int index) { - if (index < 0 || static_cast(index) >= colliders.size()) + if (index < 0 || static_cast(index) >= collisionShapes.size()) throw std::invalid_argument("Out-of-range access!"); - return colliders[index]; + return collisionShapes[index]; } /*-----------------------------------------------------------------------------------*/ @@ -83,9 +83,9 @@ namespace SHADE return nullptr; } - static constexpr auto TYPE = SHCollider::Type::BOX; + static constexpr auto TYPE = SHCollisionShape::Type::BOX; - auto& collider = colliders.emplace_back(SHCollider{ GetEID(), TYPE }); + auto& collider = collisionShapes.emplace_back(SHCollisionShape{ GetEID(), TYPE }); collider.entityID = GetEID(); collider.SetPositionOffset(posOffset); @@ -105,9 +105,9 @@ namespace SHADE return nullptr; } - static constexpr auto TYPE = SHCollider::Type::SPHERE; + static constexpr auto TYPE = SHCollisionShape::Type::SPHERE; - auto& collider = colliders.emplace_back(SHCollider{ GetEID(), TYPE }); + auto& collider = collisionShapes.emplace_back(SHCollisionShape{ GetEID(), TYPE }); collider.entityID = GetEID(); collider.SetPositionOffset(posOffset); @@ -121,12 +121,12 @@ namespace SHADE void SHColliderComponent::RemoveCollider(int index) { - if (index < 0 || static_cast(index) >= colliders.size()) + if (index < 0 || static_cast(index) >= collisionShapes.size()) throw std::invalid_argument("Out-of-range access!"); int idx = 0; - auto it = colliders.begin(); - for (; it != colliders.end(); ++it) + auto it = collisionShapes.begin(); + for (; it != collisionShapes.end(); ++it) { if (idx == index) break; @@ -134,7 +134,7 @@ namespace SHADE ++idx; } - it = colliders.erase(it); + it = collisionShapes.erase(it); // Notify Physics System if (!system) diff --git a/SHADE_Engine/src/Physics/Components/SHColliderComponent.h b/SHADE_Engine/src/Physics/Components/SHColliderComponent.h index 7ce272a9..ac5e7528 100644 --- a/SHADE_Engine/src/Physics/Components/SHColliderComponent.h +++ b/SHADE_Engine/src/Physics/Components/SHColliderComponent.h @@ -14,7 +14,7 @@ // Project Headers #include "ECS_Base/Components/SHComponent.h" -#include "Physics/SHCollider.h" +#include "Physics/SHCollisionShape.h" #include "Math/Geometry/SHBoundingBox.h" #include "Math/Geometry/SHBoundingSphere.h" @@ -43,7 +43,7 @@ namespace SHADE /* Type Definitions */ /*---------------------------------------------------------------------------------*/ - using Colliders = std::vector; + using CollisionShapes = std::vector; public: @@ -67,14 +67,14 @@ namespace SHADE /* Getter Functions */ /*---------------------------------------------------------------------------------*/ - [[nodiscard]] bool HasChanged () const noexcept; + [[nodiscard]] bool HasChanged () const noexcept; - [[nodiscard]] const SHVec3& GetPosition () const noexcept; - [[nodiscard]] const SHQuaternion& GetOrientation () const noexcept; - [[nodiscard]] SHVec3 GetRotation () const noexcept; + [[nodiscard]] const SHVec3& GetPosition () const noexcept; + [[nodiscard]] const SHQuaternion& GetOrientation () const noexcept; + [[nodiscard]] SHVec3 GetRotation () const noexcept; - [[nodiscard]] const Colliders& GetColliders () const noexcept; - [[nodiscard]] SHCollider& GetCollider (int index); + [[nodiscard]] const CollisionShapes& GetCollisionShapes() const noexcept; + [[nodiscard]] SHCollisionShape& GetCollisionShape (int index); /*---------------------------------------------------------------------------------*/ /* Function Members */ @@ -98,7 +98,7 @@ namespace SHADE SHVec3 position; SHQuaternion orientation; - Colliders colliders; + CollisionShapes collisionShapes; RTTR_ENABLE() }; diff --git a/SHADE_Engine/src/Physics/SHCollider.cpp b/SHADE_Engine/src/Physics/SHCollisionShape.cpp similarity index 75% rename from SHADE_Engine/src/Physics/SHCollider.cpp rename to SHADE_Engine/src/Physics/SHCollisionShape.cpp index 6d455d67..78ec36f9 100644 --- a/SHADE_Engine/src/Physics/SHCollider.cpp +++ b/SHADE_Engine/src/Physics/SHCollisionShape.cpp @@ -11,7 +11,7 @@ #include // Primary Header -#include "SHCollider.h" +#include "SHCollisionShape.h" // Project Headers #include "Math/Geometry/SHBoundingBox.h" #include "Math/Geometry/SHBoundingSphere.h" @@ -25,7 +25,7 @@ namespace SHADE /* Constructors & Destructor Definitions */ /*-----------------------------------------------------------------------------------*/ - SHCollider::SHCollider(EntityID eid, Type colliderType, const SHPhysicsMaterial& physicsMaterial) + SHCollisionShape::SHCollisionShape(EntityID eid, Type colliderType, const SHPhysicsMaterial& physicsMaterial) : type { colliderType } , entityID { eid } , isTrigger { false } @@ -49,7 +49,7 @@ namespace SHADE } } - SHCollider::SHCollider(const SHCollider& rhs) noexcept + SHCollisionShape::SHCollisionShape(const SHCollisionShape& rhs) noexcept : type { rhs.type} , entityID { rhs.entityID } , isTrigger { rhs.isTrigger } @@ -61,7 +61,7 @@ namespace SHADE CopyShape(rhs.shape); } - SHCollider::SHCollider(SHCollider&& rhs) noexcept + SHCollisionShape::SHCollisionShape(SHCollisionShape&& rhs) noexcept : type { rhs.type} , entityID { rhs.entityID } , isTrigger { rhs.isTrigger } @@ -73,7 +73,7 @@ namespace SHADE CopyShape(rhs.shape); } - SHCollider::~SHCollider() noexcept + SHCollisionShape::~SHCollisionShape() noexcept { shape = nullptr; } @@ -82,7 +82,7 @@ namespace SHADE /* Operator Overload Definitions */ /*-----------------------------------------------------------------------------------*/ - SHCollider& SHCollider::operator=(const SHCollider& rhs) noexcept + SHCollisionShape& SHCollisionShape::operator=(const SHCollisionShape& rhs) noexcept { if (this == &rhs) return *this; @@ -100,7 +100,7 @@ namespace SHADE return *this; } - SHCollider& SHCollider::operator=(SHCollider&& rhs) noexcept + SHCollisionShape& SHCollisionShape::operator=(SHCollisionShape&& rhs) noexcept { type = rhs.type; entityID = rhs.entityID; @@ -119,52 +119,52 @@ namespace SHADE /* Getter Function Definitions */ /*-----------------------------------------------------------------------------------*/ - bool SHCollider::HasChanged() const noexcept + bool SHCollisionShape::HasChanged() const noexcept { return dirty; } - bool SHCollider::IsTrigger() const noexcept + bool SHCollisionShape::IsTrigger() const noexcept { return isTrigger; } - SHCollider::Type SHCollider::GetType() const noexcept + SHCollisionShape::Type SHCollisionShape::GetType() const noexcept { return type; } - float SHCollider::GetFriction() const noexcept + float SHCollisionShape::GetFriction() const noexcept { return material.GetFriction(); } - float SHCollider::GetBounciness() const noexcept + float SHCollisionShape::GetBounciness() const noexcept { return material.GetBounciness(); } - float SHCollider::GetDensity() const noexcept + float SHCollisionShape::GetDensity() const noexcept { return material.GetDensity(); } - const SHPhysicsMaterial& SHCollider::GetMaterial() const noexcept + const SHPhysicsMaterial& SHCollisionShape::GetMaterial() const noexcept { return material; } - const SHVec3& SHCollider::GetPositionOffset() const noexcept + const SHVec3& SHCollisionShape::GetPositionOffset() const noexcept { return positionOffset; } - const SHVec3& SHCollider::GetRotationOffset() const noexcept + const SHVec3& SHCollisionShape::GetRotationOffset() const noexcept { return rotationOffset; } - SHShape* SHCollider::GetShape() noexcept + SHShape* SHCollisionShape::GetShape() noexcept { dirty = true; return shape; @@ -174,7 +174,7 @@ namespace SHADE /* Setter Function Definitions */ /*-----------------------------------------------------------------------------------*/ - void SHCollider::SetBoundingBox(const SHVec3& halfExtents) + void SHCollisionShape::SetBoundingBox(const SHVec3& halfExtents) { dirty = true; @@ -199,7 +199,7 @@ namespace SHADE } } - void SHCollider::SetBoundingSphere(float radius) + void SHCollisionShape::SetBoundingSphere(float radius) { dirty = true; @@ -230,37 +230,37 @@ namespace SHADE } - void SHCollider::SetIsTrigger(bool trigger) noexcept + void SHCollisionShape::SetIsTrigger(bool trigger) noexcept { dirty = true; isTrigger = trigger; } - void SHCollider::SetFriction(float friction) noexcept + void SHCollisionShape::SetFriction(float friction) noexcept { dirty = true; material.SetFriction(friction); } - void SHCollider::SetBounciness(float bounciness) noexcept + void SHCollisionShape::SetBounciness(float bounciness) noexcept { dirty = true; material.SetBounciness(bounciness); } - void SHCollider::SetDensity(float density) noexcept + void SHCollisionShape::SetDensity(float density) noexcept { dirty = true; material.SetDensity(density); } - void SHCollider::SetMaterial(const SHPhysicsMaterial& newMaterial) noexcept + void SHCollisionShape::SetMaterial(const SHPhysicsMaterial& newMaterial) noexcept { dirty = true; material = newMaterial; } - void SHCollider::SetPositionOffset(const SHVec3& posOffset) noexcept + void SHCollisionShape::SetPositionOffset(const SHVec3& posOffset) noexcept { dirty = true; positionOffset = posOffset; @@ -281,7 +281,7 @@ namespace SHADE } } - void SHCollider::SetRotationOffset(const SHVec3& rotOffset) noexcept + void SHCollisionShape::SetRotationOffset(const SHVec3& rotOffset) noexcept { dirty = true; rotationOffset = rotOffset; @@ -291,7 +291,7 @@ namespace SHADE /* Private Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ - void SHCollider::CopyShape(const SHShape* rhs) + void SHCollisionShape::CopyShape(const SHShape* rhs) { switch (type) { @@ -320,14 +320,14 @@ RTTR_REGISTRATION using namespace SHADE; using namespace rttr; - registration::enumeration("Collider Type") + registration::enumeration("Collider Type") ( - value("Box", SHCollider::Type::BOX), - value("Sphere", SHCollider::Type::SPHERE) + value("Box", SHCollisionShape::Type::BOX), + value("Sphere", SHCollisionShape::Type::SPHERE) // TODO(Diren): Add More Shapes ); - registration::class_("Collider") - .property("Position Offset", &SHCollider::GetPositionOffset, &SHCollider::SetPositionOffset) - .property("Rotation Offset", &SHCollider::GetRotationOffset, &SHCollider::SetRotationOffset) (metadata(META::angleInRad, true)); + registration::class_("Collider") + .property("Position Offset", &SHCollisionShape::GetPositionOffset, &SHCollisionShape::SetPositionOffset) + .property("Rotation Offset", &SHCollisionShape::GetRotationOffset, &SHCollisionShape::SetRotationOffset) (metadata(META::angleInRad, true)); } \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHCollider.h b/SHADE_Engine/src/Physics/SHCollisionShape.h similarity index 91% rename from SHADE_Engine/src/Physics/SHCollider.h rename to SHADE_Engine/src/Physics/SHCollisionShape.h index 8cc233c4..9c8c1d41 100644 --- a/SHADE_Engine/src/Physics/SHCollider.h +++ b/SHADE_Engine/src/Physics/SHCollisionShape.h @@ -24,7 +24,7 @@ namespace SHADE /* Type Definitions */ /*-----------------------------------------------------------------------------------*/ - class SH_API SHCollider + class SH_API SHCollisionShape { private: @@ -51,18 +51,18 @@ namespace SHADE /* Constructors & Destructor */ /*---------------------------------------------------------------------------------*/ - SHCollider (EntityID eid, Type colliderType = Type::BOX, const SHPhysicsMaterial& physicsMaterial = SHPhysicsMaterial::DEFAULT); + SHCollisionShape (EntityID eid, Type colliderType = Type::BOX, const SHPhysicsMaterial& physicsMaterial = SHPhysicsMaterial::DEFAULT); - SHCollider (const SHCollider& rhs) noexcept; - SHCollider (SHCollider&& rhs) noexcept; - ~SHCollider () noexcept; + SHCollisionShape (const SHCollisionShape& rhs) noexcept; + SHCollisionShape (SHCollisionShape&& rhs) noexcept; + ~SHCollisionShape () noexcept; /*---------------------------------------------------------------------------------*/ /* Operator Overloads */ /*---------------------------------------------------------------------------------*/ - SHCollider& operator=(const SHCollider& rhs) noexcept; - SHCollider& operator=(SHCollider&& rhs) noexcept; + SHCollisionShape& operator=(const SHCollisionShape& rhs) noexcept; + SHCollisionShape& operator=(SHCollisionShape&& rhs) noexcept; /*---------------------------------------------------------------------------------*/ /* Getter Functions */ diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp index 37c1269e..5658f304 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp @@ -128,13 +128,13 @@ namespace SHADE /* Public Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ - int SHPhysicsObject::AddCollider(SHCollider* collider) + int SHPhysicsObject::AddCollider(SHCollisionShape* collider) { const rp3d::Transform OFFSETS{ collider->GetPositionOffset(), collider->GetRotationOffset() }; switch (collider->GetType()) { - case SHCollider::Type::BOX: + case SHCollisionShape::Type::BOX: { const auto* box = reinterpret_cast(collider->GetShape()); rp3d::BoxShape* newBox = factory->createBoxShape(box->GetHalfExtents()); @@ -142,7 +142,7 @@ namespace SHADE rp3dBody->addCollider(newBox, OFFSETS); break; } - case SHCollider::Type::SPHERE: + case SHCollisionShape::Type::SPHERE: { const auto* sphere = reinterpret_cast(collider->GetShape()); rp3d::SphereShape* newSphere = factory->createSphereShape(sphere->GetRadius()); @@ -173,7 +173,7 @@ namespace SHADE void SHPhysicsObject::SyncColliders(SHColliderComponent* c) const noexcept { int index = 0; - for (auto& collider : c->colliders) + for (auto& collider : c->collisionShapes) { if (!collider.dirty) continue; @@ -188,7 +188,7 @@ namespace SHADE switch (collider.GetType()) { - case SHCollider::Type::BOX: + case SHCollisionShape::Type::BOX: { const auto* box = reinterpret_cast(collider.GetShape()); @@ -197,7 +197,7 @@ namespace SHADE break; } - case SHCollider::Type::SPHERE: + case SHCollisionShape::Type::SPHERE: { const auto* sphere = reinterpret_cast(collider.GetShape()); diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.h b/SHADE_Engine/src/Physics/SHPhysicsObject.h index 64caacdb..09b70b11 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.h +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.h @@ -69,7 +69,7 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ - int AddCollider (SHCollider* collider); + int AddCollider (SHCollisionShape* collider); void RemoveCollider (int index); void SyncColliders (SHColliderComponent* c) const noexcept; diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index 66c28958..078a5d6a 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -348,7 +348,7 @@ namespace SHADE factory.destroyPhysicsWorld(world); } - void SHPhysicsSystem::AddCollisionShape(EntityID entityID, SHCollider* collider) + void SHPhysicsSystem::AddCollisionShape(EntityID entityID, SHCollisionShape* collider) { auto* physicsObject = GetPhysicsObject(entityID); @@ -735,7 +735,7 @@ namespace SHADE // Add collision shapes back into the body if (colliderComponent != nullptr) { - for (auto& collider : colliderComponent->colliders) + for (auto& collider : colliderComponent->collisionShapes) physicsObject->AddCollider(&collider); } } @@ -756,7 +756,7 @@ namespace SHADE } // Add Collision Shapes - for (auto& collider : colliderComponent->colliders) + for (auto& collider : colliderComponent->collisionShapes) physicsObject->AddCollider(&collider); } } @@ -801,7 +801,7 @@ namespace SHADE rp3d::Transform{ colliderComponent->position, colliderComponent->orientation } ); - for (auto& collider : colliderComponent->colliders) + for (auto& collider : colliderComponent->collisionShapes) physicsObject->AddCollider(&collider); } } diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/SHPhysicsSystem.h index 0dd2754e..55575c73 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.h @@ -114,7 +114,7 @@ namespace SHADE void Init () override; void Exit () override; - void AddCollisionShape (EntityID entityID, SHCollider* collider); + void AddCollisionShape (EntityID entityID, SHCollisionShape* collider); void RemoveCollisionShape (EntityID entityID, int index); void onContact (const rp3d::CollisionCallback::CallbackData& callbackData) override; diff --git a/SHADE_Engine/src/Physics/SHPhysicsUtils.cpp b/SHADE_Engine/src/Physics/SHPhysicsUtils.cpp index 8d5bc956..14b6cc2f 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsUtils.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsUtils.cpp @@ -75,14 +75,14 @@ namespace SHADE return SHComponentManager::GetComponent_s(ids[ENTITY_B]); } - const SHCollider* SHCollisionEvent::GetColliderA() const noexcept + const SHCollisionShape* SHCollisionEvent::GetColliderA() const noexcept { - return &SHComponentManager::GetComponent(ids[ENTITY_A])->GetCollider(ids[COLLIDER_A]); + return &SHComponentManager::GetComponent(ids[ENTITY_A])->GetCollisionShape(ids[COLLIDER_A]); } - const SHCollider* SHCollisionEvent::GetColliderB() const noexcept + const SHCollisionShape* SHCollisionEvent::GetColliderB() const noexcept { - return &SHComponentManager::GetComponent(ids[ENTITY_B])->GetCollider(ids[COLLIDER_B]); + return &SHComponentManager::GetComponent(ids[ENTITY_B])->GetCollisionShape(ids[COLLIDER_B]); } SHCollisionEvent::State SHCollisionEvent::GetCollisionState() const noexcept diff --git a/SHADE_Engine/src/Physics/SHPhysicsUtils.h b/SHADE_Engine/src/Physics/SHPhysicsUtils.h index 57f9c6fc..753f8d3b 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsUtils.h +++ b/SHADE_Engine/src/Physics/SHPhysicsUtils.h @@ -24,7 +24,7 @@ namespace SHADE struct SHPhysicsColliderAddedEvent { EntityID entityID; - SHCollider::Type colliderType; + SHCollisionShape::Type colliderType; int colliderIndex; }; @@ -88,8 +88,8 @@ namespace SHADE [[nodiscard]] EntityID GetEntityB () const noexcept; [[nodiscard]] const SHRigidBodyComponent* GetRigidBodyA () const noexcept; [[nodiscard]] const SHRigidBodyComponent* GetRigidBodyB () const noexcept; - [[nodiscard]] const SHCollider* GetColliderA () const noexcept; - [[nodiscard]] const SHCollider* GetColliderB () const noexcept; + [[nodiscard]] const SHCollisionShape* GetColliderA () const noexcept; + [[nodiscard]] const SHCollisionShape* GetColliderB () const noexcept; [[nodiscard]] State GetCollisionState () const noexcept; private: diff --git a/SHADE_Engine/src/Serialization/SHYAMLConverters.h b/SHADE_Engine/src/Serialization/SHYAMLConverters.h index d4b97244..76be74ce 100644 --- a/SHADE_Engine/src/Serialization/SHYAMLConverters.h +++ b/SHADE_Engine/src/Serialization/SHYAMLConverters.h @@ -3,7 +3,7 @@ #include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h" #include "Math/Geometry/SHBoundingBox.h" #include "Math/Geometry/SHBoundingSphere.h" -#include "Physics/SHCollider.h" +#include "Physics/SHCollisionShape.h" #include "Resource/SHResourceManager.h" #include "Math/Vector/SHVec2.h" #include "Math/Vector/SHVec3.h" @@ -101,7 +101,7 @@ namespace YAML }; template<> - struct convert + struct convert { static constexpr const char* IsTrigger = "Is Trigger"; @@ -114,33 +114,33 @@ namespace YAML static constexpr const char* Density = "Density"; static constexpr const char* PositionOffset = "Position Offset"; - static Node encode(SHCollider& rhs) + static Node encode(SHCollisionShape& rhs) { Node node; node[IsTrigger] = rhs.IsTrigger(); - rttr::type const shapeRttrType = rttr::type::get(); + rttr::type const shapeRttrType = rttr::type::get(); rttr::enumeration const enumAlign = shapeRttrType.get_enumeration(); - SHCollider::Type colliderType = rhs.GetType(); + SHCollisionShape::Type colliderType = rhs.GetType(); node[Type] = enumAlign.value_to_name(colliderType).data(); switch (colliderType) { - case SHCollider::Type::BOX: + case SHCollisionShape::Type::BOX: { auto const bb = reinterpret_cast(rhs.GetShape()); node[HalfExtents] = bb->GetHalfExtents(); } break; - case SHCollider::Type::SPHERE: + case SHCollisionShape::Type::SPHERE: { auto const bs = reinterpret_cast(rhs.GetShape()); node[Radius] = bs->GetRadius(); } break; - case SHCollider::Type::CAPSULE: break; + case SHCollisionShape::Type::CAPSULE: break; default:; } @@ -151,33 +151,33 @@ namespace YAML return node; } - static bool decode(Node const& node, SHCollider& rhs) + static bool decode(Node const& node, SHCollisionShape& rhs) { if (node[IsTrigger].IsDefined()) rhs.SetIsTrigger(node[IsTrigger].as()); if (!node[Type].IsDefined()) return false; - rttr::type const shapeRttrType = rttr::type::get(); + rttr::type const shapeRttrType = rttr::type::get(); rttr::enumeration const enumAlign = shapeRttrType.get_enumeration(); bool ok; - const SHCollider::Type colliderType = enumAlign.name_to_value(node[Type].as()).convert(&ok); + const SHCollisionShape::Type colliderType = enumAlign.name_to_value(node[Type].as()).convert(&ok); if (!ok) return false; switch (colliderType) { - case SHCollider::Type::BOX: + case SHCollisionShape::Type::BOX: { if (node[HalfExtents].IsDefined()) rhs.SetBoundingBox(node[HalfExtents].as() * 2.0f); } break; - case SHCollider::Type::SPHERE: + case SHCollisionShape::Type::SPHERE: { if (node[Radius].IsDefined()) rhs.SetBoundingSphere(node[Radius].as()); } break; - case SHCollider::Type::CAPSULE: break; + case SHCollisionShape::Type::CAPSULE: break; default:; } if (node[Friction].IsDefined()) @@ -200,12 +200,12 @@ namespace YAML static Node encode(SHColliderComponent& rhs) { Node node, collidersNode; - auto const& colliders = rhs.GetColliders(); + auto const& colliders = rhs.GetCollisionShapes(); int const numColliders = static_cast(colliders.size()); for (int i = 0; i < numColliders; ++i) { - auto& collider = rhs.GetCollider(i); - Node colliderNode = convert::encode(collider); + auto& collider = rhs.GetCollisionShape(i); + Node colliderNode = convert::encode(collider); if (colliderNode.IsDefined()) collidersNode[i] = colliderNode; } @@ -219,21 +219,21 @@ namespace YAML int numColliders{}; for (auto const& colliderNode : node[Colliders]) { - rttr::type const shapeRttrType = rttr::type::get(); + rttr::type const shapeRttrType = rttr::type::get(); rttr::enumeration const enumAlign = shapeRttrType.get_enumeration(); bool ok = false; - const SHCollider::Type colliderType = enumAlign.name_to_value(colliderNode[convert::Type].as()).convert(&ok); + const SHCollisionShape::Type colliderType = enumAlign.name_to_value(colliderNode[convert::Type].as()).convert(&ok); if (!ok) return false; switch (colliderType) { - case SHCollider::Type::BOX: rhs.AddBoundingBox(); break; - case SHCollider::Type::SPHERE: rhs.AddBoundingSphere(); break; - case SHCollider::Type::CAPSULE: break; + case SHCollisionShape::Type::BOX: rhs.AddBoundingBox(); break; + case SHCollisionShape::Type::SPHERE: rhs.AddBoundingSphere(); break; + case SHCollisionShape::Type::CAPSULE: break; default:; } - YAML::convert::decode(colliderNode, rhs.GetCollider(numColliders++)); + YAML::convert::decode(colliderNode, rhs.GetCollisionShape(numColliders++)); } } return true; diff --git a/SHADE_Managed/src/Components/Collider.cxx b/SHADE_Managed/src/Components/Collider.cxx index f2119b43..dc5d27af 100644 --- a/SHADE_Managed/src/Components/Collider.cxx +++ b/SHADE_Managed/src/Components/Collider.cxx @@ -150,7 +150,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ int Collider::CollisionShapeCount::get() { - return static_cast(GetNativeComponent()->GetColliders().size()); + return static_cast(GetNativeComponent()->GetCollisionShapes().size()); } /*---------------------------------------------------------------------------------*/ @@ -230,18 +230,18 @@ namespace SHADE // Populate the list int i = 0; - for (const auto& collider : GetNativeComponent()->GetColliders()) + for (const auto& collider : GetNativeComponent()->GetCollisionShapes()) { CollisionShape^ bound = nullptr; switch (collider.GetType()) { - case SHCollider::Type::BOX: + case SHCollisionShape::Type::BOX: bound = gcnew BoxCollider(i, Owner.GetEntity()); break; - case SHCollider::Type::SPHERE: + case SHCollisionShape::Type::SPHERE: bound = gcnew SphereCollider(i, Owner.GetEntity()); break; - case SHCollider::Type::CAPSULE: + case SHCollisionShape::Type::CAPSULE: // TODO break; default: diff --git a/SHADE_Managed/src/Components/Collider.h++ b/SHADE_Managed/src/Components/Collider.h++ index 1f8b43eb..6e165619 100644 --- a/SHADE_Managed/src/Components/Collider.h++ +++ b/SHADE_Managed/src/Components/Collider.h++ @@ -27,11 +27,11 @@ namespace SHADE try { - auto& bounds = collider->GetCollider(arrayIndex); - if (bounds.GetType() != SHCollider::Type::BOX) + auto& shape = collider->GetCollisionShape(arrayIndex); + if (shape.GetType() != SHCollisionShape::Type::BOX) throw gcnew System::InvalidOperationException("Attempted to retrieve invalid ColliderBound."); - return reinterpret_cast(bounds); + return reinterpret_cast(shape); } catch (std::invalid_argument&) { From d302d7e07d212b9a7eec08a75b0e7bfd80f3d9b8 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 7 Nov 2022 19:32:12 +0800 Subject: [PATCH 17/59] Added labels for more buffers, images, imageviews, frames, semaphores and more --- .../src/Graphics/Buffers/SHVkBuffer.cpp | 7 +++++- .../Graphics/Devices/SHVkLogicalDevice.cpp | 4 ++-- .../src/Graphics/Images/SHVkImage.cpp | 16 +++++++++---- SHADE_Engine/src/Graphics/Images/SHVkImage.h | 8 +++++-- .../Graphics/MiddleEnd/Batching/SHBatch.cpp | 10 +++++++- .../GlobalData/SHGraphicsGlobalData.cpp | 16 ++++++------- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 23 +++++++++++++------ .../MiddleEnd/Interface/SHMousePickSystem.cpp | 2 +- .../MiddleEnd/Interface/SHRenderer.cpp | 8 ++++++- .../MiddleEnd/Lights/SHLightingSubSystem.cpp | 12 ++++++---- .../MiddleEnd/PerFrame/SHPerFrameData.cpp | 7 ++++-- .../MiddleEnd/PerFrame/SHPerFrameData.h | 2 +- .../MiddleEnd/PerFrame/SHRenderContext.cpp | 8 ++++++- .../MiddleEnd/Textures/SHTextureLibrary.cpp | 8 ++++++- .../Graphics/RenderGraph/SHRenderGraph.cpp | 3 ++- .../RenderGraph/SHRenderGraphNode.cpp | 5 ++-- .../Graphics/RenderGraph/SHRenderGraphNode.h | 2 +- .../RenderGraph/SHRenderGraphNodeCompute.cpp | 11 ++++++++- .../RenderGraph/SHRenderGraphNodeCompute.h | 5 +++- .../RenderGraph/SHRenderGraphResource.cpp | 9 ++++++-- .../src/Graphics/RenderGraph/SHSubpass.cpp | 5 ++++ TempScriptsFolder/RaccoonSpin.cs | 5 ++++ 22 files changed, 132 insertions(+), 44 deletions(-) diff --git a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp index 803c53be..36108628 100644 --- a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp +++ b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp @@ -217,6 +217,7 @@ namespace SHADE &bufferInfo.operator VkBufferCreateInfo & (), // TODO: Verify if this works (can use RenderDoc to check buffer variables?) &allocCreateInfo, &tempBuffer, &stagingAlloc, &allocInfo); + SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eDeviceMemory, allocInfo.deviceMemory, "[Memory] Staging - " + name); // then assign it to the hpp version stagingBuffer = tempBuffer; @@ -252,7 +253,11 @@ namespace SHADE auto result = vmaCreateBuffer(vmaAllocator, &bufferCreateInfo.operator VkBufferCreateInfo & (), &allocCreateInfo, - &tempBuffer, &alloc, &allocInfo); + &tempBuffer, &alloc, &allocInfo); +#ifdef _DEBUG + if (!name.empty()) + SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eDeviceMemory, allocInfo.deviceMemory, "[Memory] " + name); +#endif if (result != VK_SUCCESS) SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan buffer. "); diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp index 20332f1d..808ce750 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp @@ -456,12 +456,12 @@ namespace SHADE /***************************************************************************/ Handle SHVkLogicalDevice::CreateImage(uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) const noexcept { - return SHVkInstance::GetResourceManager().Create(&vmaAllocator, w, h, levels, format, usage, create); + return SHVkInstance::GetResourceManager().Create(GetHandle(), &vmaAllocator, w, h, levels, format, usage, create); } Handle SHVkLogicalDevice::CreateImage(SHImageCreateParams const& imageDetails, unsigned char* data, uint32_t dataSize, std::span inMipOffsets, VmaMemoryUsage memUsage, VmaAllocationCreateFlags allocFlags) noexcept { - return SHVkInstance::GetResourceManager().Create(&vmaAllocator, imageDetails, data, dataSize, inMipOffsets, memUsage, allocFlags); + return SHVkInstance::GetResourceManager().Create(GetHandle(), &vmaAllocator, imageDetails, data, dataSize, inMipOffsets, memUsage, allocFlags); } /***************************************************************************/ diff --git a/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp b/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp index 00cc31bf..33bed1b5 100644 --- a/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp +++ b/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp @@ -61,6 +61,7 @@ namespace SHADE &bufferInfo.operator VkBufferCreateInfo & (), // TODO: Verify if this works (can use renderdoc to check buffer variables?) &allocCreateInfo, &tempBuffer, &stagingAlloc, &allocInfo); + SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eDeviceMemory, allocInfo.deviceMemory, "[Memory] Staging Buffer for Image"); // then assign it to the hpp version stagingBuffer = tempBuffer; @@ -107,6 +108,8 @@ namespace SHADE VkImage tempImage; auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo & (), &allocCreateInfo, &tempImage, &alloc, &allocInfo); vkImage = tempImage; + //SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eImage, vkImage, "[Image] "); + SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eDeviceMemory, allocInfo.deviceMemory, "[Device Memory] Image Memory"); if (result != VK_SUCCESS) SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan image. "); @@ -115,7 +118,8 @@ namespace SHADE } SHVkImage::SHVkImage( - VmaAllocator const* allocator, + Handle logicalDeviceHdl, + VmaAllocator const* allocator, SHImageCreateParams const& imageDetails, const unsigned char* data, uint32_t dataSize, @@ -137,6 +141,7 @@ namespace SHADE , boundToCoherent{false} , randomAccessOptimized {false} , mappedPtr{nullptr} + , device { logicalDeviceHdl } { usageFlags = imageDetails.usageFlags; createFlags = imageDetails.createFlags; @@ -175,7 +180,9 @@ namespace SHADE VmaAllocationInfo allocInfo{}; VkImage tempImage; - auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo&(), &allocCreateInfo, &tempImage, &alloc, &allocInfo); + auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo & (), &allocCreateInfo, &tempImage, &alloc, &allocInfo); + //SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eImage, vkImage, "[Image] "); + SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eDeviceMemory, allocInfo.deviceMemory, "[Device Memory] Image Memory"); if (result != VK_SUCCESS) SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan image. "); @@ -220,7 +227,7 @@ namespace SHADE //} } - SHVkImage::SHVkImage(VmaAllocator const* allocator, uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) noexcept + SHVkImage::SHVkImage(Handle logicalDeviceHdl, VmaAllocator const* allocator, uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) noexcept : width {w} , height{h} , depth {1} @@ -230,11 +237,12 @@ namespace SHADE , usageFlags{usage} , createFlags {create} , vmaAllocator {allocator} + , device { logicalDeviceHdl } { CreateFramebufferImage(); } - Handle SHVkImage::CreateImageView(Handle const& inLogicalDeviceHdl, Handle const& parent, SHImageViewDetails const& createParams) const noexcept + Handle SHVkImage::CreateImageView(Handle inLogicalDeviceHdl, Handle const& parent, SHImageViewDetails const& createParams) const noexcept { return SHVkInstance::GetResourceManager().Create(inLogicalDeviceHdl, parent, createParams); } diff --git a/SHADE_Engine/src/Graphics/Images/SHVkImage.h b/SHADE_Engine/src/Graphics/Images/SHVkImage.h index 4fb16017..ba459def 100644 --- a/SHADE_Engine/src/Graphics/Images/SHVkImage.h +++ b/SHADE_Engine/src/Graphics/Images/SHVkImage.h @@ -104,6 +104,9 @@ namespace SHADE //! Mipmap offsets for initializing the vk::BufferImageCopy during transfer to GPU resource std::span mipOffsets; + //! Handle to the device that creates these images + Handle device; + /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ @@ -117,6 +120,7 @@ namespace SHADE SHVkImage(void) noexcept = default; SHVkImage( + Handle logicalDeviceHdl, VmaAllocator const* allocator, SHImageCreateParams const& imageDetails, const unsigned char* data, @@ -126,7 +130,7 @@ namespace SHADE VmaAllocationCreateFlags allocFlags ) noexcept; - SHVkImage(VmaAllocator const* allocator, uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) noexcept; + SHVkImage(Handle logicalDeviceHdl, VmaAllocator const* allocator, uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) noexcept; SHVkImage(SHVkImage&& rhs) noexcept = default; SHVkImage& operator=(SHVkImage && rhs) noexcept = default; @@ -134,7 +138,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* PUBLIC MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ - Handle CreateImageView (Handle const& inLogicalDeviceHdl, Handle const& parent, SHImageViewDetails const& createParams) const noexcept; + Handle CreateImageView (Handle inLogicalDeviceHdl, Handle const& parent, SHImageViewDetails const& createParams) const noexcept; void TransferToDeviceResource (Handle cmdBufferHdl) noexcept; void PrepareImageTransitionInfo (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept; void HandleResizeFramebufferImage(uint32_t newWidth, uint32_t newHeight) noexcept; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index 3f9b6fa2..1829096f 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -465,7 +465,8 @@ namespace SHADE SHVkUtil::EnsureBufferAndCopyHostVisibleData ( device, matPropsBuffer[frameIndex], matPropsData.get(), static_cast(matPropsDataSize), - vk::BufferUsageFlagBits::eStorageBuffer + vk::BufferUsageFlagBits::eStorageBuffer, + "Batch Material Data" ); if (!matPropsDescSet[frameIndex]) @@ -475,6 +476,13 @@ namespace SHADE { SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE] }, { 0 } ); +#ifdef _DEBUG + const auto& DESC_SETS = matPropsDescSet[frameIndex]->GetVkHandle(); + for (auto descSet : DESC_SETS) + { + SET_VK_OBJ_NAME(device, vk::ObjectType::eDescriptorSet, descSet, "[Descriptor Set] Batch Material Data"); + } +#endif } std::array, 1> bufferList = { matPropsBuffer[frameIndex] }; matPropsDescSet[frameIndex]->ModifyWriteDescBuffer diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp index 155097a5..53adf2fe 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp @@ -19,7 +19,7 @@ namespace SHADE void SHGraphicsGlobalData::InitHighFrequencyGlobalData(void) noexcept { - } + } /*-----------------------------------------------------------------------------------*/ /* Function Definitions */ @@ -44,7 +44,8 @@ namespace SHADE }; // For global data (generic data and textures) - Handle staticGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS,{ genericDataBinding, texturesBinding }); + Handle staticGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS, { genericDataBinding, texturesBinding }); + SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, staticGlobalLayout->GetVkHandle(), "[Descriptor Set Layout] Static Globals"); std::vector lightBindings{}; @@ -70,11 +71,11 @@ namespace SHADE }); } - // For Dynamic global data (lights) Handle dynamicGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, lightBindings); + SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, dynamicGlobalLayout->GetVkHandle(), "[Descriptor Set Layout] Dynamic Globals"); - + // For High frequency global data (camera) SHVkDescriptorSetLayout::Binding cameraDataBinding { .Type = vk::DescriptorType::eUniformBufferDynamic, @@ -82,10 +83,10 @@ namespace SHADE .BindPoint = SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA, .DescriptorCount = 1, }; - - // For High frequency global data (camera) Handle cameraDataGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, { cameraDataBinding }); + SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, cameraDataGlobalLayout->GetVkHandle(), "[Descriptor Set Layout] High Frequency Globals"); + // For per instance data (transforms, materials, etc.) SHVkDescriptorSetLayout::Binding materialDataBinding { .Type = vk::DescriptorType::eStorageBufferDynamic, @@ -93,9 +94,8 @@ namespace SHADE .BindPoint = SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA, .DescriptorCount = 1, }; - - // For High frequency global data (camera) Handle materialDataPerInstanceLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, { materialDataBinding }); + SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, materialDataPerInstanceLayout->GetVkHandle(), "[Descriptor Set Layout] Material Globals"); globalDescSetLayouts.push_back(staticGlobalLayout); globalDescSetLayouts.push_back(dynamicGlobalLayout); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 5b2fea7c..27234781 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -213,6 +213,7 @@ namespace SHADE ssaoStorage = resourceManager.Create(); ssaoTransferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); + SET_VK_OBJ_NAME(device, vk::ObjectType::eCommandBuffer, ssaoTransferCmdBuffer->GetVkCommandBuffer(), "[Command Buffer] SSAO Pass (Graphics)"); ssaoTransferCmdBuffer->BeginRecording(); ssaoStorage->Init(device, ssaoTransferCmdBuffer); @@ -234,7 +235,7 @@ namespace SHADE ssaoStorage->PrepareRotationVectorsVkData(device); - Handle ssaoPass = gBufferNode->AddNodeCompute(ssaoShader, {"Position", "Normals", "SSAO"}); + Handle ssaoPass = gBufferNode->AddNodeCompute("SSAO", ssaoShader, {"Position", "Normals", "SSAO"}); auto ssaoDataBuffer = ssaoStorage->GetBuffer(); ssaoPass->ModifyWriteDescBufferComputeResource(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, SHSSAO::DESC_SET_BUFFER_BINDING, { &ssaoDataBuffer, 1 }, 0, ssaoStorage->GetBuffer()->GetSizeStored()); auto viewSamplerLayout = ssaoStorage->GetViewSamplerLayout(); @@ -242,12 +243,12 @@ namespace SHADE ssaoPass->ModifyWriteDescImageComputeResource(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, SHSSAO::DESC_SET_IMAGE_BINDING, {&viewSamplerLayout, 1}); - Handle ssaoBlurPass = gBufferNode->AddNodeCompute(ssaoBlurShader, { "SSAO", "SSAO Blur"}); + Handle ssaoBlurPass = gBufferNode->AddNodeCompute("SSAO Blur Step", ssaoBlurShader, {"SSAO", "SSAO Blur"}); /*-----------------------------------------------------------------------*/ /* DEFERRED COMPOSITE SUBPASS INIT */ /*-----------------------------------------------------------------------*/ - gBufferNode->AddNodeCompute(deferredCompositeShader, { "Position", "Normals", "Albedo", "Light Layer Indices", "SSAO Blur", "Scene" }); + gBufferNode->AddNodeCompute("Deferred Composite", deferredCompositeShader, {"Position", "Normals", "Albedo", "Light Layer Indices", "SSAO Blur", "Scene"}); // Dummy Node auto dummyNode = worldRenderGraph->AddNode("Dummy Pass", { "Scene" }, { "Debug Draw" }); // no predecessors @@ -271,7 +272,11 @@ namespace SHADE // Create debug draw pipeline debugDrawPipeline = createDebugDrawPipeline(debugDrawNode->GetRenderpass(), debugDrawSubpass); + SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, debugDrawPipeline->GetVkPipeline(), "[Pipeline] Debug Draw"); + SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, debugDrawPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline] Debug Draw Pipeline Layout"); debugDrawDepthPipeline = createDebugDrawPipeline(debugDrawNodeDepth->GetRenderpass(), debugDrawDepthSubpass); + SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, debugDrawDepthPipeline->GetVkPipeline(), "[Pipeline] Debug Draw with Depth Test"); + SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, debugDrawDepthPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline] Debug Draw with Depth Test Pipeline Layout"); } void SHGraphicsSystem::InitMiddleEnd(void) noexcept @@ -677,6 +682,8 @@ namespace SHADE auto renderGraphNode = subpass->GetParentNode(); auto pipeline = renderGraphNode->GetOrCreatePipeline(std::make_pair(vertShader, fragShader), subpass); + SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, pipeline->GetVkPipeline(), "[Pipeline] Custom Pipeline"); + SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, pipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline] Custom Pipeline Layout"); mat->SetPipeline(pipeline); @@ -723,14 +730,15 @@ namespace SHADE void SHGraphicsSystem::BuildMeshBuffers() { - transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); - device->WaitIdle(); + transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); + SET_VK_OBJ_NAME(device, vk::ObjectType::eCommandBuffer, transferCmdBuffer->GetVkCommandBuffer(), "[Command Buffer] Mesh Buffer Building (Transfer)"); + device->WaitIdle(); transferCmdBuffer->BeginRecording(); meshLibrary.BuildBuffers(device, transferCmdBuffer); transferCmdBuffer->EndRecording(); graphicsQueue->SubmitCommandBuffer({ transferCmdBuffer }); - device->WaitIdle(); - transferCmdBuffer.Free(); transferCmdBuffer = {}; + device->WaitIdle(); + transferCmdBuffer.Free(); transferCmdBuffer = {}; } Handle SHGraphicsSystem::GetMeshPrimitive(PrimitiveType type) const noexcept @@ -768,6 +776,7 @@ namespace SHADE void SHGraphicsSystem::BuildTextures() { graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); + SET_VK_OBJ_NAME(device, vk::ObjectType::eCommandBuffer, graphicsTexCmdBuffer->GetVkCommandBuffer(), "[Command Buffer] Texture Building (Graphics)"); device->WaitIdle(); texLibrary.BuildTextures ( diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp index 46126ae1..86d85c16 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp @@ -76,7 +76,7 @@ namespace SHADE uint32_t bufferSize = entityIDAttachment->GetWidth() * entityIDAttachment->GetHeight() * SHVkUtil::GetBytesPerPixelFromFormat(entityIDAttachment->GetResourceFormat()); // Create the buffer - imageDataDstBuffer = logicalDevice->CreateBuffer(bufferSize, nullptr, bufferSize, vk::BufferUsageFlagBits::eTransferDst, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); + imageDataDstBuffer = logicalDevice->CreateBuffer(bufferSize, nullptr, bufferSize, vk::BufferUsageFlagBits::eTransferDst, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, "Mouse Pick Image Data Destination"); } void SHMousePickSystem::SetViewportMousePos(SHVec2 vpMousePos) noexcept diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp index d0deb30c..63d374eb 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp @@ -39,9 +39,15 @@ namespace SHADE cameraDescriptorSet = descriptorPool->Allocate({ cameraDescLayout }, { 1 }); +#ifdef _DEBUG + const auto& CAM_DESC_SETS = cameraDescriptorSet->GetVkHandle(); + for (int i = 0; i < static_cast(CAM_DESC_SETS.size()); ++i) + SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSet, CAM_DESC_SETS[i], "[Descriptor Set] Camera Data Frame #" + std::to_string(i)); +#endif + cameraDataAlignedSize = logicalDevice->PadUBOSize(sizeof(SHShaderCameraData)); - cameraBuffer = logicalDevice->CreateBuffer(cameraDataAlignedSize * numFrames, nullptr, cameraDataAlignedSize * numFrames, vk::BufferUsageFlagBits::eUniformBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); + cameraBuffer = logicalDevice->CreateBuffer(cameraDataAlignedSize * numFrames, nullptr, cameraDataAlignedSize * numFrames, vk::BufferUsageFlagBits::eUniformBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, "Camera Data"); std::array cameraBufferArray{cameraBuffer}; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp index 485f859f..02bd8f1f 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp @@ -134,7 +134,7 @@ namespace SHADE lightDataTotalAlignedSize = logicalDevice->PadSSBOSize(lightDataAlignedSize * maxLights); // We want to initialize 3 times the amount of data required. - dataBuffer = logicalDevice->CreateBuffer(lightDataTotalAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, nullptr, lightDataTotalAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, vk::BufferUsageFlagBits::eStorageBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); + dataBuffer = logicalDevice->CreateBuffer(lightDataTotalAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, nullptr, lightDataTotalAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, vk::BufferUsageFlagBits::eStorageBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, "Light Data"); } else { @@ -385,8 +385,12 @@ namespace SHADE std::fill (variableSizes.begin(), variableSizes.end(), 1); // Create the descriptor set - lightingDataDescSet = descPool->Allocate({SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS]}, variableSizes); - + lightingDataDescSet = descPool->Allocate({ SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS] }, variableSizes); +#ifdef _DEBUG + const auto& CAM_DESC_SETS = lightingDataDescSet->GetVkHandle(); + for (int i = 0; i < static_cast(CAM_DESC_SETS.size()); ++i) + SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSet, CAM_DESC_SETS[i], "[Descriptor Set] Light Data Frame #" + std::to_string(i)); +#endif for (uint32_t i = 0; i < NUM_LIGHT_TYPES; ++i) { @@ -402,7 +406,7 @@ namespace SHADE lightCountsAlignedSize = logicalDevice->PadUBOSize(lightCountsAlignedSize); // Create the GPU buffer to hold light count - lightCountsBuffer = logicalDevice->CreateBuffer(lightCountsAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, nullptr, lightCountsAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, vk::BufferUsageFlagBits::eUniformBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); + lightCountsBuffer = logicalDevice->CreateBuffer(lightCountsAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, nullptr, lightCountsAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, vk::BufferUsageFlagBits::eUniformBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, "Light Count Data"); lightingDataDescSet->ModifyWriteDescBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::LIGHTING_COUNT, {&lightCountsBuffer, 1}, 0, sizeof (uint32_t) * NUM_LIGHT_TYPES); lightingDataDescSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::LIGHTING_COUNT); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHPerFrameData.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHPerFrameData.cpp index bbbdd015..96db1ad1 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHPerFrameData.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHPerFrameData.cpp @@ -26,7 +26,7 @@ namespace SHADE */ /***************************************************************************/ - void SHPerFrameData::Recreate(Handle const& logicalDeviceHdl) noexcept + void SHPerFrameData::Recreate(Handle logicalDeviceHdl) noexcept { // Swapchain recreation means the images are just relinked to SHVkImages. Handles will remain the same. There is no need for this line. //swapchainImageHdl = params.swapchainHdl->GetSwapchainImage(frameIndex); @@ -44,14 +44,17 @@ namespace SHADE // Create image views for the swapchain swapchainImageViewHdl = swapchainImageHdl->CreateImageView(logicalDeviceHdl, swapchainImageHdl, viewDetails); + SET_VK_OBJ_NAME(logicalDeviceHdl, vk::ObjectType::eImageView, swapchainImageViewHdl->GetImageView(), "[Image View] Swap Chain"); // Create a fence fenceHdl = logicalDeviceHdl->CreateFence(); + SET_VK_OBJ_NAME(logicalDeviceHdl, vk::ObjectType::eFence, fenceHdl->GetVkFence(), "[Fence] Swap Chain"); // scope makes it easier to navigate semImgAvailableHdl = logicalDeviceHdl->SHVkLogicalDevice::CreateSemaphore(); + SET_VK_OBJ_NAME(logicalDeviceHdl, vk::ObjectType::eSemaphore, semImgAvailableHdl->GetVkSem(), "[Semaphore] Swap Chain Image Available"); semRenderFinishHdl = logicalDeviceHdl->SHVkLogicalDevice::CreateSemaphore(); - + SET_VK_OBJ_NAME(logicalDeviceHdl, vk::ObjectType::eSemaphore, semRenderFinishHdl->GetVkSem(), "[Semaphore] Swap Chain Render Finish"); } /***************************************************************************/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHPerFrameData.h b/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHPerFrameData.h index 5ac38503..d19764c2 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHPerFrameData.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHPerFrameData.h @@ -63,7 +63,7 @@ namespace SHADE /* PRIVATE MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ // These are made into functions (instead of ctor and dtor) because we want to call these functions again when we resize the window - void Recreate (Handle const& logicalDeviceHdl) noexcept; + void Recreate (Handle logicalDeviceHdl) noexcept; void Destroy (void); friend class SHRenderContext; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.cpp index 45103819..1d24d6f7 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.cpp @@ -50,7 +50,13 @@ namespace SHADE for (uint32_t j = 0; j < params.numThreads; ++j) { - frameData[i].cmdPoolHdls.push_back(logicalDeviceHdl->CreateCommandPool(params.cmdPoolQueueFamilyType, params.cmdPoolResetMode, params.cmdBufferTransient)); + auto cmdPool = logicalDeviceHdl->CreateCommandPool(params.cmdPoolQueueFamilyType, params.cmdPoolResetMode, params.cmdBufferTransient); + SET_VK_OBJ_NAME + ( + logicalDeviceHdl, vk::ObjectType::eCommandPool, cmdPool->GetVkCommandPool(), + "[Command Pool] Render Context #" + std::to_string(i) + " Pool #" + std::to_string(j) + ); + frameData[i].cmdPoolHdls.push_back(cmdPool); } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp index 9c330b9f..b92ccddf 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp @@ -79,6 +79,7 @@ namespace SHADE { job.Image = resourceManager.Create ( + device, &device->GetVMAAllocator(), SHImageCreateParams { @@ -143,6 +144,7 @@ namespace SHADE .layerCount = 1 }; job.TextureHandle->ImageView = job.Image->CreateImageView(device, job.Image, DETAILS); + SET_VK_OBJ_NAME(device, vk::ObjectType::eImageView, job.TextureHandle->ImageView->GetImageView(), "[Image View] Texture Library Texture #" + std::to_string(job.TextureHandle->TextureArrayIndex)); } // Add Textures @@ -153,7 +155,7 @@ namespace SHADE job.TextureHandle->TextureArrayIndex = static_cast(texOrder.size()) - 1U; SET_VK_OBJ_NAME(device, vk::ObjectType::eImage, job.Image->GetVkImage(), "[Image] Texture Library Texture #" + std::to_string(job.TextureHandle->TextureArrayIndex)); - SET_VK_OBJ_NAME(device, vk::ObjectType::eImageView, job.TextureHandle->ImageView->GetImageView(), "[ImageView] Texture Library Texture #" + std::to_string(job.TextureHandle->TextureArrayIndex)); + SET_VK_OBJ_NAME(device, vk::ObjectType::eImageView, job.TextureHandle->ImageView->GetImageView(), "[Image View] Texture Library Texture #" + std::to_string(job.TextureHandle->TextureArrayIndex)); } addJobs.clear(); @@ -169,6 +171,10 @@ namespace SHADE { SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS] }, { static_cast(texOrder.size()) } ); +#ifdef _DEBUG + for (auto set : texDescriptors->GetVkHandle()) + SET_VK_OBJ_NAME(device, vk::ObjectType::eDescriptorSet, set, "[Descriptor Set] Static Globals"); +#endif texDescriptors->ModifyWriteDescImage ( SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS, diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index 9c4e0d65..500bcf04 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -59,7 +59,8 @@ namespace SHADE format = renderGraphStorage->swapchain->GetSurfaceFormatKHR().format; } - renderGraphStorage->graphResources->try_emplace(resourceName, resourceManager->Create(renderGraphStorage, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags)); + auto resource = resourceManager->Create(renderGraphStorage, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags); + renderGraphStorage->graphResources->try_emplace(resourceName, resource); } /***************************************************************************/ diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp index 9aa42c0a..b3b5b58b 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp @@ -58,6 +58,7 @@ namespace SHADE framebuffers[i] = graphStorage->logicalDevice->CreateFramebuffer(renderpass, imageViews, fbWidth, fbHeight); + SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eFramebuffer, framebuffers[i]->GetVkFramebuffer(), "[Framebuffer] " + name + std::to_string(i)); } } @@ -266,7 +267,7 @@ namespace SHADE return subpass; } - Handle SHRenderGraphNode::AddNodeCompute(Handle computeShaderModule, std::initializer_list resources, std::unordered_set&& dynamicBufferBindings, float numWorkGroupScale/* = 1.0f*/) noexcept + Handle SHRenderGraphNode::AddNodeCompute(std::string nodeName, Handle computeShaderModule, std::initializer_list resources, std::unordered_set&& dynamicBufferBindings, float numWorkGroupScale/* = 1.0f*/) noexcept { // Look for the required resources in the graph std::vector> nodeComputeResources{}; @@ -279,7 +280,7 @@ namespace SHADE } // Create the subpass compute with the resources - auto nodeCompute = graphStorage->resourceManager->Create(graphStorage, computeShaderModule, std::move(nodeComputeResources), std::move (dynamicBufferBindings), nodeComputes.empty()); + auto nodeCompute = graphStorage->resourceManager->Create(std::move(nodeName), graphStorage, computeShaderModule, std::move(nodeComputeResources), std::move (dynamicBufferBindings), nodeComputes.empty()); nodeComputes.push_back(nodeCompute); return nodeCompute; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h index 33868f5e..4fdac45c 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h @@ -103,7 +103,7 @@ namespace SHADE /* PUBLIC MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ Handle AddSubpass(std::string subpassName) noexcept; - Handle AddNodeCompute(Handle computeShaderModule, std::initializer_list resources, std::unordered_set&& dynamicBufferBindings = {}, float numWorkGroupScale = 1.0f) noexcept; + Handle AddNodeCompute(std::string nodeName, Handle computeShaderModule, std::initializer_list resources, std::unordered_set&& dynamicBufferBindings = {}, float numWorkGroupScale = 1.0f) noexcept; void AddDummySubpassIfNeeded (void) noexcept; // TODO: RemoveSubpass() diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp index a86acbc7..8cdff55a 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp @@ -13,7 +13,7 @@ namespace SHADE { - SHRenderGraphNodeCompute::SHRenderGraphNodeCompute(Handle graphStorage, Handle computeShaderModule, std::vector>&& subpassComputeResources, std::unordered_set&& dynamicBufferBindings, bool followingEndRP, float inNumWorkGroupScale/* = 1.0f*/) noexcept + SHRenderGraphNodeCompute::SHRenderGraphNodeCompute(std::string nodeName, Handle graphStorage, Handle computeShaderModule, std::vector>&& subpassComputeResources, std::unordered_set&& dynamicBufferBindings, bool followingEndRP, float inNumWorkGroupScale/* = 1.0f*/) noexcept : computePipeline{} , pipelineLayout{} , resources{} @@ -22,6 +22,7 @@ namespace SHADE , followingEndRenderpass {followingEndRP} , numWorkGroupScale {std::clamp(inNumWorkGroupScale, 0.0f, 1.0f)} , computeResource{} + , name { std::move(nodeName) } { SHPipelineLayoutParams pipelineLayoutParams { @@ -50,6 +51,10 @@ namespace SHADE for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i) { graphResourceDescSets[i] = graphStorage->descriptorPool->Allocate({graphResourceLayout}, { 1 }); +#ifdef _DEBUG + for (auto set : graphResourceDescSets[i]->GetVkHandle()) + SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eDescriptorSet, set, "[Descriptor Set] " + name + " #" + std::to_string(i)); +#endif } @@ -61,6 +66,10 @@ namespace SHADE computeResource = graphStorage->resourceManager->Create(); auto computeResourceLayout = layouts[SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE]; computeResource->descSet = graphStorage->descriptorPool->Allocate({ computeResourceLayout }, { 1 }); +#ifdef _DEBUG + for (auto set : computeResource->descSet->GetVkHandle()) + SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eDescriptorSet, set, "[Descriptor Set] " + name + " Resources"); +#endif // Allocate for descriptor offsets for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i) diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.h index 81157dc2..580f018c 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.h @@ -65,8 +65,11 @@ namespace SHADE std::array, SHGraphicsConstants::NUM_FRAME_BUFFERS> memoryBarriers; + //! Name of this node + std::string name; + public: - SHRenderGraphNodeCompute(Handle graphStorage, Handle computeShaderModule, std::vector>&& subpassComputeResources, std::unordered_set&& dynamicBufferBindings, bool followingEndRP, float inNumWorkGroupScale = 1.0f) noexcept; + SHRenderGraphNodeCompute(std::string nodeName, Handle graphStorage, Handle computeShaderModule, std::vector>&& subpassComputeResources, std::unordered_set&& dynamicBufferBindings, bool followingEndRP, float inNumWorkGroupScale = 1.0f) noexcept; void Execute (Handle cmdBuffer, uint32_t frameIndex) noexcept; void HandleResize (void) noexcept; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp index 502e09b2..4d4099c6 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp @@ -82,6 +82,7 @@ namespace SHADE { images[i] = graphStorage->swapchain->GetSwapchainImage(i); imageViews[i] = images[i]->CreateImageView(graphStorage->logicalDevice, images[i], viewDetails); + SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eImageView, imageViews[i]->GetImageView(), "[Image View] " + resourceName + " #" + std::to_string(i)); } } else // if swapchain image resource @@ -129,7 +130,9 @@ namespace SHADE } // The resource is not a swapchain image, just use the first slot of the vector - images.push_back(graphStorage->logicalDevice->CreateImage(width, height, mipLevels, resourceFormat, usage, createFlags)); + auto image = graphStorage->logicalDevice->CreateImage(width, height, mipLevels, resourceFormat, usage, createFlags); + SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eImage, image->GetVkImage(), "[Image] " + resourceName); + images.push_back(image); // prepare image view details SHImageViewDetails viewDetails @@ -144,7 +147,9 @@ namespace SHADE }; // just 1 image view created - imageViews.push_back(images[0]->CreateImageView(graphStorage->logicalDevice, images[0], viewDetails)); + auto imageView = images[0]->CreateImageView(graphStorage->logicalDevice, images[0], viewDetails); + imageViews.push_back(imageView); + SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eImageView, imageView->GetImageView(), "[Image View] " + resourceName); } } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp index 23dbbde3..2ed84d92 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp @@ -302,6 +302,11 @@ namespace SHADE group.Free(); group = graphStorage->descriptorPool->Allocate({ inputDescriptorLayout }, variableCounts); +#ifdef _DEBUG + const auto& GROUP_HANDLES = group->GetVkHandle(); + for (int i = 0; i < static_cast(GROUP_HANDLES.size()); ++i) + SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eDescriptorSet, GROUP_HANDLES[i], "[Descriptor Set] " + name + " #" + std::to_string(i)); +#endif uint32_t i = 0; for (auto& binding : bindings) diff --git a/TempScriptsFolder/RaccoonSpin.cs b/TempScriptsFolder/RaccoonSpin.cs index c5420ffb..06b3c163 100644 --- a/TempScriptsFolder/RaccoonSpin.cs +++ b/TempScriptsFolder/RaccoonSpin.cs @@ -14,8 +14,13 @@ public class RaccoonSpin : Script private Transform Transform; public RaccoonSpin(GameObject gameObj) : base(gameObj) { } + protected override void awake() { + testEvent = new CallbackEvent(); + Action action = (x) => Debug.Log($"{x}"); + testEvent.RegisterAction(action); + Transform = GetComponent(); if (Transform == null) { From 0b813d769ad1cad84796095c5eeff55da2a50a9c Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 7 Nov 2022 19:41:19 +0800 Subject: [PATCH 18/59] Added WIP Compute Pipelines labeling --- .../src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp | 6 +++--- .../src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 27234781..3c9ddfaa 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -235,7 +235,7 @@ namespace SHADE ssaoStorage->PrepareRotationVectorsVkData(device); - Handle ssaoPass = gBufferNode->AddNodeCompute("SSAO", ssaoShader, {"Position", "Normals", "SSAO"}); + Handle ssaoPass = gBufferNode->AddNodeCompute("SSAO", ssaoShader, { "Position", "Normals", "SSAO" }); auto ssaoDataBuffer = ssaoStorage->GetBuffer(); ssaoPass->ModifyWriteDescBufferComputeResource(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, SHSSAO::DESC_SET_BUFFER_BINDING, { &ssaoDataBuffer, 1 }, 0, ssaoStorage->GetBuffer()->GetSizeStored()); auto viewSamplerLayout = ssaoStorage->GetViewSamplerLayout(); @@ -273,9 +273,9 @@ namespace SHADE // Create debug draw pipeline debugDrawPipeline = createDebugDrawPipeline(debugDrawNode->GetRenderpass(), debugDrawSubpass); SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, debugDrawPipeline->GetVkPipeline(), "[Pipeline] Debug Draw"); - SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, debugDrawPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline] Debug Draw Pipeline Layout"); + SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, debugDrawPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline Layout] Debug Draw Pipeline Layout"); debugDrawDepthPipeline = createDebugDrawPipeline(debugDrawNodeDepth->GetRenderpass(), debugDrawDepthSubpass); - SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, debugDrawDepthPipeline->GetVkPipeline(), "[Pipeline] Debug Draw with Depth Test"); + SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, debugDrawDepthPipeline->GetVkPipeline(), "[Pipeline Layout] Debug Draw with Depth Test"); SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, debugDrawDepthPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline] Debug Draw with Depth Test Pipeline Layout"); } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp index 8cdff55a..b567c55d 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp @@ -32,13 +32,15 @@ namespace SHADE }; // Create pipeline layout from parameters - pipelineLayout = graphStorage->logicalDevice->CreatePipelineLayout (pipelineLayoutParams); + pipelineLayout = graphStorage->logicalDevice->CreatePipelineLayout(pipelineLayoutParams); // Create the compute pipeline computePipeline = graphStorage->logicalDevice->CreateComputePipeline(pipelineLayout); // and construct it computePipeline->ConstructPipeline(); + SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::ePipelineLayout, pipelineLayout->GetVkPipelineLayout(), "[Compute Pipeline Layout] " + nodeName); + SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::ePipeline, computePipeline->GetVkPipeline(), "[Compute Pipeline] " + nodeName); // save the resources resources = std::move (subpassComputeResources); From ed3131143d5f30c0da16b9180d777ab09c498c87 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 7 Nov 2022 23:51:48 +0800 Subject: [PATCH 19/59] Added debug labels for samplers and fixed issue with compute pipeline names not being labelled correctly --- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 12 ++++++++---- .../RenderGraph/SHRenderGraphNodeCompute.cpp | 4 ++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 3c9ddfaa..15c8ec5d 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -758,14 +758,18 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ Handle SHGraphicsSystem::AddTexture(const SHTextureAsset& texAsset) { - auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams { .maxLod = static_cast(texAsset.mipOffsets.size()) }); - return texLibrary.Add(texAsset, sampler); + const int MIPS = texAsset.mipOffsets.size(); + auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams { .maxLod = static_cast(MIPS) }); + SET_VK_OBJ_NAME(device, vk::ObjectType::eSampler, sampler->GetVkSampler(), "[Sampler] Mips " + std::to_string(MIPS)); + return texLibrary.Add(texAsset, sampler); } SHADE::Handle SHGraphicsSystem::AddTexture(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, uint32_t width, uint32_t height, SHTexture::TextureFormat format, std::vector mipOffsets) { - auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams{ .maxLod = static_cast(mipOffsets.size()) }); - return texLibrary.Add(pixelCount, pixelData, width, height, format, mipOffsets, sampler); + const int MIPS = mipOffsets.size(); + auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams{ .maxLod = static_cast(MIPS) }); + SET_VK_OBJ_NAME(device, vk::ObjectType::eSampler, sampler->GetVkSampler(), "[Sampler] Mips " + std::to_string(MIPS)); + return texLibrary.Add(pixelCount, pixelData, width, height, format, mipOffsets, sampler); } void SHGraphicsSystem::RemoveTexture(Handle tex) diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp index b567c55d..f4a103f7 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp @@ -39,8 +39,8 @@ namespace SHADE // and construct it computePipeline->ConstructPipeline(); - SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::ePipelineLayout, pipelineLayout->GetVkPipelineLayout(), "[Compute Pipeline Layout] " + nodeName); - SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::ePipeline, computePipeline->GetVkPipeline(), "[Compute Pipeline] " + nodeName); + SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::ePipelineLayout, pipelineLayout->GetVkPipelineLayout(), "[Compute Pipeline Layout] " + name); + SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::ePipeline, computePipeline->GetVkPipeline(), "[Compute Pipeline] " + name); // save the resources resources = std::move (subpassComputeResources); From 8fbd32a1449b64038dc1f6f43f7cc9557092f755 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Tue, 8 Nov 2022 00:46:09 +0800 Subject: [PATCH 20/59] Added Relative Sizes to Shapes --- Assets/Scenes/M2Scene.shade | 59 ++++++++----------- SHADE_Application/src/Scenes/SBTestScene.cpp | 2 +- .../Inspector/SHEditorComponentView.hpp | 14 +---- .../src/Math/Geometry/SHBoundingBox.cpp | 38 ++++++++---- .../src/Math/Geometry/SHBoundingBox.h | 29 +++++---- .../src/Math/Geometry/SHBoundingSphere.cpp | 40 +++++++++---- .../src/Math/Geometry/SHBoundingSphere.h | 17 ++++-- .../Components/SHColliderComponent.cpp | 52 ++++++++++++++-- .../Physics/Components/SHColliderComponent.h | 14 +++-- SHADE_Engine/src/Physics/SHCollisionShape.cpp | 57 +++++++----------- SHADE_Engine/src/Physics/SHPhysicsObject.cpp | 8 +-- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 13 ++-- .../src/Serialization/SHYAMLConverters.h | 6 +- SHADE_Managed/src/Components/Collider.cxx | 8 +-- 14 files changed, 211 insertions(+), 146 deletions(-) diff --git a/Assets/Scenes/M2Scene.shade b/Assets/Scenes/M2Scene.shade index 443d4a87..6086eed9 100644 --- a/Assets/Scenes/M2Scene.shade +++ b/Assets/Scenes/M2Scene.shade @@ -50,7 +50,7 @@ Colliders: - Is Trigger: false Type: Box - Half Extents: {x: 24.7399445, y: 0.25, z: 8.75} + Half Extents: {x: 1, y: 1, z: 1} Friction: 0.400000006 Bounciness: 0 Density: 1 @@ -90,23 +90,7 @@ Bounciness: 0 Density: 1 Position Offset: {x: 0, y: 0.5, z: 0} - Scripts: - - Type: PlayerController - drag: 2 - currentState: 0 - maxMoveVel: 2 - moveForce: 50 - sprintMultiplier: 2 - rotationFactorPerFrame: 1 - maxJumpHeight: 4 - maxJumpTime: 0.75 - fallMultipler: 2 - lightMultiper: 0.75 - mediumMultiper: 0.5 - heavyMultiper: 0.25 - - Type: PickAndThrow - throwForce: [200, 300, 200] - item: 5 + Scripts: ~ - EID: 3 Name: Default IsActive: true @@ -126,12 +110,7 @@ Translate: {x: 0, y: 0, z: 0} Rotate: {x: 0, y: 0, z: 0} Scale: {x: 1, y: 1, z: 1} - Scripts: - - Type: SHADE_Scripting.ThirdPersonCamera - armLength: 2 - turnSpeedPitch: 0.300000012 - turnSpeedYaw: 0.5 - pitchClamp: 45 + Scripts: ~ - EID: 9 Name: Default IsActive: true @@ -186,9 +165,7 @@ Bounciness: 0 Density: 1 Position Offset: {x: 0, y: 0.5, z: 0} - Scripts: - - Type: Item - currCategory: 0 + Scripts: ~ - EID: 6 Name: AI IsActive: true @@ -223,14 +200,7 @@ Bounciness: 0 Density: 1 Position Offset: {x: 0, y: 0.5, z: 0} - Scripts: - - Type: AIPrototype - movementForceMultiplier: 100 - patrolSpeed: 0.400000006 - chaseSpeed: 0.800000012 - distanceToCapture: 1.20000005 - distanceToStartChase: 2 - distanceToEndChase: 2.5 + Scripts: ~ - EID: 7 Name: Default IsActive: true @@ -256,4 +226,23 @@ Color: {x: 1, y: 1, z: 1, w: 1} Layer: 4294967295 Strength: 0.25 + Scripts: ~ +- EID: 10 + Name: Default + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0, y: 2.45315814, z: -5} + Rotate: {x: -0, y: 0, z: -0} + Scale: {x: 2, y: 1, z: 1} + Collider Component: + Colliders: + - Is Trigger: false + Type: Box + Half Extents: {x: 2, y: 1, z: 1} + Friction: 0.400000006 + Bounciness: 0 + Density: 1 + Position Offset: {x: 0, y: 0, z: 0} Scripts: ~ \ No newline at end of file diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index ecacdc79..8281f114 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -92,7 +92,7 @@ namespace Sandbox floorRigidBody.SetType(SHRigidBodyComponent::Type::STATIC); - auto* floorBox = floorCollider.AddBoundingBox(); + floorCollider.AddBoundingBox(); // Create blank entity with a script //testObj = SHADE::SHEntityManager::CreateEntity(); diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index d7ae56c1..85d10c1a 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -224,9 +224,6 @@ namespace SHADE if (!component) return; - // Get transform component for extrapolating relative sizes - auto* transformComponent = SHComponentManager::GetComponent_s(component->GetEID()); - const auto componentType = rttr::type::get(*component); SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active"); ImGui::SameLine(); @@ -249,28 +246,21 @@ namespace SHADE if (collider->GetType() == SHCollisionShape::Type::BOX) { SHEditorWidgets::BeginPanel(std::format("{} Box #{}", ICON_FA_CUBE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y }); - SHEditorWidgets::CheckBox("Is Trigger", [collider]() {return collider->IsTrigger(); }, [collider](bool const& value) {collider->SetIsTrigger(value); }, "Is Trigger"); auto box = reinterpret_cast(collider->GetShape()); SHEditorWidgets::DragVec3 ( "Half Extents", { "X", "Y", "Z" }, - [box, transformComponent] { return (box->GetHalfExtents() * 2.0f) / transformComponent->GetWorldScale(); }, + [box] { return box->GetRelativeExtents(); }, [collider](SHVec3 const& vec) { collider->SetBoundingBox(vec); }); } else if (collider->GetType() == SHCollisionShape::Type::SPHERE) { SHEditorWidgets::BeginPanel(std::format("{} Sphere #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y }); - SHEditorWidgets::CheckBox("Is Trigger", [collider]() {return collider->IsTrigger(); }, [collider](bool const& value) {collider->SetIsTrigger(value); }, "Is Trigger"); auto sphere = reinterpret_cast(collider->GetShape()); SHEditorWidgets::DragFloat ( "Radius", - [sphere, transformComponent] - { - const SHVec3& TF_WORLD_SCALE = transformComponent->GetWorldScale(); - const float MAX_SCALE = SHMath::Max({ TF_WORLD_SCALE.x, TF_WORLD_SCALE.y, TF_WORLD_SCALE.z }); - return (sphere->GetRadius() / MAX_SCALE) * 2.0f; - }, + [sphere] { return sphere->GetRelativeRadius(); }, [collider](float const& value) { collider->SetBoundingSphere(value); }); } else if (collider->GetType() == SHCollisionShape::Type::CAPSULE) diff --git a/SHADE_Engine/src/Math/Geometry/SHBoundingBox.cpp b/SHADE_Engine/src/Math/Geometry/SHBoundingBox.cpp index d0ba2f14..5bbf5e15 100644 --- a/SHADE_Engine/src/Math/Geometry/SHBoundingBox.cpp +++ b/SHADE_Engine/src/Math/Geometry/SHBoundingBox.cpp @@ -25,11 +25,13 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ SHBoundingBox::SHBoundingBox() noexcept + : RelativeExtents { SHVec3::One } { type = Type::BOX; } SHBoundingBox::SHBoundingBox(const SHVec3& c, const SHVec3& hE) noexcept + : RelativeExtents { SHVec3::One } { type = Type::BOX; @@ -45,16 +47,18 @@ namespace SHADE type = Type::BOX; - Center = rhs.Center; - Extents = rhs.Extents; + Center = rhs.Center; + Extents = rhs.Extents; + RelativeExtents = rhs.RelativeExtents; } SHBoundingBox::SHBoundingBox(SHBoundingBox&& rhs) noexcept { type = Type::BOX; - Center = rhs.Center; - Extents = rhs.Extents; + Center = rhs.Center; + Extents = rhs.Extents; + RelativeExtents = rhs.RelativeExtents; } /*-----------------------------------------------------------------------------------*/ @@ -69,8 +73,9 @@ namespace SHADE } else if (this != &rhs) { - Center = rhs.Center; - Extents = rhs.Extents; + Center = rhs.Center; + Extents = rhs.Extents; + RelativeExtents = rhs.RelativeExtents; } return *this; @@ -84,8 +89,9 @@ namespace SHADE } else { - Center = rhs.Center; - Extents = rhs.Extents; + Center = rhs.Center; + Extents = rhs.Extents; + RelativeExtents = rhs.RelativeExtents; } return *this; @@ -100,11 +106,16 @@ namespace SHADE return Center; } - SHVec3 SHBoundingBox::GetHalfExtents() const noexcept + SHVec3 SHBoundingBox::GetWorldExtents() const noexcept { return Extents; } + const SHVec3& SHBoundingBox::GetRelativeExtents() const noexcept + { + return RelativeExtents; + } + SHVec3 SHBoundingBox::GetMin() const noexcept { return SHVec3{ Center.x - Extents.x, Center.y - Extents.y, Center.z - Extents.z }; @@ -124,9 +135,14 @@ namespace SHADE Center = newCenter; } - void SHBoundingBox::SetHalfExtents(const SHVec3& newHalfExtents) noexcept + void SHBoundingBox::SetWorldExtents(const SHVec3& newWorldExtents) noexcept { - Extents = newHalfExtents; + Extents = newWorldExtents; + } + + void SHBoundingBox::SetRelativeExtents(const SHVec3& newRelativeExtents) noexcept + { + RelativeExtents = newRelativeExtents; } void SHBoundingBox::SetMin(const SHVec3& min) noexcept diff --git a/SHADE_Engine/src/Math/Geometry/SHBoundingBox.h b/SHADE_Engine/src/Math/Geometry/SHBoundingBox.h index 5b3d26d5..e2757c17 100644 --- a/SHADE_Engine/src/Math/Geometry/SHBoundingBox.h +++ b/SHADE_Engine/src/Math/Geometry/SHBoundingBox.h @@ -54,21 +54,23 @@ namespace SHADE /* Getter Functions */ /*---------------------------------------------------------------------------------*/ - [[nodiscard]] SHVec3 GetCenter () const noexcept; - [[nodiscard]] SHVec3 GetHalfExtents() const noexcept; - [[nodiscard]] SHVec3 GetMin () const noexcept; - [[nodiscard]] SHVec3 GetMax () const noexcept; - [[nodiscard]] std::vector GetVertices () const noexcept; + [[nodiscard]] SHVec3 GetCenter () const noexcept; + [[nodiscard]] SHVec3 GetWorldExtents () const noexcept; + [[nodiscard]] const SHVec3& GetRelativeExtents () const noexcept; + [[nodiscard]] SHVec3 GetMin () const noexcept; + [[nodiscard]] SHVec3 GetMax () const noexcept; + [[nodiscard]] std::vector GetVertices () const noexcept; /*---------------------------------------------------------------------------------*/ /* Setter Functions */ /*---------------------------------------------------------------------------------*/ - void SetCenter (const SHVec3& newCenter) noexcept; - void SetHalfExtents (const SHVec3& newHalfExtents) noexcept; - void SetMin (const SHVec3& min) noexcept; - void SetMax (const SHVec3& max) noexcept; - void SetMinMax (const SHVec3& min, const SHVec3& max) noexcept; + void SetCenter (const SHVec3& newCenter) noexcept; + void SetWorldExtents (const SHVec3& newWorldExtents) noexcept; + void SetRelativeExtents (const SHVec3& newRelativeExtents) noexcept; + void SetMin (const SHVec3& min) noexcept; + void SetMax (const SHVec3& max) noexcept; + void SetMinMax (const SHVec3& min, const SHVec3& max) noexcept; /*---------------------------------------------------------------------------------*/ /* Function Members */ @@ -89,6 +91,13 @@ namespace SHADE [[nodiscard]] static bool Intersect (const SHBoundingBox& lhs, const SHBoundingBox& rhs) noexcept; [[nodiscard]] static SHBoundingBox BuildFromBoxes (const SHBoundingBox* boxes, size_t numBoxes) noexcept; [[nodiscard]] static SHBoundingBox BuildFromVertices (const SHVec3* vertices, size_t numVertices, size_t stride = 0) noexcept; + + private: + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + + SHVec3 RelativeExtents; }; diff --git a/SHADE_Engine/src/Math/Geometry/SHBoundingSphere.cpp b/SHADE_Engine/src/Math/Geometry/SHBoundingSphere.cpp index 62bf12b2..f843a6bb 100644 --- a/SHADE_Engine/src/Math/Geometry/SHBoundingSphere.cpp +++ b/SHADE_Engine/src/Math/Geometry/SHBoundingSphere.cpp @@ -25,11 +25,13 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ SHBoundingSphere::SHBoundingSphere() noexcept + : RelativeRadius { 1.0f } { type = Type::SPHERE; } SHBoundingSphere::SHBoundingSphere(const SHVec3& center, float radius) noexcept + : RelativeRadius { 1.0f } { type = Type::SPHERE; @@ -44,16 +46,18 @@ namespace SHADE type = Type::SPHERE; - Center = rhs.Center; - Radius = rhs.Radius; + Center = rhs.Center; + Radius = rhs.Radius; + RelativeRadius = rhs.RelativeRadius; } SHBoundingSphere::SHBoundingSphere(SHBoundingSphere&& rhs) noexcept { type = Type::SPHERE; - Center = rhs.Center; - Radius = rhs.Radius; + Center = rhs.Center; + Radius = rhs.Radius; + RelativeRadius = rhs.RelativeRadius; } /*-----------------------------------------------------------------------------------*/ @@ -68,8 +72,9 @@ namespace SHADE } else if (this != &rhs) { - Center = rhs.Center; - Radius = rhs.Radius; + Center = rhs.Center; + Radius = rhs.Radius; + RelativeRadius = rhs.RelativeRadius; } return *this; @@ -83,8 +88,9 @@ namespace SHADE } else { - Center = rhs.Center; - Radius = rhs.Radius; + Center = rhs.Center; + Radius = rhs.Radius; + RelativeRadius = rhs.RelativeRadius; } return *this; @@ -99,11 +105,16 @@ namespace SHADE return Center; } - float SHBoundingSphere::GetRadius() const noexcept + float SHBoundingSphere::GetWorldRadius() const noexcept { return Radius; } - + + float SHBoundingSphere::GetRelativeRadius() const noexcept + { + return RelativeRadius; + } + /*-----------------------------------------------------------------------------------*/ /* Setter Function Definitions */ /*-----------------------------------------------------------------------------------*/ @@ -113,9 +124,14 @@ namespace SHADE Center = center; } - void SHBoundingSphere::SetRadius(float radius) noexcept + void SHBoundingSphere::SetWorldRadius(float newWorldRadius) noexcept { - Radius = radius; + Radius = newWorldRadius; + } + + void SHBoundingSphere::SetRelativeRadius(float newRelativeRadius) noexcept + { + RelativeRadius = newRelativeRadius; } /*-----------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Math/Geometry/SHBoundingSphere.h b/SHADE_Engine/src/Math/Geometry/SHBoundingSphere.h index 001e889b..d94722d6 100644 --- a/SHADE_Engine/src/Math/Geometry/SHBoundingSphere.h +++ b/SHADE_Engine/src/Math/Geometry/SHBoundingSphere.h @@ -48,15 +48,17 @@ namespace SHADE /* Getter Functions */ /*---------------------------------------------------------------------------------*/ - [[nodiscard]] SHVec3 GetCenter () const noexcept; - [[nodiscard]] float GetRadius () const noexcept; + [[nodiscard]] SHVec3 GetCenter () const noexcept; + [[nodiscard]] float GetWorldRadius () const noexcept; + [[nodiscard]] float GetRelativeRadius () const noexcept; /*---------------------------------------------------------------------------------*/ /* Setter Functions */ /*---------------------------------------------------------------------------------*/ - void SetCenter (const SHVec3& center) noexcept; - void SetRadius (float radius) noexcept; + void SetCenter (const SHVec3& center) noexcept; + void SetWorldRadius (float newWorldRadius) noexcept; + void SetRelativeRadius (float newRelativeRadius) noexcept; /*---------------------------------------------------------------------------------*/ /* Function Members */ @@ -79,5 +81,12 @@ namespace SHADE [[nodiscard]] static SHBoundingSphere BuildFromSpheres (const SHBoundingSphere* spheres, size_t numSpheres) noexcept; [[nodiscard]] static SHBoundingSphere BuildFromVertices (const SHVec3* vertices, size_t numVertices, size_t stride = 0) noexcept; + private: + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + + float RelativeRadius; + }; } // namespace SHADE diff --git a/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp b/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp index af3965fb..93126fc5 100644 --- a/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp +++ b/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp @@ -48,6 +48,11 @@ namespace SHADE return orientation.ToEuler(); } + const SHVec3& SHColliderComponent::GetScale() const noexcept + { + return scale; + } + const SHColliderComponent::CollisionShapes& SHColliderComponent::GetCollisionShapes() const noexcept { return collisionShapes; @@ -75,12 +80,46 @@ namespace SHADE } - SHBoundingBox* SHColliderComponent::AddBoundingBox(const SHVec3& halfExtents, const SHVec3& posOffset) noexcept + void SHColliderComponent::RecomputeCollisionShapes() noexcept + { + for (auto& collisionShape : collisionShapes) + { + switch (collisionShape.GetType()) + { + case SHCollisionShape::Type::BOX: + { + auto* box = reinterpret_cast(collisionShape.GetShape()); + const SHVec3& RELATIVE_EXTENTS = box->GetRelativeExtents(); + + // Recompute world extents based on new scale and fixed relative extents + const SHVec3 WORLD_EXTENTS = RELATIVE_EXTENTS * (scale * 0.5f); + box->SetWorldExtents(WORLD_EXTENTS); + + continue; + } + case SHCollisionShape::Type::SPHERE: + { + auto* sphere = reinterpret_cast(collisionShape.GetShape()); + const float RELATIVE_RADIUS = sphere->GetRelativeRadius(); + + // Recompute world radius based on new scale and fixed radius + const float MAX_SCALE = SHMath::Max({ scale.x, scale.y, scale.z }); + const float WORLD_RADIUS = RELATIVE_RADIUS * MAX_SCALE * 0.5f; + sphere->SetWorldRadius(WORLD_RADIUS); + + continue; + } + default: continue; + } + } + } + + int SHColliderComponent::AddBoundingBox(const SHVec3& halfExtents, const SHVec3& posOffset, const SHVec3& rotOffset) noexcept { if (!system) { SHLOG_ERROR("Physics system does not exist, unable to add Box Collider!") - return nullptr; + return -1; } static constexpr auto TYPE = SHCollisionShape::Type::BOX; @@ -89,20 +128,21 @@ namespace SHADE collider.entityID = GetEID(); collider.SetPositionOffset(posOffset); + collider.SetRotationOffset(rotOffset); collider.SetBoundingBox(halfExtents); // Notify Physics System system->AddCollisionShape(GetEID(), &collider); - return reinterpret_cast(collider.GetShape()); + return static_cast(collisionShapes.size()) - 1; } - SHBoundingSphere* SHColliderComponent::AddBoundingSphere(float radius, const SHVec3& posOffset) noexcept + int SHColliderComponent::AddBoundingSphere(float radius, const SHVec3& posOffset) noexcept { if (!system) { SHLOG_ERROR("Physics system does not exist, unable to add Sphere Collider!") - return nullptr; + return -1; } static constexpr auto TYPE = SHCollisionShape::Type::SPHERE; @@ -116,7 +156,7 @@ namespace SHADE // Notify Physics System system->AddCollisionShape(GetEID(), &collider); - return reinterpret_cast(collider.GetShape()); + return static_cast(collisionShapes.size()) - 1; } void SHColliderComponent::RemoveCollider(int index) diff --git a/SHADE_Engine/src/Physics/Components/SHColliderComponent.h b/SHADE_Engine/src/Physics/Components/SHColliderComponent.h index ac5e7528..5f9b7a1b 100644 --- a/SHADE_Engine/src/Physics/Components/SHColliderComponent.h +++ b/SHADE_Engine/src/Physics/Components/SHColliderComponent.h @@ -72,6 +72,7 @@ namespace SHADE [[nodiscard]] const SHVec3& GetPosition () const noexcept; [[nodiscard]] const SHQuaternion& GetOrientation () const noexcept; [[nodiscard]] SHVec3 GetRotation () const noexcept; + [[nodiscard]] const SHVec3& GetScale () const noexcept; [[nodiscard]] const CollisionShapes& GetCollisionShapes() const noexcept; [[nodiscard]] SHCollisionShape& GetCollisionShape (int index); @@ -80,13 +81,15 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ - void OnCreate () override; - void OnDestroy () override; + void OnCreate () override; + void OnDestroy () override; - void RemoveCollider (int index); + void RecomputeCollisionShapes () noexcept; - SHBoundingBox* AddBoundingBox (const SHVec3& halfExtents = SHVec3::One, const SHVec3& posOffset = SHVec3::Zero) noexcept; - SHBoundingSphere* AddBoundingSphere (float radius = 1.0f, const SHVec3& posOffset = SHVec3::Zero) noexcept; + void RemoveCollider (int index); + + int AddBoundingBox (const SHVec3& halfExtents = SHVec3::One, const SHVec3& posOffset = SHVec3::Zero, const SHVec3& rotOffset = SHVec3::Zero) noexcept; + int AddBoundingSphere (float radius = 1.0f, const SHVec3& posOffset = SHVec3::Zero) noexcept; private: @@ -98,6 +101,7 @@ namespace SHADE SHVec3 position; SHQuaternion orientation; + SHVec3 scale; CollisionShapes collisionShapes; RTTR_ENABLE() diff --git a/SHADE_Engine/src/Physics/SHCollisionShape.cpp b/SHADE_Engine/src/Physics/SHCollisionShape.cpp index 78ec36f9..c8f8020c 100644 --- a/SHADE_Engine/src/Physics/SHCollisionShape.cpp +++ b/SHADE_Engine/src/Physics/SHCollisionShape.cpp @@ -15,8 +15,8 @@ // Project Headers #include "Math/Geometry/SHBoundingBox.h" #include "Math/Geometry/SHBoundingSphere.h" -#include "Math/Transform/SHTransformComponent.h" #include "Math/SHMathHelpers.h" +#include "Physics/Components/SHColliderComponent.h" #include "Reflection/SHReflectionMetadata.h" namespace SHADE @@ -178,56 +178,43 @@ namespace SHADE { dirty = true; - // Set the half extents relative to transform - SHVec3 worldHalfExtents = halfExtents; + const auto* colliderComponent = SHComponentManager::GetComponent(entityID); + // Set the half extents relative to world scale + const SHVec3 WORLD_EXTENTS = halfExtents * colliderComponent->GetScale() * 0.5f; - const auto* transformComponent = SHComponentManager::GetComponent_s(entityID); - if (transformComponent != nullptr) - worldHalfExtents *= (transformComponent->GetWorldScale() * 0.5f); - - if (type == Type::BOX) - { - auto* box = reinterpret_cast(shape); - box->SetHalfExtents(worldHalfExtents); - } - else + if (type != Type::BOX) { type = Type::BOX; delete shape; - shape = new SHBoundingBox{ positionOffset, worldHalfExtents }; + shape = new SHBoundingBox{ positionOffset, WORLD_EXTENTS }; } + + auto* box = reinterpret_cast(shape); + box->SetWorldExtents(WORLD_EXTENTS); + box->SetRelativeExtents(halfExtents); } void SHCollisionShape::SetBoundingSphere(float radius) { dirty = true; - // Set the radius relative to transform - float worldRadius = radius; + const auto* colliderComponent = SHComponentManager::GetComponent(entityID); + // Set the radius relative to world scale + const SHVec3 WORLD_SCALE = colliderComponent->GetScale(); + const float MAX_SCALE = SHMath::Max({ WORLD_SCALE.x, WORLD_SCALE.y, WORLD_SCALE.z }); + const float WORLD_RADIUS = radius * MAX_SCALE * 0.5f; - const auto* transformComponent = SHComponentManager::GetComponent_s(entityID); - if (transformComponent != nullptr) - { - const SHVec3 TF_WORLD_SCALE = transformComponent->GetWorldScale(); - const float MAX_SCALE = SHMath::Max({ TF_WORLD_SCALE.x, TF_WORLD_SCALE.y, TF_WORLD_SCALE.z }); - - worldRadius *= MAX_SCALE * 0.5f; - } - - if (type == Type::SPHERE) - { - auto* sphere = reinterpret_cast(shape); - sphere->SetRadius(worldRadius); - } - else + if (type != Type::SPHERE) { type = Type::SPHERE; delete shape; - shape = new SHBoundingSphere{ positionOffset, worldRadius }; + shape = new SHBoundingSphere{ positionOffset, WORLD_RADIUS }; } - + + auto* sphere = reinterpret_cast(shape); + sphere->SetWorldRadius(WORLD_RADIUS); } void SHCollisionShape::SetIsTrigger(bool trigger) noexcept @@ -299,14 +286,14 @@ namespace SHADE { const auto* RHS_BOX = reinterpret_cast(rhs); - shape = new SHBoundingBox{ positionOffset, RHS_BOX->GetHalfExtents() }; + shape = new SHBoundingBox{ positionOffset, RHS_BOX->GetWorldExtents() }; break; } case Type::SPHERE: { const auto* RHS_SPHERE = reinterpret_cast(rhs); - shape = new SHBoundingSphere{ positionOffset, RHS_SPHERE->GetRadius() }; + shape = new SHBoundingSphere{ positionOffset, RHS_SPHERE->GetWorldRadius() }; break; } default: break; diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp index 5658f304..00c6943b 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp @@ -137,7 +137,7 @@ namespace SHADE case SHCollisionShape::Type::BOX: { const auto* box = reinterpret_cast(collider->GetShape()); - rp3d::BoxShape* newBox = factory->createBoxShape(box->GetHalfExtents()); + rp3d::BoxShape* newBox = factory->createBoxShape(box->GetWorldExtents()); rp3dBody->addCollider(newBox, OFFSETS); break; @@ -145,7 +145,7 @@ namespace SHADE case SHCollisionShape::Type::SPHERE: { const auto* sphere = reinterpret_cast(collider->GetShape()); - rp3d::SphereShape* newSphere = factory->createSphereShape(sphere->GetRadius()); + rp3d::SphereShape* newSphere = factory->createSphereShape(sphere->GetWorldRadius()); rp3dBody->addCollider(newSphere, OFFSETS); break; @@ -193,7 +193,7 @@ namespace SHADE const auto* box = reinterpret_cast(collider.GetShape()); auto* rp3dBoxShape = reinterpret_cast(rp3dCollider->getCollisionShape()); - rp3dBoxShape->setHalfExtents(box->GetHalfExtents()); + rp3dBoxShape->setHalfExtents(box->GetWorldExtents()); break; } @@ -202,7 +202,7 @@ namespace SHADE const auto* sphere = reinterpret_cast(collider.GetShape()); auto* rp3dSphereShape = reinterpret_cast(rp3dCollider->getCollisionShape()); - rp3dSphereShape->setRadius(sphere->GetRadius()); + rp3dSphereShape->setRadius(sphere->GetWorldRadius()); break; } diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index 078a5d6a..437b5ff8 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -395,6 +395,7 @@ namespace SHADE { const auto WORLD_POS = transformComponent->GetWorldPosition(); const auto WORLD_ROT = transformComponent->GetWorldOrientation(); + const auto WORLD_SCL = transformComponent->GetWorldScale(); physicsObject.SetPosition(WORLD_POS); physicsObject.SetOrientation(WORLD_ROT); @@ -409,8 +410,11 @@ namespace SHADE if (colliderComponent) { - colliderComponent->position = WORLD_POS; - colliderComponent->orientation = WORLD_ROT; + colliderComponent->position = WORLD_POS; + colliderComponent->orientation = WORLD_ROT; + colliderComponent->scale = WORLD_SCL; + + colliderComponent->RecomputeCollisionShapes(); } } @@ -744,8 +748,9 @@ namespace SHADE { SHASSERT(colliderComponent != nullptr, "Collider Component was not added to Entity " + std::to_string(ENTITY_ID) + "!"); - colliderComponent->position = transformComponent->GetWorldPosition(); - colliderComponent->orientation = transformComponent->GetWorldOrientation(); + colliderComponent->position = transformComponent->GetWorldPosition(); + colliderComponent->orientation = transformComponent->GetWorldOrientation(); + colliderComponent->scale = transformComponent->GetWorldScale(); if (physicsObject->rp3dBody == nullptr) { diff --git a/SHADE_Engine/src/Serialization/SHYAMLConverters.h b/SHADE_Engine/src/Serialization/SHYAMLConverters.h index 76be74ce..1b93c63a 100644 --- a/SHADE_Engine/src/Serialization/SHYAMLConverters.h +++ b/SHADE_Engine/src/Serialization/SHYAMLConverters.h @@ -131,13 +131,13 @@ namespace YAML case SHCollisionShape::Type::BOX: { auto const bb = reinterpret_cast(rhs.GetShape()); - node[HalfExtents] = bb->GetHalfExtents(); + node[HalfExtents] = bb->GetRelativeExtents(); } break; case SHCollisionShape::Type::SPHERE: { auto const bs = reinterpret_cast(rhs.GetShape()); - node[Radius] = bs->GetRadius(); + node[Radius] = bs->GetRelativeRadius(); } break; case SHCollisionShape::Type::CAPSULE: break; @@ -168,7 +168,7 @@ namespace YAML case SHCollisionShape::Type::BOX: { if (node[HalfExtents].IsDefined()) - rhs.SetBoundingBox(node[HalfExtents].as() * 2.0f); + rhs.SetBoundingBox(node[HalfExtents].as()); } break; case SHCollisionShape::Type::SPHERE: diff --git a/SHADE_Managed/src/Components/Collider.cxx b/SHADE_Managed/src/Components/Collider.cxx index dc5d27af..0e916b7b 100644 --- a/SHADE_Managed/src/Components/Collider.cxx +++ b/SHADE_Managed/src/Components/Collider.cxx @@ -55,11 +55,11 @@ namespace SHADE } Vector3 BoxCollider::HalfExtents::get() { - return Convert::ToCLI(getNativeBoundObject().GetHalfExtents()); + return Convert::ToCLI(getNativeBoundObject().GetWorldExtents()); } void BoxCollider::HalfExtents::set(Vector3 value) { - getNativeBoundObject().SetHalfExtents(Convert::ToNative(value)); + getNativeBoundObject().SetWorldExtents(Convert::ToNative(value)); } Vector3 BoxCollider::Min::get() { @@ -103,11 +103,11 @@ namespace SHADE } float SphereCollider::Radius::get() { - return getNativeBoundObject().GetRadius(); + return getNativeBoundObject().GetWorldRadius(); } void SphereCollider::Radius::set(float value) { - getNativeBoundObject().SetRadius(value); + getNativeBoundObject().SetWorldRadius(value); } /*---------------------------------------------------------------------------------*/ From ddd93a85f4f7791168b2b122f124a579fc1d1725 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 8 Nov 2022 00:53:47 +0800 Subject: [PATCH 21/59] Added support for null GameObjects (loading is buggy) --- Assets/Scenes/M2Scene.shade | 5 +- SHADE_Engine/src/Editor/SHEditorUI.cpp | 11 +- SHADE_Engine/src/Editor/SHEditorUI.h | 6 +- SHADE_Managed/src/Editor/Editor.cxx | 7 +- SHADE_Managed/src/Engine/GameObject.cxx | 104 +++++++++++++----- SHADE_Managed/src/Engine/GameObject.hxx | 18 ++- .../src/Serialisation/ReflectionUtilities.cxx | 6 +- 7 files changed, 119 insertions(+), 38 deletions(-) diff --git a/Assets/Scenes/M2Scene.shade b/Assets/Scenes/M2Scene.shade index 443d4a87..585582e4 100644 --- a/Assets/Scenes/M2Scene.shade +++ b/Assets/Scenes/M2Scene.shade @@ -256,4 +256,7 @@ Color: {x: 1, y: 1, z: 1, w: 1} Layer: 4294967295 Strength: 0.25 - Scripts: ~ \ No newline at end of file + Scripts: + - Type: PickAndThrow + throwForce: [100, 200, 100] + item: 1 \ No newline at end of file diff --git a/SHADE_Engine/src/Editor/SHEditorUI.cpp b/SHADE_Engine/src/Editor/SHEditorUI.cpp index cc63c565..49cfbfd6 100644 --- a/SHADE_Engine/src/Editor/SHEditorUI.cpp +++ b/SHADE_Engine/src/Editor/SHEditorUI.cpp @@ -288,7 +288,7 @@ namespace SHADE return CHANGED; } - bool SHEditorUI::InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered) + bool SHEditorUI::InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered, bool alwaysNull) { ImGui::Text(label.c_str()); if (isHovered) @@ -296,7 +296,7 @@ namespace SHADE ImGui::SameLine(); SHEntity* entity = SHEntityManager::GetEntityByID(value); std::ostringstream oss; - if (entity) + if (!alwaysNull && entity) { oss << value << ": " << entity->name; } @@ -314,6 +314,13 @@ namespace SHADE SHDragDrop::EndTarget(); } } + ImGui::SameLine(); + if (ImGui::Button("Clear")) + { + value = MAX_EID; + changed = true; + } + return changed; } diff --git a/SHADE_Engine/src/Editor/SHEditorUI.h b/SHADE_Engine/src/Editor/SHEditorUI.h index d4104639..4e8f4400 100644 --- a/SHADE_Engine/src/Editor/SHEditorUI.h +++ b/SHADE_Engine/src/Editor/SHEditorUI.h @@ -313,8 +313,12 @@ namespace SHADE /// Label used to identify this widget. /// Reference to the variable to store the result. /// + /// If set, the field displayed will always be blank regardless of specified + /// GameObject. + /// /// True if the value was changed. - static bool InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered = nullptr); + static bool InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered = nullptr, bool alwaysNull = false); /// /// Creates a combo box for enumeration input. /// diff --git a/SHADE_Managed/src/Editor/Editor.cxx b/SHADE_Managed/src/Editor/Editor.cxx index 55fe91da..2afe9697 100644 --- a/SHADE_Managed/src/Editor/Editor.cxx +++ b/SHADE_Managed/src/Editor/Editor.cxx @@ -290,9 +290,14 @@ namespace SHADE { GameObject gameObj = safe_cast(field->GetValue(object)); uint32_t entityId = gameObj.GetEntity(); - if (SHEditorUI::InputGameObjectField(Convert::ToNative(field->Name), entityId, &isHovered)) + if (SHEditorUI::InputGameObjectField(Convert::ToNative(field->Name), entityId, &isHovered, !gameObj)) { GameObject newVal = GameObject(entityId); + if (entityId != MAX_EID) + { + // Null GameObject set + newVal = GameObject(entityId); + } field->SetValue(object, newVal); registerUndoAction(object, field, newVal, gameObj); } diff --git a/SHADE_Managed/src/Engine/GameObject.cxx b/SHADE_Managed/src/Engine/GameObject.cxx index 7ceabfed..9f15c6c9 100644 --- a/SHADE_Managed/src/Engine/GameObject.cxx +++ b/SHADE_Managed/src/Engine/GameObject.cxx @@ -6,9 +6,9 @@ \brief Contains the definition of the functions for the GameObject managed class. Note: This file is written in C++17/CLI. - + Copyright (C) 2021 DigiPen Institute of Technology. -Reproduction or disclosure of this file or its contents without the prior written consent +Reproduction or disclosure of this file or its contents without the prior written consent of DigiPen Institute of Technology is prohibited. *//*************************************************************************************/ // Precompiled Headers @@ -36,10 +36,12 @@ namespace SHADE void GameObject::Destroy(GameObject obj) { + if (!obj.valid) + throw gcnew System::NullReferenceException("Attempted to destroy a null GameObject."); SHEntityManager::DestroyEntity(static_cast(obj.GetEntity())); } - System::Nullable GameObject::Find(System::String ^ name) + System::Nullable GameObject::Find(System::String^ name) { // Search the GameObjectLibrary for an Entity with the specified name const auto ENTITY_ID = SHEntityManager::GetEntityByName(Convert::ToNative(name)); @@ -50,21 +52,27 @@ namespace SHADE return GameObject(ENTITY_ID); } - + /*---------------------------------------------------------------------------------*/ /* Properties */ /*---------------------------------------------------------------------------------*/ System::String^ GameObject::Name::get() { + if (!valid) + throw gcnew System::NullReferenceException(); return Convert::ToCLI(GetNativeEntity().name); - - } + + } bool GameObject::IsActiveSelf::get() { + if (!valid) + throw gcnew System::NullReferenceException(); return GetNativeEntity().GetActive(); } bool GameObject::IsActiveInHierarchy::get() { + if (!valid) + throw gcnew System::NullReferenceException(); auto node = SHSceneManager::GetCurrentSceneGraph().GetNode(GetEntity()); if (!node) { @@ -75,39 +83,49 @@ namespace SHADE } Entity GameObject::EntityId::get() { + if (!valid) + throw gcnew System::NullReferenceException(); return entity; } GameObject^ GameObject::Parent::get() { - const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph(); - const auto* ROOT = SCENE_GRAPH.GetRoot(); + if (!valid) + throw gcnew System::NullReferenceException(); + const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph(); + const auto* ROOT = SCENE_GRAPH.GetRoot(); - const auto* NODE = SCENE_GRAPH.GetNode(entity); - if (NODE == nullptr) - throw gcnew System::InvalidOperationException("Unable to retrieve SceneGraphNode for Entity " + entity.ToString()); + const auto* NODE = SCENE_GRAPH.GetNode(entity); + if (NODE == nullptr) + throw gcnew System::InvalidOperationException("Unable to retrieve SceneGraphNode for Entity " + entity.ToString()); - const auto* PARENT = NODE->GetParent(); - return PARENT != ROOT ? gcnew GameObject(PARENT->GetEntityID()) : nullptr; + const auto* PARENT = NODE->GetParent(); + return PARENT != ROOT ? gcnew GameObject(PARENT->GetEntityID()) : nullptr; } void GameObject::Parent::set(GameObject^ newParent) { - const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph(); + if (!valid) + throw gcnew System::NullReferenceException(); + const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph(); - if (newParent == nullptr) - SCENE_GRAPH.SetParent(entity, nullptr); - else - SCENE_GRAPH.SetParent(entity, newParent->EntityId); + if (newParent == nullptr) + SCENE_GRAPH.SetParent(entity, nullptr); + else + SCENE_GRAPH.SetParent(entity, newParent->EntityId); } - + /*---------------------------------------------------------------------------------*/ /* GameObject Property Functions */ /*---------------------------------------------------------------------------------*/ void GameObject::SetName(System::String^ name) { + if (!valid) + throw gcnew System::NullReferenceException(); GetNativeEntity().name = Convert::ToNative(name); } void GameObject::SetActive(bool active) { + if (!valid) + throw gcnew System::NullReferenceException(); GetNativeEntity().SetActive(active); } @@ -117,63 +135,83 @@ namespace SHADE generic T GameObject::AddComponent() { + if (!valid) + throw gcnew System::NullReferenceException(); return ECS::AddComponent(entity); } generic T GameObject::GetComponent() { + if (!valid) + throw gcnew System::NullReferenceException(); return ECS::GetComponent(entity); } generic T GameObject::GetComponentInChildren() { + if (!valid) + throw gcnew System::NullReferenceException(); return ECS::GetComponentInChildren(entity); } generic T GameObject::EnsureComponent() { + if (!valid) + throw gcnew System::NullReferenceException(); return ECS::EnsureComponent(entity); } generic void GameObject::RemoveComponent() { + if (!valid) + throw gcnew System::NullReferenceException(); ECS::RemoveComponent(entity); } - + /*---------------------------------------------------------------------------------*/ /* Script Access Functions */ /*---------------------------------------------------------------------------------*/ generic T GameObject::AddScript() { + if (!valid) + throw gcnew System::NullReferenceException(); return ScriptStore::AddScript(entity); } generic T GameObject::GetScript() { + if (!valid) + throw gcnew System::NullReferenceException(); return ScriptStore::GetScript(entity); } generic T GameObject::GetScriptInChildren() { + if (!valid) + throw gcnew System::NullReferenceException(); return ScriptStore::GetScriptInChildren(entity); } generic System::Collections::Generic::IEnumerable^ GameObject::GetScripts() { + if (!valid) + throw gcnew System::NullReferenceException(); return ScriptStore::GetScripts(entity); } generic void GameObject::RemoveScript() { + if (!valid) + throw gcnew System::NullReferenceException(); ScriptStore::RemoveScript(entity); } @@ -181,20 +219,24 @@ namespace SHADE /* Constructors */ /*---------------------------------------------------------------------------------*/ GameObject::GameObject(const SHEntity& entity) - : entity { entity.GetEID() } - , children{ gcnew System::Collections::ArrayList } + : entity{ entity.GetEID() } + , children{ gcnew System::Collections::ArrayList } + , valid{ true } {} GameObject::GameObject(Entity entity) - : entity { entity } - , children{ gcnew System::Collections::ArrayList } + : entity{ entity } + , children{ gcnew System::Collections::ArrayList } + , valid{ true } {} - + /*---------------------------------------------------------------------------------*/ /* Getters */ /*---------------------------------------------------------------------------------*/ SHEntity& GameObject::GetNativeEntity() { + if (!valid) + throw gcnew System::NullReferenceException(); SHEntity* nativeEntity = SHEntityManager::GetEntityByID(entity); if (nativeEntity == nullptr) throw gcnew System::InvalidOperationException("[GameObject] Unable to obtain native Entity for GameObject."); @@ -202,14 +244,22 @@ namespace SHADE return *nativeEntity; } + /*---------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*---------------------------------------------------------------------------------*/ + GameObject::operator bool(GameObject gameObj) + { + return gameObj.valid; + } + /*---------------------------------------------------------------------------------*/ /* IEquatable */ /*---------------------------------------------------------------------------------*/ bool GameObject::Equals(GameObject other) { - return entity == other.entity; + return (!valid && !other.valid) || entity == other.entity; } - + /*---------------------------------------------------------------------------------*/ /* Object */ /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Managed/src/Engine/GameObject.hxx b/SHADE_Managed/src/Engine/GameObject.hxx index 99296a91..525b6c10 100644 --- a/SHADE_Managed/src/Engine/GameObject.hxx +++ b/SHADE_Managed/src/Engine/GameObject.hxx @@ -29,8 +29,8 @@ namespace SHADE /* Class Definitions */ /*---------------------------------------------------------------------------------*/ /// - /// Lightweight object for an PlushieEngine Entity that allows for easy access - /// to Component and Script operations. + /// Lightweight object for an Entity that allows for easy access to Component and + /// Script operations. /// public value class GameObject : public System::IEquatable { @@ -98,8 +98,8 @@ namespace SHADE /// property GameObject^ Parent { - GameObject^ get(); - void set(GameObject^); + GameObject^ get(); + void set(GameObject^); } /*-----------------------------------------------------------------------------*/ @@ -247,12 +247,22 @@ namespace SHADE /// Native Entity object that this GameObject represents. SHEntity& GetNativeEntity(); + /*-----------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*-----------------------------------------------------------------------------*/ + /// + /// Implicit conversion operator to enable checking if a GameObject is valid. + /// + /// GameObjects to check. + static operator bool(GameObject gameObj); + private: /*-----------------------------------------------------------------------------*/ /* Data Members */ /*-----------------------------------------------------------------------------*/ Entity entity; System::Collections::ArrayList^ children; + bool valid; public: /*-----------------------------------------------------------------------------*/ diff --git a/SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx b/SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx index 4b4e44fc..66ef493a 100644 --- a/SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx +++ b/SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx @@ -171,7 +171,7 @@ namespace SHADE else if (fieldInfo->FieldType == GameObject::typeid) { GameObject gameObj = safe_cast(fieldInfo->GetValue(object)); - fieldNode = gameObj.GetEntity(); + fieldNode = gameObj ? gameObj.GetEntity() : MAX_EID; } else // Not any of the supported types { @@ -250,7 +250,9 @@ namespace SHADE } else if (fieldInfo->FieldType == GameObject::typeid) { - fieldInfo->SetValue(object, GameObject(node.as())); + const uint32_t EID = node.as(); + fieldInfo->SetValue(object, EID == MAX_EID ? GameObject() : GameObject(EID)); + Debug::LogError(std::to_string(EID)); } else // Not any of the supported types { From e0481ad8af4587008fe0b6d05c94f1efdaa17ce3 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 8 Nov 2022 13:47:39 +0800 Subject: [PATCH 22/59] Removed debug log --- SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx | 1 - 1 file changed, 1 deletion(-) diff --git a/SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx b/SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx index 66ef493a..651afb73 100644 --- a/SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx +++ b/SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx @@ -252,7 +252,6 @@ namespace SHADE { const uint32_t EID = node.as(); fieldInfo->SetValue(object, EID == MAX_EID ? GameObject() : GameObject(EID)); - Debug::LogError(std::to_string(EID)); } else // Not any of the supported types { From e3369c688d12a1ff1e445b4ed7b51f238e74838c Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 8 Nov 2022 13:49:49 +0800 Subject: [PATCH 23/59] Added comment to document invalid/null GameObject usage --- SHADE_Managed/src/Engine/GameObject.hxx | 1 + 1 file changed, 1 insertion(+) diff --git a/SHADE_Managed/src/Engine/GameObject.hxx b/SHADE_Managed/src/Engine/GameObject.hxx index 525b6c10..030b917c 100644 --- a/SHADE_Managed/src/Engine/GameObject.hxx +++ b/SHADE_Managed/src/Engine/GameObject.hxx @@ -31,6 +31,7 @@ namespace SHADE /// /// Lightweight object for an Entity that allows for easy access to Component and /// Script operations. + /// Can be set to a invalid/null GameObject by default construction. /// public value class GameObject : public System::IEquatable { From 1f4a530dccaa3f78db5833d3b494de26b36c9f81 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 8 Nov 2022 14:06:01 +0800 Subject: [PATCH 24/59] Fixed compile error in Release --- SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h index 022d4b62..fc348487 100644 --- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h +++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h @@ -81,9 +81,8 @@ namespace SHADE //! The push constant data for the command buffer uint8_t pushConstantData[PUSH_CONSTANT_SIZE]; -#ifdef _DEBUG + //! Depth of segmenting of the command buffer (used for debug data) int segmentDepth; -#endif /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER FUNCTIONS */ From ee814fa61d418428bcf92c381feb33cc361fd147 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 8 Nov 2022 15:02:08 +0800 Subject: [PATCH 25/59] Added support for parameter-less CallbackActions and CallbackEvents --- SHADE_CSharp/src/Events/CallbackAction.cs | 93 ++++++++++++++++ SHADE_CSharp/src/Events/CallbackAction.tt | 8 +- SHADE_CSharp/src/Events/CallbackEvent.cs | 126 ++++++++++++++++++---- SHADE_CSharp/src/Events/CallbackEvent.tt | 24 ++--- TempScriptsFolder/RaccoonSpin.cs | 4 + 5 files changed, 219 insertions(+), 36 deletions(-) diff --git a/SHADE_CSharp/src/Events/CallbackAction.cs b/SHADE_CSharp/src/Events/CallbackAction.cs index 623e4f59..b6082c0c 100644 --- a/SHADE_CSharp/src/Events/CallbackAction.cs +++ b/SHADE_CSharp/src/Events/CallbackAction.cs @@ -34,6 +34,99 @@ namespace SHADE Object TargetObject { get; } } + /// + /// Represents a function call that can be serialised and put togetheer with scripts. + /// This variant accepts functions with 0 parameter. + /// + public class CallbackAction : ICallbackAction + { + #region Properties ------------------------------------------------------------ + /// + public Object TargetObject { get; private set; } + /// + public string TargetMethodName => targetMethod == null ? "" : targetMethod.Name; + /// + public bool IsRuntimeAction => targetAction != null; + #endregion + + #region Fields ------------------------------------------------------------------ + private MethodInfo targetMethod; + private Action targetAction; + private Object[] parameters; + #endregion + + #region Constructors ------------------------------------------------------------ + /// + /// Constructs an empty Callback action. + /// + public CallbackAction() {} + /// + /// Constructs a CallbackAction that represents a call to the specified static + /// method. + /// + /// Method to call. + /// + /// Thrown if a method that is not compatible with the target is specified. The method's + /// source type must match the target's type. + /// + public CallbackAction(MethodInfo method) + { + // No errors, assign + targetMethod = method; + + // Create storage for parameters for calling + parameters = new Object[0]; + } + /// + /// Constructs a CallbackAction that represents a call to a specified member + /// method on the specified target. + /// + /// Object to call the method on. + /// Method to call. + /// + /// Thrown if a method that is not compatible with the target is specified. The method's + /// source type must match the target's type. + /// + public CallbackAction(Object target, MethodInfo method) + { + // Error Checks + if (method.DeclaringType != target.GetType()) + throw new ArgumentException("[CallbackAction] Attempted register an action using an incompatible target object and method."); + + // No errors, assign + TargetObject = target; + targetMethod = method; + + // Create storage for parameters for calling + parameters = new Object[0]; + } + /// + /// Constructs a Callback action based on an action. + /// + /// Action that wraps a function to be called. + public CallbackAction(Action action) + { + targetAction = action; + } + #endregion + + #region Usage Functions --------------------------------------------------------- + /// + /// Invokes the CallbackAction's stored method/action with the specified parameters. + /// + public void Invoke() + { + if (targetAction != null) + { + targetAction.Invoke(); + } + else if (targetMethod != null) + { + _ = targetMethod.Invoke(TargetObject, parameters); + } + } + #endregion + } /// /// Represents a function call that can be serialised and put togetheer with scripts. /// This variant accepts functions with 1 parameter. diff --git a/SHADE_CSharp/src/Events/CallbackAction.tt b/SHADE_CSharp/src/Events/CallbackAction.tt index 34789b67..3fbb7617 100644 --- a/SHADE_CSharp/src/Events/CallbackAction.tt +++ b/SHADE_CSharp/src/Events/CallbackAction.tt @@ -50,12 +50,12 @@ namespace SHADE Object TargetObject { get; } } -<# for (int i = 1; i <= max; ++i) { #> +<# for (int i = 0; i <= max; ++i) { #> /// /// Represents a function call that can be serialised and put togetheer with scripts. /// This variant accepts functions with <#=i#> parameter<# if (i > 1) {#>s<#} #>. /// - public class CallbackAction<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>> : ICallbackAction + public class CallbackAction<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #> : ICallbackAction { #region Properties ------------------------------------------------------------ /// @@ -68,7 +68,7 @@ namespace SHADE #region Fields ------------------------------------------------------------------ private MethodInfo targetMethod; - private Action<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>> targetAction; + private Action<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #> targetAction; private Object[] parameters; #endregion @@ -121,7 +121,7 @@ namespace SHADE /// Constructs a Callback action based on an action. /// /// Action that wraps a function to be called. - public CallbackAction(Action<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>> action) + public CallbackAction(Action<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #> action) { targetAction = action; } diff --git a/SHADE_CSharp/src/Events/CallbackEvent.cs b/SHADE_CSharp/src/Events/CallbackEvent.cs index ec464ba9..2c3cc388 100644 --- a/SHADE_CSharp/src/Events/CallbackEvent.cs +++ b/SHADE_CSharp/src/Events/CallbackEvent.cs @@ -45,6 +45,92 @@ namespace SHADE IEnumerable Actions { get; } } + /// + /// A container of CallbackActions that is correlated to a specific scenario as + /// specified by the user of this class. + /// This variant accepts CallbackEvents with 1 generic parameter. + /// + public class CallbackEvent : ICallbackEvent + { + #region Properties -------------------------------------------------------------- + /// + public IEnumerable Actions => actions; + #endregion + + #region Fields ------------------------------------------------------------------ + private List actions = new List(); + #endregion + + #region Usage Functions --------------------------------------------------------- + /// + public void RegisterAction() + { + actions.Add(new CallbackAction()); + } + /// + public void RegisterAction(ICallbackAction action) + { + // Check if valid action + if (action.GetType() != typeof(CallbackAction)) + { + Debug.LogWarning("Attempted to register an invalid CallbackAction type. Ignoring.", this); + return; + } + + actions.Add(action); + } + /// + /// Adds a CallbackAction into the event. + /// + /// CallbackAction to add. + public void RegisterAction(CallbackAction action) + { + actions.Add(action); + } + /// + /// Constructs and adds a CallbackAction into the event. + /// + /// System.Action to add as a CallbackAction. + public void RegisterAction(Action action) + { + actions.Add(new CallbackAction(action)); + } + /// + /// Constructs and adds a CallbackAction into the event. + /// + /// Object to call the method on. + /// Method to call. + public void RegisterAction(Object target, MethodInfo method) + { + actions.Add(new CallbackAction(target, method)); + } + /// + public void DeregisterAction(ICallbackAction action) + { + if (!actions.Remove(action)) + { + Debug.LogWarning("Attempted to deregister invalid action. Ignored.", this); + } + } + /// + /// Invokes all stored CallbackActions with the specified parameters. + /// + public void Invoke() + { + foreach (CallbackAction action in actions) + { + try + { + action.Invoke(); + } + catch (Exception e) + { + Debug.LogException(e, this); + } + } + } + #endregion + } /// /// A container of CallbackActions that is correlated to a specific scenario as /// specified by the user of this class. @@ -88,7 +174,7 @@ namespace SHADE actions.Add(action); } /// - /// Constructs and adds a CallbackACtion into the event. + /// Constructs and adds a CallbackAction into the event. /// /// System.Action to add as a CallbackAction. public void RegisterAction(Action action) @@ -96,7 +182,7 @@ namespace SHADE actions.Add(new CallbackAction(action)); } /// - /// Constructs and adds a CallbackACtion into the event. + /// Constructs and adds a CallbackAction into the event. /// /// Object to call the method on. /// Method to call. @@ -174,7 +260,7 @@ namespace SHADE actions.Add(action); } /// - /// Constructs and adds a CallbackACtion into the event. + /// Constructs and adds a CallbackAction into the event. /// /// System.Action to add as a CallbackAction. public void RegisterAction(Action action) @@ -182,7 +268,7 @@ namespace SHADE actions.Add(new CallbackAction(action)); } /// - /// Constructs and adds a CallbackACtion into the event. + /// Constructs and adds a CallbackAction into the event. /// /// Object to call the method on. /// Method to call. @@ -260,7 +346,7 @@ namespace SHADE actions.Add(action); } /// - /// Constructs and adds a CallbackACtion into the event. + /// Constructs and adds a CallbackAction into the event. /// /// System.Action to add as a CallbackAction. public void RegisterAction(Action action) @@ -268,7 +354,7 @@ namespace SHADE actions.Add(new CallbackAction(action)); } /// - /// Constructs and adds a CallbackACtion into the event. + /// Constructs and adds a CallbackAction into the event. /// /// Object to call the method on. /// Method to call. @@ -346,7 +432,7 @@ namespace SHADE actions.Add(action); } /// - /// Constructs and adds a CallbackACtion into the event. + /// Constructs and adds a CallbackAction into the event. /// /// System.Action to add as a CallbackAction. public void RegisterAction(Action action) @@ -354,7 +440,7 @@ namespace SHADE actions.Add(new CallbackAction(action)); } /// - /// Constructs and adds a CallbackACtion into the event. + /// Constructs and adds a CallbackAction into the event. /// /// Object to call the method on. /// Method to call. @@ -432,7 +518,7 @@ namespace SHADE actions.Add(action); } /// - /// Constructs and adds a CallbackACtion into the event. + /// Constructs and adds a CallbackAction into the event. /// /// System.Action to add as a CallbackAction. public void RegisterAction(Action action) @@ -440,7 +526,7 @@ namespace SHADE actions.Add(new CallbackAction(action)); } /// - /// Constructs and adds a CallbackACtion into the event. + /// Constructs and adds a CallbackAction into the event. /// /// Object to call the method on. /// Method to call. @@ -518,7 +604,7 @@ namespace SHADE actions.Add(action); } /// - /// Constructs and adds a CallbackACtion into the event. + /// Constructs and adds a CallbackAction into the event. /// /// System.Action to add as a CallbackAction. public void RegisterAction(Action action) @@ -526,7 +612,7 @@ namespace SHADE actions.Add(new CallbackAction(action)); } /// - /// Constructs and adds a CallbackACtion into the event. + /// Constructs and adds a CallbackAction into the event. /// /// Object to call the method on. /// Method to call. @@ -604,7 +690,7 @@ namespace SHADE actions.Add(action); } /// - /// Constructs and adds a CallbackACtion into the event. + /// Constructs and adds a CallbackAction into the event. /// /// System.Action to add as a CallbackAction. public void RegisterAction(Action action) @@ -612,7 +698,7 @@ namespace SHADE actions.Add(new CallbackAction(action)); } /// - /// Constructs and adds a CallbackACtion into the event. + /// Constructs and adds a CallbackAction into the event. /// /// Object to call the method on. /// Method to call. @@ -690,7 +776,7 @@ namespace SHADE actions.Add(action); } /// - /// Constructs and adds a CallbackACtion into the event. + /// Constructs and adds a CallbackAction into the event. /// /// System.Action to add as a CallbackAction. public void RegisterAction(Action action) @@ -698,7 +784,7 @@ namespace SHADE actions.Add(new CallbackAction(action)); } /// - /// Constructs and adds a CallbackACtion into the event. + /// Constructs and adds a CallbackAction into the event. /// /// Object to call the method on. /// Method to call. @@ -776,7 +862,7 @@ namespace SHADE actions.Add(action); } /// - /// Constructs and adds a CallbackACtion into the event. + /// Constructs and adds a CallbackAction into the event. /// /// System.Action to add as a CallbackAction. public void RegisterAction(Action action) @@ -784,7 +870,7 @@ namespace SHADE actions.Add(new CallbackAction(action)); } /// - /// Constructs and adds a CallbackACtion into the event. + /// Constructs and adds a CallbackAction into the event. /// /// Object to call the method on. /// Method to call. @@ -862,7 +948,7 @@ namespace SHADE actions.Add(action); } /// - /// Constructs and adds a CallbackACtion into the event. + /// Constructs and adds a CallbackAction into the event. /// /// System.Action to add as a CallbackAction. public void RegisterAction(Action action) @@ -870,7 +956,7 @@ namespace SHADE actions.Add(new CallbackAction(action)); } /// - /// Constructs and adds a CallbackACtion into the event. + /// Constructs and adds a CallbackAction into the event. /// /// Object to call the method on. /// Method to call. diff --git a/SHADE_CSharp/src/Events/CallbackEvent.tt b/SHADE_CSharp/src/Events/CallbackEvent.tt index 6a545601..66a8b6d9 100644 --- a/SHADE_CSharp/src/Events/CallbackEvent.tt +++ b/SHADE_CSharp/src/Events/CallbackEvent.tt @@ -61,13 +61,13 @@ namespace SHADE IEnumerable Actions { get; } } -<# for (int i = 1; i <= max; ++i) { #> +<# for (int i = 0; i <= max; ++i) { #> /// /// A container of CallbackActions that is correlated to a specific scenario as /// specified by the user of this class. /// This variant accepts CallbackEvents with 1 generic parameter. /// - public class CallbackEvent<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>> : ICallbackEvent + public class CallbackEvent<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #> : ICallbackEvent { #region Properties -------------------------------------------------------------- /// @@ -82,13 +82,13 @@ namespace SHADE /// public void RegisterAction() { - actions.Add(new CallbackAction<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>>()); + actions.Add(new CallbackAction<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #>()); } /// public void RegisterAction(ICallbackAction action) { // Check if valid action - if (action.GetType() != typeof(CallbackAction<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>>)) + if (action.GetType() != typeof(CallbackAction<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #>)) { Debug.LogWarning("Attempted to register an invalid CallbackAction type. Ignoring.", this); return; @@ -100,26 +100,26 @@ namespace SHADE /// Adds a CallbackAction into the event. /// /// CallbackAction to add. - public void RegisterAction(CallbackAction<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>> action) + public void RegisterAction(CallbackAction<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #> action) { actions.Add(action); } /// - /// Constructs and adds a CallbackACtion into the event. + /// Constructs and adds a CallbackAction into the event. /// /// System.Action to add as a CallbackAction. - public void RegisterAction(Action<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>> action) + public void RegisterAction(Action<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #> action) { - actions.Add(new CallbackAction<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>>(action)); + actions.Add(new CallbackAction<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #>(action)); } /// - /// Constructs and adds a CallbackACtion into the event. + /// Constructs and adds a CallbackAction into the event. /// /// Object to call the method on. /// Method to call. public void RegisterAction(Object target, MethodInfo method) { - actions.Add(new CallbackAction<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>>(target, method)); + actions.Add(new CallbackAction<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #>(target, method)); } /// public void DeregisterAction(ICallbackAction action) @@ -132,9 +132,9 @@ namespace SHADE /// /// Invokes all stored CallbackActions with the specified parameters. /// - public void Invoke(<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#> t<#=t#><# if (t != i) { #>, <# } #><# } #>) + public void Invoke(<# if (i != 0) { for (int t = 1; t < i + 1; ++t) { #>T<#=t#> t<#=t#><# if (t != i) { #>, <# } #><# } } #>) { - foreach (CallbackAction<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>> action in actions) + foreach (CallbackAction<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #> action in actions) { try { diff --git a/TempScriptsFolder/RaccoonSpin.cs b/TempScriptsFolder/RaccoonSpin.cs index 06b3c163..efdfadeb 100644 --- a/TempScriptsFolder/RaccoonSpin.cs +++ b/TempScriptsFolder/RaccoonSpin.cs @@ -8,6 +8,8 @@ public class RaccoonSpin : Script private float RotateSpeed = 1.0f; private float rotation = 0.0f; [SerializeField] + private CallbackEvent emptyEvent; + [SerializeField] private CallbackEvent testEvent; [SerializeField] private CallbackEvent testEvent3 = new CallbackEvent(); @@ -17,6 +19,8 @@ public class RaccoonSpin : Script protected override void awake() { + emptyEvent = new CallbackEvent(); + emptyEvent.RegisterAction(() => Debug.Log("Empty event action!")); testEvent = new CallbackEvent(); Action action = (x) => Debug.Log($"{x}"); testEvent.RegisterAction(action); From 9be58e7e5d961df6c90f60fbc20a4f8ea38a927d Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 8 Nov 2022 18:32:13 +0800 Subject: [PATCH 26/59] Added SceneGraph interaction functions in GameObject --- SHADE_Managed/src/Engine/ChildListCache.cxx | 89 ++++++++++++++ SHADE_Managed/src/Engine/ChildListCache.hxx | 80 +++++++++++++ SHADE_Managed/src/Engine/EngineInterface.hxx | 2 +- SHADE_Managed/src/Engine/GameObject.cxx | 120 +++++++++++++++++-- SHADE_Managed/src/Engine/GameObject.hxx | 102 ++++++++++++++-- 5 files changed, 372 insertions(+), 21 deletions(-) create mode 100644 SHADE_Managed/src/Engine/ChildListCache.cxx create mode 100644 SHADE_Managed/src/Engine/ChildListCache.hxx diff --git a/SHADE_Managed/src/Engine/ChildListCache.cxx b/SHADE_Managed/src/Engine/ChildListCache.cxx new file mode 100644 index 00000000..b183646f --- /dev/null +++ b/SHADE_Managed/src/Engine/ChildListCache.cxx @@ -0,0 +1,89 @@ +/************************************************************************************//*! +\file ChildListCache.cxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Nov 11, 2022 +\brief Contains the definition of the functions for the ChildListCache managed + class. + + Note: This file is written in C++17/CLI. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +// Precompiled Headers +#include "SHpch.h" +// Primary Header +#include "ChildListCache.hxx" +// External Dependencies +#include "Scene/SHSceneManager.h" +// Project Headers +#include "Utility/Debug.hxx" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Static Usage Functions */ + /*---------------------------------------------------------------------------------*/ + ChildListCache::ChildEnumerable^ ChildListCache::GetChildList(Entity entity) + { + // Ignore if invalid + if (entity == MAX_EID) + return nullptr; + + // Check if in cache + if (cachedLists->ContainsKey(entity)) + return cachedLists[entity]; + + // Grab the native child list + auto node = GameObject(entity).GetSceneNode(); + if (!node || node->GetChildren().empty()) + return nullptr; + + // Otherwise + // - Create the list + ChildList^ list = gcnew ChildList(); + updateChildList(list, node); + // - Cache it + cachedLists[entity] = list; + + return list; + } + + void ChildListCache::UpdateChildList(Entity entity) + { + // Ignore if invalid + if (entity == MAX_EID) + return; + + // Check if in cache + if (!cachedLists->ContainsKey(entity)) + return; + + // Update + updateChildList(cachedLists[entity], GameObject(entity).GetSceneNode()); + } + + /*---------------------------------------------------------------------------------*/ + /* Event Handling Functions */ + /*---------------------------------------------------------------------------------*/ + void ChildListCache::OnChildrenChanged(EntityID entity) + { + SAFE_NATIVE_CALL_BEGIN + UpdateChildList(entity); + SAFE_NATIVE_CALL_END_N("SHADE_Managed.ChildListCache") + } + + /*---------------------------------------------------------------------------------*/ + /* Helper Functions */ + /*---------------------------------------------------------------------------------*/ + void ChildListCache::updateChildList(ChildList^ list, const SHSceneNode* sceneNode) + { + list->Clear(); + for (auto node : sceneNode->GetChildren()) + { + list->Add(GameObject(node->GetEntityID())); + } + } +} diff --git a/SHADE_Managed/src/Engine/ChildListCache.hxx b/SHADE_Managed/src/Engine/ChildListCache.hxx new file mode 100644 index 00000000..1a2637d3 --- /dev/null +++ b/SHADE_Managed/src/Engine/ChildListCache.hxx @@ -0,0 +1,80 @@ +/************************************************************************************//*! +\file ChildListCache.hxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Nov 11, 2022 +\brief Contains the definition of the ChildListCache managed class. + + Note: This file is written in C++17/CLI. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#pragma once + +// Project Includes +#include "GameObject.hxx" + +namespace SHADE { } + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Forward Declarations */ + /*---------------------------------------------------------------------------------*/ + class SHSceneNode; + + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + /// + /// Static class that caches all the lists of children for GameObjects. + /// + private ref class ChildListCache abstract sealed + { + public: + /*-----------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------*/ + using ChildList = System::Collections::Generic::List; + using ChildEnumerable = System::Collections::Generic::IEnumerable; + using ListMap = System::Collections::Generic::Dictionary; + + internal: + /*-----------------------------------------------------------------------------*/ + /* Static Usage Functions */ + /*-----------------------------------------------------------------------------*/ + /// + /// Retrieves the children list for the specified Entity. + /// + /// + /// Enumerable read only list of an Entity's children. Null if entity is invalid + /// or there are no children. + /// + static ChildEnumerable^ GetChildList(Entity entity); + /// + /// Updates the children list for the specified Entity if it exists. + /// + static void UpdateChildList(Entity entity); + + /*-----------------------------------------------------------------------------*/ + /* Event Handling Functions */ + /*-----------------------------------------------------------------------------*/ + /// + /// To be + /// + static void OnChildrenChanged(EntityID entity); + + private: + /*-----------------------------------------------------------------------------*/ + /* Static Data Members */ + /*-----------------------------------------------------------------------------*/ + static ListMap^ cachedLists = gcnew ListMap(); + + /*-----------------------------------------------------------------------------*/ + /* Helper Functions */ + /*-----------------------------------------------------------------------------*/ + static void updateChildList(ChildList^ list, const SHSceneNode* sceneNode); + }; +} \ No newline at end of file diff --git a/SHADE_Managed/src/Engine/EngineInterface.hxx b/SHADE_Managed/src/Engine/EngineInterface.hxx index 4fd8f7b3..37ded4eb 100644 --- a/SHADE_Managed/src/Engine/EngineInterface.hxx +++ b/SHADE_Managed/src/Engine/EngineInterface.hxx @@ -20,7 +20,7 @@ namespace SHADE { /// /// Static class that contains the functions for interfacing with the core - /// PlushieEngine written in C++ for managing the lifecycle of managed code. + /// SHADE Engine written in C++ for managing the lifecycle of managed code. /// private ref class EngineInterface abstract sealed { diff --git a/SHADE_Managed/src/Engine/GameObject.cxx b/SHADE_Managed/src/Engine/GameObject.cxx index 9f15c6c9..ece163f9 100644 --- a/SHADE_Managed/src/Engine/GameObject.cxx +++ b/SHADE_Managed/src/Engine/GameObject.cxx @@ -23,6 +23,7 @@ of DigiPen Institute of Technology is prohibited. #include "Utility/Convert.hxx" #include "Scripts/ScriptStore.hxx" #include "Utility/Debug.hxx" +#include "ChildListCache.hxx" namespace SHADE { @@ -87,30 +88,43 @@ namespace SHADE throw gcnew System::NullReferenceException(); return entity; } - GameObject^ GameObject::Parent::get() + GameObject GameObject::Parent::get() { if (!valid) throw gcnew System::NullReferenceException(); + const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph(); const auto* ROOT = SCENE_GRAPH.GetRoot(); - const auto* NODE = SCENE_GRAPH.GetNode(entity); if (NODE == nullptr) throw gcnew System::InvalidOperationException("Unable to retrieve SceneGraphNode for Entity " + entity.ToString()); const auto* PARENT = NODE->GetParent(); - return PARENT != ROOT ? gcnew GameObject(PARENT->GetEntityID()) : nullptr; + return PARENT != ROOT ? GameObject(PARENT->GetEntityID()) : GameObject(); } - void GameObject::Parent::set(GameObject^ newParent) + void GameObject::Parent::set(GameObject newParent) { if (!valid) throw gcnew System::NullReferenceException(); const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph(); - if (newParent == nullptr) - SCENE_GRAPH.SetParent(entity, nullptr); + if (newParent) + SCENE_GRAPH.SetParent(entity, newParent.EntityId); else - SCENE_GRAPH.SetParent(entity, newParent->EntityId); + SCENE_GRAPH.SetParent(entity, nullptr); + } + int GameObject::ChildCount::get() + { + if (!valid) + throw gcnew System::NullReferenceException(); + + const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph(); + const auto* ROOT = SCENE_GRAPH.GetRoot(); + const auto* NODE = SCENE_GRAPH.GetNode(entity); + if (NODE == nullptr) + throw gcnew System::InvalidOperationException("Unable to retrieve SceneGraphNode for Entity " + entity.ToString()); + + return static_cast(NODE->GetChildren().size()); } /*---------------------------------------------------------------------------------*/ @@ -215,6 +229,88 @@ namespace SHADE ScriptStore::RemoveScript(entity); } + /*---------------------------------------------------------------------------------*/ + /* Scene Graph Functions */ + /*---------------------------------------------------------------------------------*/ + void GameObject::DetachChildren() + { + // Validity Checks + if (!valid) + throw gcnew System::NullReferenceException(); + auto node = GetSceneNode(); + if (!node) + throw gcnew System::NullReferenceException(); + + // Unparent all children to the root + for (auto child : node->GetChildren()) + { + child->SetParent(nullptr); + ChildListCache::UpdateChildList(child->GetEntityID()); + } + ChildListCache::UpdateChildList(entity); + } + + GameObject GameObject::GetChild(int index) + { + // Validity Checks + if (!valid) + throw gcnew System::NullReferenceException(); + auto node = GetSceneNode(); + if (!node) + throw gcnew System::NullReferenceException(); + + auto child = node->GetChild(index); + return child ? GameObject(child->GetEntityID()) : GameObject(); + } + + System::Collections::Generic::IEnumerable^ GameObject::GetChildren() + { + return ChildListCache::GetChildList(entity); + } + + int GameObject::GetSiblingIndex() + { + throw gcnew System::NotImplementedException(); + } + + bool GameObject::IsChildOf(GameObject gameObj) + { + // Search parents recursively + auto node = GetSceneNode(); + while (node != nullptr) + { + if (node->GetEntityID() == gameObj.entity) + return true; + + // Go up higher + node = node->GetParent(); + } + return false; + } + + void GameObject::SetAsFirstSibling() + { + throw gcnew System::NotImplementedException(); + } + + void GameObject::SetAsLastSibling() + { + throw gcnew System::NotImplementedException(); + } + + void GameObject::SetSiblingIndex(int index) + { + throw gcnew System::NotImplementedException(); + } + + /*---------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*---------------------------------------------------------------------------------*/ + GameObject::operator bool(GameObject gameObj) + { + return gameObj.valid; + } + /*---------------------------------------------------------------------------------*/ /* Constructors */ /*---------------------------------------------------------------------------------*/ @@ -245,11 +341,15 @@ namespace SHADE } /*---------------------------------------------------------------------------------*/ - /* Operator Overloads */ + /* Helper Functions */ /*---------------------------------------------------------------------------------*/ - GameObject::operator bool(GameObject gameObj) + SHSceneNode* GameObject::GetSceneNode() { - return gameObj.valid; + const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph(); + const auto* ROOT = SCENE_GRAPH.GetRoot(); + if (!ROOT) + return nullptr; + return SCENE_GRAPH.GetNode(entity); } /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Managed/src/Engine/GameObject.hxx b/SHADE_Managed/src/Engine/GameObject.hxx index 030b917c..ec75f9d9 100644 --- a/SHADE_Managed/src/Engine/GameObject.hxx +++ b/SHADE_Managed/src/Engine/GameObject.hxx @@ -20,7 +20,7 @@ of DigiPen Institute of Technology is prohibited. namespace SHADE { /*---------------------------------------------------------------------------------*/ - /* Forward Declarations */ + /* Forward Declarations */ /*---------------------------------------------------------------------------------*/ ref class Script; ref class BaseComponent; @@ -97,10 +97,17 @@ namespace SHADE /// /// The parent entity for this GameObject. /// - property GameObject^ Parent + property GameObject Parent { - GameObject^ get(); - void set(GameObject^); + GameObject get(); + void set(GameObject); + } + /// + /// Number of Children held by this GameObject + /// + property int ChildCount + { + int get(); } /*-----------------------------------------------------------------------------*/ @@ -120,8 +127,7 @@ namespace SHADE /// /// Whether to activate or deactivate this GameObject. /// - void SetActive(bool active); - + void SetActive(bool active); /*-----------------------------------------------------------------------------*/ /* Component Access Functions */ @@ -214,6 +220,82 @@ namespace SHADE generic where T : ref class, Script void RemoveScript(); + /*-----------------------------------------------------------------------------*/ + /* Scene Graph Functions */ + /*-----------------------------------------------------------------------------*/ + /// + /// Unparents all children. Useful if you want to destroy the root of a hierarchy + /// without destroying the children. + /// + void DetachChildren(); + /// + /// Returns a child by index. + /// + /// Index of the child GameObject to retrieve. + /// + /// Handle to the GameObject if the index is valid. Invalid GameObject otherwise. + /// + GameObject GetChild(int index); + /// + /// Returns a cached enumerable container of child GameObjects of this + /// GameObject. + /// + /// + /// Enumerable container of child GameObjects of this GameObject. Null if + /// ChildCount is 0. + /// + System::Collections::Generic::IEnumerable^ GetChildren(); + /// + /// Gets the sibling index. Use GetSiblingIndex to find out the GameObject’s + /// place in this hierarchy. When the sibling index of a GameObject is changed, + /// its order in the Hierarchy window will also change. + /// + /// + /// Index of this GameObject among the parent GameObject's children. + /// + [System::ObsoleteAttribute("Not yet implemented.", true)] + int GetSiblingIndex(); + /// + /// Checks if this GameObject a direct or indirect child of the specified + /// GameObject. + /// + /// + /// True if this GameObject is a child, deep child (child of a child) or + /// identical to this GameObject, otherwise false. + /// + bool IsChildOf(GameObject gameObj); + /// + /// Move the GameObject to the start of the parent GameObject's children list. + /// + [System::ObsoleteAttribute("Not yet implemented.", true)] + void SetAsFirstSibling(); + /// + /// Move the GameObject to the end of the parent GameObject's children list. + /// + [System::ObsoleteAttribute("Not yet implemented.", true)] + void SetAsLastSibling(); + /// + /// Move the GameObject to the specified position in the parent GameObject's + /// children list. An existing object at that position if any, will be pushed + /// to the next index (existing element will be at index + 1). + /// + /// + /// Position to place this GameObject at in the hierarchy. Clamped to between + /// [0, parent.ChildCount]. + /// + [System::ObsoleteAttribute("Not yet implemented.", true)] + void SetSiblingIndex(int index); + + /*-----------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*-----------------------------------------------------------------------------*/ + /// + /// Implicit conversion operator to enable checking if a GameObject is valid. + /// + /// GameObjects to check. + /// True if the GameObject is valid. + static operator bool(GameObject gameObj); + internal: /*-----------------------------------------------------------------------------*/ /* Constructors */ @@ -249,13 +331,13 @@ namespace SHADE SHEntity& GetNativeEntity(); /*-----------------------------------------------------------------------------*/ - /* Operator Overloads */ + /* Helper Functions */ /*-----------------------------------------------------------------------------*/ /// - /// Implicit conversion operator to enable checking if a GameObject is valid. + /// Retrieves the SceneNode for this GameObject's referenced entity. /// - /// GameObjects to check. - static operator bool(GameObject gameObj); + /// Pointer to the SceneNode for this GameObject.. + SHSceneNode* GetSceneNode(); private: /*-----------------------------------------------------------------------------*/ From 8512c658f9503acc83dca3a5e0ad9c6ba8089732 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 8 Nov 2022 18:32:47 +0800 Subject: [PATCH 27/59] Made GameObject an IEnumerable to follow Unity's Transform interface for iterating through children --- SHADE_Managed/src/Engine/GameObject.cxx | 20 ++++++++++++++++++++ SHADE_Managed/src/Engine/GameObject.hxx | 11 ++++++++++- TempScriptsFolder/RaccoonShowcase.cs | 5 +++++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/SHADE_Managed/src/Engine/GameObject.cxx b/SHADE_Managed/src/Engine/GameObject.cxx index ece163f9..e7cc4445 100644 --- a/SHADE_Managed/src/Engine/GameObject.cxx +++ b/SHADE_Managed/src/Engine/GameObject.cxx @@ -265,6 +265,9 @@ namespace SHADE System::Collections::Generic::IEnumerable^ GameObject::GetChildren() { + // Validity Checks + if (!valid) + throw gcnew System::NullReferenceException(); return ChildListCache::GetChildList(entity); } @@ -390,4 +393,21 @@ namespace SHADE { return !(lhs == rhs); } + + /*---------------------------------------------------------------------------------*/ + /* IEnummerable */ + /*---------------------------------------------------------------------------------*/ + System::Collections::Generic::IEnumerator^ GameObject::GetEnumerator() + { + System::Collections::Generic::IEnumerable^ childList = GetChildren(); + if (childList == nullptr) + return System::Linq::Enumerable::Empty()->GetEnumerator(); + else + return childList->GetEnumerator(); + } + + System::Collections::IEnumerator^ GameObject::GetEnumeratorNonGeneric() + { + return GetEnumerator(); + } } diff --git a/SHADE_Managed/src/Engine/GameObject.hxx b/SHADE_Managed/src/Engine/GameObject.hxx index ec75f9d9..ce1dd3eb 100644 --- a/SHADE_Managed/src/Engine/GameObject.hxx +++ b/SHADE_Managed/src/Engine/GameObject.hxx @@ -32,8 +32,9 @@ namespace SHADE /// Lightweight object for an Entity that allows for easy access to Component and /// Script operations. /// Can be set to a invalid/null GameObject by default construction. + /// Can also be iterated to access children. /// - public value class GameObject : public System::IEquatable + public value class GameObject : public System::IEquatable, public System::Collections::Generic::IEnumerable { public: /*-----------------------------------------------------------------------------*/ @@ -386,6 +387,14 @@ namespace SHADE /// Another GameObject to check with. /// True if both Components are different. static bool operator!=(GameObject lhs, GameObject rhs); + + /*-----------------------------------------------------------------------------*/ + /* IEnummerable */ + /*-----------------------------------------------------------------------------*/ + /// + System::Collections::Generic::IEnumerator^ GetEnumerator() override; + /// + System::Collections::IEnumerator^ GetEnumeratorNonGeneric() override = System::Collections::IEnumerable::GetEnumerator; }; } diff --git a/TempScriptsFolder/RaccoonShowcase.cs b/TempScriptsFolder/RaccoonShowcase.cs index da0b89d2..2fc8104d 100644 --- a/TempScriptsFolder/RaccoonShowcase.cs +++ b/TempScriptsFolder/RaccoonShowcase.cs @@ -27,6 +27,11 @@ public class RaccoonShowcase : Script Debug.LogError("Transform is NULL!"); } + foreach (var child in Owner) + { + Debug.Log(child.Name); + } + originalScale = Transform.LocalScale.z; } protected override void update() From 715699b63bcb9d2d4561fb021f66f8f0574b458c Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 8 Nov 2022 20:18:50 +0800 Subject: [PATCH 28/59] Add interface for C# light class and modified Color to match Unity's interface --- SHADE_Managed/src/Components/Light.cxx | 79 ++++++++++++ SHADE_Managed/src/Components/Light.hxx | 125 +++++++++++++++++++ SHADE_Managed/src/Engine/ECS.cxx | 10 +- SHADE_Managed/src/Graphics/Color.hxx | 160 ++++++++++++------------- SHADE_Managed/src/Utility/Convert.cxx | 10 ++ SHADE_Managed/src/Utility/Convert.hxx | 13 ++ 6 files changed, 308 insertions(+), 89 deletions(-) create mode 100644 SHADE_Managed/src/Components/Light.cxx create mode 100644 SHADE_Managed/src/Components/Light.hxx diff --git a/SHADE_Managed/src/Components/Light.cxx b/SHADE_Managed/src/Components/Light.cxx new file mode 100644 index 00000000..a220c79a --- /dev/null +++ b/SHADE_Managed/src/Components/Light.cxx @@ -0,0 +1,79 @@ +/************************************************************************************//*! +\file Light.cxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Nov 8, 2022 +\brief Contains the definition of the functions of the managed Light class. + + Note: This file is written in C++17/CLI. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +// Precompiled Headers +#include "SHpch.h" +// Primary Header +#include "Light.hxx" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Constructors */ + /*---------------------------------------------------------------------------------*/ + Light::Light(Entity entity) + : Component(entity) + {} + + /*---------------------------------------------------------------------------------*/ + /* Properties */ + /*---------------------------------------------------------------------------------*/ + Vector3 Light::Position::get() + { + return Convert::ToCLI(GetNativeComponent()->GetPosition()); + } + void Light::Position::set(Vector3 value) + { + GetNativeComponent()->SetPosition(Convert::ToNative(value)); + } + Light::Type Light::LightType::get() + { + return static_cast(GetNativeComponent()->GetType()); + } + void Light::LightType::set(Light::Type value) + { + GetNativeComponent()->SetType(static_cast(value)); + } + Vector3 Light::Direction::get() + { + return Convert::ToCLI(GetNativeComponent()->GetDirection()); + } + void Light::Direction::set(Vector3 value) + { + GetNativeComponent()->SetDirection(Convert::ToNative(value)); + } + Color Light::Color::get() + { + return Convert::ToCLI(SHColour(GetNativeComponent()->GetColor())); + } + void Light::Color::set(SHADE::Color value) + { + GetNativeComponent()->SetColor(Convert::ToNative(value)); + } + System::UInt32 Light::CullingMask::get() + { + return GetNativeComponent()->GetCullingMask(); + } + void Light::CullingMask::set(System::UInt32 value) + { + GetNativeComponent()->SetCullingMask(value); + } + float Light::Strength::get() + { + return GetNativeComponent()->GetStrength(); + } + void Light::Strength::set(float value) + { + GetNativeComponent()->SetStrength(value); + } +} diff --git a/SHADE_Managed/src/Components/Light.hxx b/SHADE_Managed/src/Components/Light.hxx new file mode 100644 index 00000000..9abb05d5 --- /dev/null +++ b/SHADE_Managed/src/Components/Light.hxx @@ -0,0 +1,125 @@ +/************************************************************************************//*! +\file Light.hxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Nov 8, 2022 +\brief Contains the definition of the managed Light class with the declaration + of functions for working with it. + + Note: This file is written in C++17/CLI. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#pragma once + +// Project Includes +#include "Components/Component.hxx" +#include "Math/Vector3.hxx" +// External Dependencies +#include "Graphics/MiddleEnd/Lights/SHLightComponent.h" + +namespace SHADE +{ + /// + /// CLR version of the SHADE Engine's SHLightComponent. + /// + public ref class Light : public Component + { + internal: + /*-----------------------------------------------------------------------------*/ + /* Constructors */ + /*-----------------------------------------------------------------------------*/ + /// + /// Constructs a Light Component that represents a native Light component tied to + /// the specified Entity. + /// + /// Entity that this Component will be tied to. + Light(Entity entity); + + public: + /*-----------------------------------------------------------------------------*/ + /* Constants */ + /*-----------------------------------------------------------------------------*/ + /// + /// Supported types of the Light Component. + /// + enum class Type + { + /// + /// Light applied uniformly across the scene at a specified direction. + /// + Directional, + /// + /// Light that originates from a certain point in all directions. + /// Not implemented yet. + /// + Point, + /// + /// Light that originates from a certain point within a angle. + /// Not implemented yet. + /// + Spot, + /// + /// Light applied to all objects. Has no source point. + /// + Ambient + }; + + /*-----------------------------------------------------------------------------*/ + /* Properties */ + /*-----------------------------------------------------------------------------*/ + /// + /// Position of the light. Only works for Point Light (unimplemented). + /// + [System::ObsoleteAttribute("Not implemented yet.", true)] + property Vector3 Position + { + Vector3 get(); + void set(Vector3 val); + } + /// + /// Type of lighting that this Light component will apply onto the scene. + /// + property Type LightType + { + Type get(); + void set(Type val); + } + /// + /// Direction of the light. Only applicable for Directional Lights. + /// + property Vector3 Direction + { + Vector3 get(); + void set(Vector3 val); + } + /// + /// Colour of the Light. + /// + property SHADE::Color Color + { + SHADE::Color get(); + void set(SHADE::Color val); + } + /// + /// Culling mask that is used to control what types of Materials would be + /// affected by this Light. + /// + property System::UInt32 CullingMask + { + System::UInt32 get(); + void set(System::UInt32 val); + } + /// + /// Intensity of the Light + /// + property float Strength + { + float get(); + void set(float val); + } + }; +} + diff --git a/SHADE_Managed/src/Engine/ECS.cxx b/SHADE_Managed/src/Engine/ECS.cxx index 3da39394..00c3c182 100644 --- a/SHADE_Managed/src/Engine/ECS.cxx +++ b/SHADE_Managed/src/Engine/ECS.cxx @@ -22,8 +22,8 @@ of DigiPen Institute of Technology is prohibited. // External Dependencies #include "ECS_Base/Managers/SHEntityManager.h" #include "Math/Transform/SHTransformComponent.h" -#include "Physics\Components\SHColliderComponent.h" -#include "Physics\Components\SHRigidBodyComponent.h" +#include "Physics/Components/SHColliderComponent.h" +#include "Physics/Components/SHRigidBodyComponent.h" #include "Scene/SHSceneManager.h" #include "Scene/SHSceneGraph.h" #include "Tools/SHLog.h" @@ -31,10 +31,11 @@ of DigiPen Institute of Technology is prohibited. #include "Utility/Convert.hxx" #include "Utility/Debug.hxx" #include "Components/Transform.hxx" -#include "Components\RigidBody.hxx" -#include "Components\Collider.hxx" +#include "Components/RigidBody.hxx" +#include "Components/Collider.hxx" #include "Components/Camera.hxx" #include "Components/CameraArm.hxx" +#include "Components/Light.hxx" namespace SHADE { @@ -252,6 +253,7 @@ namespace SHADE componentMap.Add(createComponentSet()); componentMap.Add(createComponentSet()); componentMap.Add(createComponentSet()); + componentMap.Add(createComponentSet()); } /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Managed/src/Graphics/Color.hxx b/SHADE_Managed/src/Graphics/Color.hxx index d6a46216..64152394 100644 --- a/SHADE_Managed/src/Graphics/Color.hxx +++ b/SHADE_Managed/src/Graphics/Color.hxx @@ -25,95 +25,85 @@ namespace SHADE { public: /*-----------------------------------------------------------------------------*/ - /* Type Definitions */ + /* Properties */ /*-----------------------------------------------------------------------------*/ /// - /// A static class that contains a set of default Colors. + /// Pure black. /// - ref class Defaults abstract sealed + static property Color Black { - public: - /*-------------------------------------------------------------------------*/ - /* Properties */ - /*-------------------------------------------------------------------------*/ - /// - /// Pure black. - /// - static property Color Black - { - Color get() { return Color(0.0f, 0.0f, 0.0f); } - } - /// - /// Light Gray, lighter than gray. - /// - static property Color LightGray - { - Color get() { return Color(0.827451f, 0.827451f, 0.827451f); } - } - /// - /// Gray, halfway between black and white. - /// - static property Color Gray - { - Color get() { return Color(0.5f, 0.5f, 0.5f); } - } - /// - /// Dark Gray, darker than gray. - /// - static property Color DarkGray - { - Color get() { return Color(0.622f, 0.622f, 0.622f); } - } - /// - /// Pure white. - /// - static property Color White - { - Color get() { return Color(1.0f, 1.0f, 1.0f); } - } - /// - /// Pure red. - /// - static property Color Red - { - Color get() { return Color(1.0f, 0.0f, 0.0f); } - } - /// - /// Pure green. - /// - static property Color Green - { - Color get() { return Color(0.0f, 1.0f, 0.0f); } - } - /// - /// Pure blue. - /// - static property Color Blue - { - Color get() { return Color(0.0f, 0.0f, 1.0f); } - } - /// - /// Pure cyan, mix of pure green and blue. - /// - static property Color Cyan - { - Color get() { return Color(0.0f, 1.0f, 1.0f); } - } - /// - /// Pure magenta, mix of pure red and blue. - /// - static property Color Magenta - { - Color get() { return Color(1.0f, 0.0f, 1.0f); } - } - /// - /// Pure yellow, mix of pure red and green. - /// - static property Color Yellow - { - Color get() { return Color(1.0f, 1.0f, 0.0f); } - } - }; + Color get() { return Color(0.0f, 0.0f, 0.0f); } + } + /// + /// Light Gray, lighter than gray. + /// + static property Color LightGray + { + Color get() { return Color(0.827451f, 0.827451f, 0.827451f); } + } + /// + /// Gray, halfway between black and white. + /// + static property Color Gray + { + Color get() { return Color(0.5f, 0.5f, 0.5f); } + } + /// + /// Dark Gray, darker than gray. + /// + static property Color DarkGray + { + Color get() { return Color(0.622f, 0.622f, 0.622f); } + } + /// + /// Pure white. + /// + static property Color White + { + Color get() { return Color(1.0f, 1.0f, 1.0f); } + } + /// + /// Pure red. + /// + static property Color Red + { + Color get() { return Color(1.0f, 0.0f, 0.0f); } + } + /// + /// Pure green. + /// + static property Color Green + { + Color get() { return Color(0.0f, 1.0f, 0.0f); } + } + /// + /// Pure blue. + /// + static property Color Blue + { + Color get() { return Color(0.0f, 0.0f, 1.0f); } + } + /// + /// Pure cyan, mix of pure green and blue. + /// + static property Color Cyan + { + Color get() { return Color(0.0f, 1.0f, 1.0f); } + } + /// + /// Pure magenta, mix of pure red and blue. + /// + static property Color Magenta + { + Color get() { return Color(1.0f, 0.0f, 1.0f); } + } + /// + /// Pure yellow, mix of pure red and green. + /// + static property Color Yellow + { + Color get() { return Color(1.0f, 1.0f, 0.0f); } + } /*-----------------------------------------------------------------------------*/ /* Constructors */ diff --git a/SHADE_Managed/src/Utility/Convert.cxx b/SHADE_Managed/src/Utility/Convert.cxx index 1d89569f..3b1f0f38 100644 --- a/SHADE_Managed/src/Utility/Convert.cxx +++ b/SHADE_Managed/src/Utility/Convert.cxx @@ -72,6 +72,16 @@ namespace SHADE return Ray(ToCLI(vec.position), ToCLI(vec.direction)); } + SHColour Convert::ToNative(Color col) + { + return SHColour(col.r, col.g, col.b, col.a); + } + + Color Convert::ToCLI(const SHColour& vec) + { + return Color(vec.x, vec.y, vec.z, vec.w); + } + /*---------------------------------------------------------------------------------*/ /* String Conversions */ /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Managed/src/Utility/Convert.hxx b/SHADE_Managed/src/Utility/Convert.hxx index d3dca740..666b5062 100644 --- a/SHADE_Managed/src/Utility/Convert.hxx +++ b/SHADE_Managed/src/Utility/Convert.hxx @@ -29,6 +29,8 @@ of DigiPen Institute of Technology is prohibited. #include "Math/Quaternion.hxx" #include "Math/Ray.hxx" #include "Engine/GenericHandle.hxx" +#include "Math/SHColour.h" +#include "Graphics/Color.hxx" namespace SHADE { @@ -104,6 +106,17 @@ namespace SHADE /// The native Vector2 to convert from. /// Managed copy of a native Vector2. static Ray ToCLI(const SHRay& vec); + /// Converts from a managed Color to a native Colour. + /// + /// The managed Color to convert from. + /// Native copy of a managed Color. + static SHColour ToNative(Color col); + /// + /// Converts from a native Colour to a managed Color. + /// + /// The native Colour to convert from. + /// Managed copy of a native Colour. + static Color ToCLI(const SHColour& vec); /*-----------------------------------------------------------------------------*/ /* String Conversions */ From e89f5b4b9e0b640b93abe1456cdfd9b24491a777 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 8 Nov 2022 20:49:07 +0800 Subject: [PATCH 29/59] Added OnDrawGizmos for debug draw for scripts --- .../src/Application/SBApplication.cpp | 1 + SHADE_Engine/src/Scripting/SHScriptEngine.cpp | 6 ++++++ SHADE_Engine/src/Scripting/SHScriptEngine.h | 7 +++++++ .../src/Scripting/SHScriptEngineRoutines.cpp | 11 +++++++++++ SHADE_Managed/src/Scripts/Script.cxx | 12 ++++++++++++ SHADE_Managed/src/Scripts/Script.hxx | 17 +++++++++++++++++ SHADE_Managed/src/Scripts/ScriptStore.cxx | 18 ++++++++++++++++++ SHADE_Managed/src/Scripts/ScriptStore.hxx | 4 ++++ 8 files changed, 76 insertions(+) diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index f4102067..6b67dbce 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -106,6 +106,7 @@ namespace Sandbox SHSystemManager::RegisterRoutine(); SHSystemManager::RegisterRoutine(); + SHSystemManager::RegisterRoutine(); SHSystemManager::RegisterRoutine(); SHSystemManager::RegisterRoutine(); diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp index 4a73342e..827f45a2 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp @@ -379,6 +379,12 @@ namespace SHADE DEFAULT_CSHARP_LIB_NAME, DEFAULT_CSHARP_NAMESPACE + ".ScriptStore", "ExecuteLateUpdate" + ); + csScriptsExecuteDrawGizmos = dotNet.GetFunctionPtr + ( + DEFAULT_CSHARP_LIB_NAME, + DEFAULT_CSHARP_NAMESPACE + ".ScriptStore", + "ExecuteOnDrawGizmos" ); csScriptsExecutePhysicsEvents = dotNet.GetFunctionPtr ( diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.h b/SHADE_Engine/src/Scripting/SHScriptEngine.h index 9ddd617a..7d83606e 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.h +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.h @@ -55,6 +55,12 @@ namespace SHADE LateUpdateRoutine(); void Execute(double dt) noexcept override final; }; + class SH_API GizmosDrawRoutine final : public SHSystemRoutine + { + public: + GizmosDrawRoutine(); + void Execute(double dt) noexcept override final; + }; class SH_API FrameCleanUpRoutine final : public SHSystemRoutine { public: @@ -250,6 +256,7 @@ namespace SHADE CsFuncPtr csScriptsExecuteFixedUpdate = nullptr; CsFuncPtr csScriptsExecuteUpdate = nullptr; CsFuncPtr csScriptsExecuteLateUpdate = nullptr; + CsFuncPtr csScriptsExecuteDrawGizmos = nullptr; CsFuncPtr csScriptsExecutePhysicsEvents = nullptr; CsFuncPtr csScriptsFrameCleanUp = nullptr; CsScriptManipFuncPtr csScriptsAdd = nullptr; diff --git a/SHADE_Engine/src/Scripting/SHScriptEngineRoutines.cpp b/SHADE_Engine/src/Scripting/SHScriptEngineRoutines.cpp index a2981c06..699776ca 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngineRoutines.cpp +++ b/SHADE_Engine/src/Scripting/SHScriptEngineRoutines.cpp @@ -50,6 +50,17 @@ namespace SHADE reinterpret_cast(system)->csScriptsExecuteLateUpdate(); } + /*-----------------------------------------------------------------------------------*/ + /* System Routine Functions - GizmosDrawRoutine */ + /*-----------------------------------------------------------------------------------*/ + SHScriptEngine::GizmosDrawRoutine::GizmosDrawRoutine() + : SHSystemRoutine("Script Engine Gizmos Draw", true) + {} + void SHScriptEngine::GizmosDrawRoutine::Execute(double dt) noexcept + { + reinterpret_cast(system)->csScriptsExecuteDrawGizmos(); + } + /*-----------------------------------------------------------------------------------*/ /* System Routine Functions - FrameCleanUpRoutine */ /*-----------------------------------------------------------------------------------*/ diff --git a/SHADE_Managed/src/Scripts/Script.cxx b/SHADE_Managed/src/Scripts/Script.cxx index e476d69d..bd6d7bef 100644 --- a/SHADE_Managed/src/Scripts/Script.cxx +++ b/SHADE_Managed/src/Scripts/Script.cxx @@ -140,6 +140,13 @@ namespace SHADE lateUpdate(); SAFE_NATIVE_CALL_END(this) } + void Script::OnDrawGizmos() + { + SAFE_NATIVE_CALL_BEGIN + OnGizmosDrawOverriden = true; + onDrawGizmos(); + SAFE_NATIVE_CALL_END(this) + } void Script::OnDestroy() { SAFE_NATIVE_CALL_BEGIN @@ -194,6 +201,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ Script::Script(GameObject gameObj) : owner { gameObj } + , OnGizmosDrawOverriden { false } {} /*---------------------------------------------------------------------------------*/ @@ -210,6 +218,10 @@ namespace SHADE void Script::fixedUpdate() {} void Script::update() {} void Script::lateUpdate() {} + void Script::onDrawGizmos() + { + OnGizmosDrawOverriden = false; + } void Script::onDestroy() {} /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Managed/src/Scripts/Script.hxx b/SHADE_Managed/src/Scripts/Script.hxx index afeaa8a0..bbe36784 100644 --- a/SHADE_Managed/src/Scripts/Script.hxx +++ b/SHADE_Managed/src/Scripts/Script.hxx @@ -164,6 +164,14 @@ namespace SHADE static operator bool(Script^ s); internal: + /*-----------------------------------------------------------------------------*/ + /* Properties */ + /*-----------------------------------------------------------------------------*/ + /// + /// If true, the OnGizmosDraw function was overridden. + /// + bool OnGizmosDrawOverriden; + /*-----------------------------------------------------------------------------*/ /* "All-Time" Lifecycle Functions */ /*-----------------------------------------------------------------------------*/ @@ -208,6 +216,11 @@ namespace SHADE /// void LateUpdate(); /// + /// Used to call onDrawGizmos(). This should be called just before rendering + /// the scene. This will only be called when working in the editor. + /// + void OnDrawGizmos(); + /// /// Used to call onDestroy(). This should be called at the end of the frame /// where the attached GameObject or this script is destroyed directly or /// indirectly due to destruction of the owner. @@ -308,6 +321,10 @@ namespace SHADE /// virtual void lateUpdate(); /// + /// Called every frame just before rendering but only if working in the editor. + /// + virtual void onDrawGizmos(); + /// /// Called just before the end of the frame where the attached GameObject or /// this script is destroyed directly or indirectly due to destruction of the /// owner. diff --git a/SHADE_Managed/src/Scripts/ScriptStore.cxx b/SHADE_Managed/src/Scripts/ScriptStore.cxx index 407d0fa8..a90b4f12 100644 --- a/SHADE_Managed/src/Scripts/ScriptStore.cxx +++ b/SHADE_Managed/src/Scripts/ScriptStore.cxx @@ -478,6 +478,24 @@ namespace SHADE SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore") } + void ScriptStore::ExecuteOnDrawGizmos() + { + SAFE_NATIVE_CALL_BEGIN + for each (System::Collections::Generic::KeyValuePair entity in scripts) + { + // Check active state + if (!isEntityActive(entity.Key)) + continue; + + // Update each script + for each (Script^ script in entity.Value) + { + script->OnDrawGizmos(); + } + } + SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore") + } + void ScriptStore::ExecuteCollisionFunctions() { SAFE_NATIVE_CALL_BEGIN diff --git a/SHADE_Managed/src/Scripts/ScriptStore.hxx b/SHADE_Managed/src/Scripts/ScriptStore.hxx index a4c6e824..c151392f 100644 --- a/SHADE_Managed/src/Scripts/ScriptStore.hxx +++ b/SHADE_Managed/src/Scripts/ScriptStore.hxx @@ -234,6 +234,10 @@ namespace SHADE /// static void ExecuteLateUpdate(); /// + /// Executes OnDrawGizmos() for all scripts. + /// + static void ExecuteOnDrawGizmos(); + /// /// Executes OnCollision*() and OnTrigger*() for all scripts. /// static void ExecuteCollisionFunctions(); From 41b7cb842cdd50cadeb60de0f049c0903a34f820 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 8 Nov 2022 21:31:53 +0800 Subject: [PATCH 30/59] Added C# Gizmos class interface --- .../MiddleEnd/Interface/SHDebugDrawSystem.cpp | 2 +- SHADE_Managed/src/Utility/Gizmos.cxx | 23 ++++++++++ SHADE_Managed/src/Utility/Gizmos.hxx | 45 +++++++++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 SHADE_Managed/src/Utility/Gizmos.cxx create mode 100644 SHADE_Managed/src/Utility/Gizmos.hxx diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.cpp index 883e4894..daa6a23d 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.cpp @@ -323,7 +323,7 @@ namespace SHADE static const SHMeshData SPHERE = SHPrimitiveGenerator::Sphere(); for (const auto& idx : SPHERE.Indices) { - spherePoints.emplace_back(SPHERE.VertexPositions[idx]); + spherePoints.emplace_back(SPHERE.VertexPositions[idx] * radius); } } drawLineSet(storage, color, spherePoints.begin(), spherePoints.end()); diff --git a/SHADE_Managed/src/Utility/Gizmos.cxx b/SHADE_Managed/src/Utility/Gizmos.cxx new file mode 100644 index 00000000..47d86251 --- /dev/null +++ b/SHADE_Managed/src/Utility/Gizmos.cxx @@ -0,0 +1,23 @@ +/************************************************************************************//*! +\file Gizmos.cxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Nov 8, 2022 +\brief Contains the definition of the functions for the Convert managed static + class. + + Note: This file is written in C++17/CLI. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +// Precompiled Headers +#include "SHpch.h" +// Primary Header +#include "Gizmos.hxx" +// External Dependencies + +namespace SHADE +{ +} diff --git a/SHADE_Managed/src/Utility/Gizmos.hxx b/SHADE_Managed/src/Utility/Gizmos.hxx new file mode 100644 index 00000000..f0b082d7 --- /dev/null +++ b/SHADE_Managed/src/Utility/Gizmos.hxx @@ -0,0 +1,45 @@ +/************************************************************************************//*! +\file Gizmos.hxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Nov 8, 2022 +\brief Contains the definition of the Gizmos static class and the + declaration of its functions. + + Note: This file is written in C++17/CLI. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#pragma once + +// Project Includes +#include "Math/Vector3.hxx" +#include "Graphics/Color.hxx" + +namespace SHADE +{ + /// + /// Provides functions for implementing debug drawing. + /// + public value class Gizmos abstract sealed + { + public: + /*-----------------------------------------------------------------------------*/ + /* Debug Draw Functions */ + /*-----------------------------------------------------------------------------*/ + static void DrawLine(Vector3 from, Vector3 to); + static void DrawLine(Vector3 from, Vector3 to, Color color); + static void DrawWireCube(Vector3 center, Vector3 extents); + static void DrawWireCube(Vector3 center, Vector3 extents, Color color); + static void DrawWireSphere(Vector3 center, float radius); + static void DrawWireSphere(Vector3 center, float radius, Color color); + + private: + /*-----------------------------------------------------------------------------*/ + /* Data Members */ + /*-----------------------------------------------------------------------------*/ + Color defaultColor; + }; +} From 349f4a875b48cfae33226964414aab8660b307aa Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Wed, 9 Nov 2022 10:22:11 +0800 Subject: [PATCH 31/59] Added full implementation of Gizmos class --- SHADE_Managed/src/Utility/Gizmos.cxx | 46 +++++++++++++++++++++ SHADE_Managed/src/Utility/Gizmos.hxx | 60 ++++++++++++++++++++++++++-- TempScriptsFolder/RaccoonShowcase.cs | 6 +++ 3 files changed, 108 insertions(+), 4 deletions(-) diff --git a/SHADE_Managed/src/Utility/Gizmos.cxx b/SHADE_Managed/src/Utility/Gizmos.cxx index 47d86251..21636a5d 100644 --- a/SHADE_Managed/src/Utility/Gizmos.cxx +++ b/SHADE_Managed/src/Utility/Gizmos.cxx @@ -16,8 +16,54 @@ of DigiPen Institute of Technology is prohibited. #include "SHpch.h" // Primary Header #include "Gizmos.hxx" +#include "Convert.hxx" +#include "Tools/SHDebugDraw.h" // External Dependencies namespace SHADE { + /*---------------------------------------------------------------------------------*/ + /* Public Properties */ + /*---------------------------------------------------------------------------------*/ + Color Gizmos::Color::get() + { + return defaultColor; + } + void Gizmos::Color::set(SHADE::Color color) + { + defaultColor = color; + } + + /*---------------------------------------------------------------------------------*/ + /* Debug Draw Functions */ + /*---------------------------------------------------------------------------------*/ + void Gizmos::DrawLine(Vector3 from, Vector3 to) + { + DrawLine(from, to, defaultColor); + } + + void Gizmos::DrawLine(Vector3 from, Vector3 to, SHADE::Color color) + { + SHDebugDraw::Line(Convert::ToNative(color), Convert::ToNative(from), Convert::ToNative(to)); + } + + void Gizmos::DrawWireCube(Vector3 center, Vector3 extents) + { + DrawWireCube(center, extents, defaultColor); + } + + void Gizmos::DrawWireCube(Vector3 center, Vector3 extents, SHADE::Color color) + { + SHDebugDraw::Cube(Convert::ToNative(color), Convert::ToNative(center), Convert::ToNative(extents)); + } + + void Gizmos::DrawWireSphere(Vector3 center, float radius) + { + DrawWireSphere(center, radius, defaultColor); + } + + void Gizmos::DrawWireSphere(Vector3 center, float radius, SHADE::Color color) + { + SHDebugDraw::Sphere(Convert::ToNative(color), Convert::ToNative(center), radius); + } } diff --git a/SHADE_Managed/src/Utility/Gizmos.hxx b/SHADE_Managed/src/Utility/Gizmos.hxx index f0b082d7..1878d867 100644 --- a/SHADE_Managed/src/Utility/Gizmos.hxx +++ b/SHADE_Managed/src/Utility/Gizmos.hxx @@ -26,20 +26,72 @@ namespace SHADE public value class Gizmos abstract sealed { public: + /*-----------------------------------------------------------------------------*/ + /* Public Properties */ + /*-----------------------------------------------------------------------------*/ + /// + /// Default colour that will be used for drawing debug primitives if the color + /// parameter is not specified. + /// + static property Color Color + { + SHADE::Color get(); + void set(SHADE::Color color); + } /*-----------------------------------------------------------------------------*/ /* Debug Draw Functions */ /*-----------------------------------------------------------------------------*/ + /// + /// Renders a line between two points in world space. + /// Uses Color to render. + /// + /// First point of the line. + /// Second point of the line. static void DrawLine(Vector3 from, Vector3 to); - static void DrawLine(Vector3 from, Vector3 to, Color color); + /// + /// Renders a line between two points in world space. + /// + /// First point of the line. + /// Second point of the line. + /// Colour of the line. + static void DrawLine(Vector3 from, Vector3 to, SHADE::Color color); + /// + /// Renders a wireframe cube centered around the position specified in world + /// space. + /// Uses Color to render. + /// + /// Position where the cube wil be centered at. + /// Size of the rendered cube. static void DrawWireCube(Vector3 center, Vector3 extents); - static void DrawWireCube(Vector3 center, Vector3 extents, Color color); + /// + /// Renders a wireframe cube centered around the position specified in world + /// space. + /// + /// Position where the cube wil be centered at. + /// Size of the rendered cube. + /// Colour of the cube. + static void DrawWireCube(Vector3 center, Vector3 extents, SHADE::Color color); + /// + /// Renders a wireframe sphere centered around the position specified in world + /// space. + /// Uses Color to render. + /// + /// Position where the sphere wil be centered at. + /// Radius of the rendered sphere. static void DrawWireSphere(Vector3 center, float radius); - static void DrawWireSphere(Vector3 center, float radius, Color color); + /// + /// Renders a wireframe sphere centered around the position specified in world + /// space. + /// + /// Position where the sphere wil be centered at. + /// Radius of the rendered sphere. + /// Colour of the sphere. + static void DrawWireSphere(Vector3 center, float radius, SHADE::Color color); private: /*-----------------------------------------------------------------------------*/ /* Data Members */ /*-----------------------------------------------------------------------------*/ - Color defaultColor; + static SHADE::Color defaultColor = SHADE::Color::White; }; } diff --git a/TempScriptsFolder/RaccoonShowcase.cs b/TempScriptsFolder/RaccoonShowcase.cs index da0b89d2..4583a699 100644 --- a/TempScriptsFolder/RaccoonShowcase.cs +++ b/TempScriptsFolder/RaccoonShowcase.cs @@ -36,4 +36,10 @@ public class RaccoonShowcase : Script //Transform.LocalRotation = new Vector3(0.0f, rotation, 0.0f); //Transform.LocalScale = new Vector3(System.Math.Abs(System.Math.Sin(scale.x)) * originalScale, System.Math.Abs(System.Math.Cos(scale.y)) * originalScale, System.Math.Abs(System.Math.Sin(scale.z)) * originalScale); } + + protected override void onDrawGizmos() + { + Gizmos.DrawLine(new Vector3(-1.0f, 0.0f, 0.0f), new Vector3(1.0f, 0.0f, 0.0f)); + Gizmos.DrawLine(new Vector3(-1.0f, 1.0f, 0.0f), new Vector3(1.0f, 1.0f, 0.0f), Color.Red); + } } \ No newline at end of file From a3fe98317dc4be18cbfa0b035062b75ac8abef38 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Wed, 9 Nov 2022 10:31:30 +0800 Subject: [PATCH 32/59] Fixed performance issue in scripts editor when multiple attributes are applied onto script fields --- SHADE_Managed/src/Editor/Editor.cxx | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/SHADE_Managed/src/Editor/Editor.cxx b/SHADE_Managed/src/Editor/Editor.cxx index 2afe9697..54200c1e 100644 --- a/SHADE_Managed/src/Editor/Editor.cxx +++ b/SHADE_Managed/src/Editor/Editor.cxx @@ -414,19 +414,10 @@ namespace SHADE generic Attribute Editor::hasAttribute(System::Reflection::FieldInfo^ field) { - array^ attributes = field->GetCustomAttributes(true); - for each (System::Object^ attrib in attributes) + array^ attributes = field->GetCustomAttributes(Attribute::typeid, false); + if (attributes->Length > 0) { - try - { - Attribute attribute = safe_cast(attrib); - if (attribute != nullptr) - return attribute; - } - catch (System::InvalidCastException^) - { - continue; - } + return safe_cast(attributes[0]); } // Failed to find return Attribute{}; From bbe8622d1e20c51e2f40499795e7d3bdcad5945f Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Wed, 9 Nov 2022 14:45:08 +0800 Subject: [PATCH 33/59] De-plushied SHADE_Managed comments --- SHADE_Managed/src/Components/Component.hxx | 2 +- SHADE_Managed/src/Editor/Editor.hxx | 6 +++--- SHADE_Managed/src/Engine/EngineInterface.hxx | 2 +- SHADE_Managed/src/Engine/GameObject.hxx | 2 +- SHADE_Managed/src/Math/Vector2.cxx | 2 +- SHADE_Managed/src/Math/Vector3.cxx | 2 +- SHADE_Managed/src/Math/Vector3.hxx | 3 ++- SHADE_Managed/src/Scripts/Script.cxx | 3 +-- SHADE_Managed/src/Scripts/ScriptStore.hxx | 2 +- SHADE_Managed/src/Utility/DisposableAssemblyLoadContext.cxx | 2 +- SHADE_Managed/src/Utility/DisposableAssemblyLoadContext.hxx | 2 +- 11 files changed, 14 insertions(+), 14 deletions(-) diff --git a/SHADE_Managed/src/Components/Component.hxx b/SHADE_Managed/src/Components/Component.hxx index 5ffa3952..e52ab3a7 100644 --- a/SHADE_Managed/src/Components/Component.hxx +++ b/SHADE_Managed/src/Components/Component.hxx @@ -97,7 +97,7 @@ namespace SHADE /// /// Removes all Scripts of the specified type from this GameObject. /// - /// Type of PLushieScripts to remove. + /// Type of Scripts to remove. generic where T : ref class, Script void RemoveScript(); diff --git a/SHADE_Managed/src/Editor/Editor.hxx b/SHADE_Managed/src/Editor/Editor.hxx index 6b59589a..109842b5 100644 --- a/SHADE_Managed/src/Editor/Editor.hxx +++ b/SHADE_Managed/src/Editor/Editor.hxx @@ -39,10 +39,10 @@ namespace SHADE /// The Entity to render the Scripts of. static void RenderScriptsInInspector(Entity entity); /// - /// Renders a dropdown button that allows for the addition of PlushieScripts - /// onto the specified Entity. + /// Renders a dropdown button that allows for the addition of Scripts onto the + /// specified Entity. /// - /// The Entity to add PlushieScripts to. + /// The Entity to add Scripts to. static void RenderScriptAddButton(Entity entity); /*-----------------------------------------------------------------------------*/ diff --git a/SHADE_Managed/src/Engine/EngineInterface.hxx b/SHADE_Managed/src/Engine/EngineInterface.hxx index 4fd8f7b3..37ded4eb 100644 --- a/SHADE_Managed/src/Engine/EngineInterface.hxx +++ b/SHADE_Managed/src/Engine/EngineInterface.hxx @@ -20,7 +20,7 @@ namespace SHADE { /// /// Static class that contains the functions for interfacing with the core - /// PlushieEngine written in C++ for managing the lifecycle of managed code. + /// SHADE Engine written in C++ for managing the lifecycle of managed code. /// private ref class EngineInterface abstract sealed { diff --git a/SHADE_Managed/src/Engine/GameObject.hxx b/SHADE_Managed/src/Engine/GameObject.hxx index 030b917c..02a0ed4f 100644 --- a/SHADE_Managed/src/Engine/GameObject.hxx +++ b/SHADE_Managed/src/Engine/GameObject.hxx @@ -210,7 +210,7 @@ namespace SHADE /// /// Removes all Scripts of the specified type from this GameObject. /// - /// Type of PLushieScripts to remove. + /// Type of Scripts to remove. generic where T : ref class, Script void RemoveScript(); diff --git a/SHADE_Managed/src/Math/Vector2.cxx b/SHADE_Managed/src/Math/Vector2.cxx index 42080d60..8242a11c 100644 --- a/SHADE_Managed/src/Math/Vector2.cxx +++ b/SHADE_Managed/src/Math/Vector2.cxx @@ -276,4 +276,4 @@ namespace SHADE { return !(lhs == rhs); } -} // namespace PlushieAPI::Mathematics \ No newline at end of file +} diff --git a/SHADE_Managed/src/Math/Vector3.cxx b/SHADE_Managed/src/Math/Vector3.cxx index 83adbb38..f2286aa7 100644 --- a/SHADE_Managed/src/Math/Vector3.cxx +++ b/SHADE_Managed/src/Math/Vector3.cxx @@ -294,4 +294,4 @@ namespace SHADE { return Vector3(vec); } -} // namespace PlushieAPI::Mathematics \ No newline at end of file +} diff --git a/SHADE_Managed/src/Math/Vector3.hxx b/SHADE_Managed/src/Math/Vector3.hxx index 4cdf653e..189f2930 100644 --- a/SHADE_Managed/src/Math/Vector3.hxx +++ b/SHADE_Managed/src/Math/Vector3.hxx @@ -439,4 +439,5 @@ namespace SHADE /// Vector2 to convert from. static explicit operator Vector3(Vector2 vec); }; -} // namespace PlushieAPI::Mathematics +} + diff --git a/SHADE_Managed/src/Scripts/Script.cxx b/SHADE_Managed/src/Scripts/Script.cxx index bd6d7bef..9d6cadb8 100644 --- a/SHADE_Managed/src/Scripts/Script.cxx +++ b/SHADE_Managed/src/Scripts/Script.cxx @@ -3,8 +3,7 @@ \author Tng Kah Wei, kahwei.tng, 390009620 \par email: kahwei.tng\@digipen.edu \date Oct 28, 2021 -\brief Contains the definition of the functions for the PlushieScript managed - class. +\brief Contains the definition of the functions for the Script managed class. Note: This file is written in C++17/CLI. diff --git a/SHADE_Managed/src/Scripts/ScriptStore.hxx b/SHADE_Managed/src/Scripts/ScriptStore.hxx index c151392f..23440f3d 100644 --- a/SHADE_Managed/src/Scripts/ScriptStore.hxx +++ b/SHADE_Managed/src/Scripts/ScriptStore.hxx @@ -36,7 +36,7 @@ namespace SHADE /// /// /// Type of script to add. - /// This needs to be a default constructable PlushieScript. + /// This needs to be a default constructable Script. /// /// The entity to add a script to. /// Reference to the script added. diff --git a/SHADE_Managed/src/Utility/DisposableAssemblyLoadContext.cxx b/SHADE_Managed/src/Utility/DisposableAssemblyLoadContext.cxx index ebf2e987..e19c4d06 100644 --- a/SHADE_Managed/src/Utility/DisposableAssemblyLoadContext.cxx +++ b/SHADE_Managed/src/Utility/DisposableAssemblyLoadContext.cxx @@ -33,4 +33,4 @@ namespace SHADE { return nullptr; } -} // namespace PlushieAPI \ No newline at end of file +} diff --git a/SHADE_Managed/src/Utility/DisposableAssemblyLoadContext.hxx b/SHADE_Managed/src/Utility/DisposableAssemblyLoadContext.hxx index 433dd85e..14d612b3 100644 --- a/SHADE_Managed/src/Utility/DisposableAssemblyLoadContext.hxx +++ b/SHADE_Managed/src/Utility/DisposableAssemblyLoadContext.hxx @@ -36,4 +36,4 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ System::Reflection::Assembly^ Load(System::Reflection::AssemblyName^ assemblyName) override; }; -} // namespace PlushieAPI \ No newline at end of file +} From eeab3494ba35bd395646ebee60829203863ee3b8 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 10 Nov 2022 03:30:02 +0800 Subject: [PATCH 34/59] Reworked SceneGraph Interface --- Assets/Scenes/M2Scene.shade | 84 ++--- .../HierarchyPanel/SHHierarchyPanel.cpp | 4 +- SHADE_Engine/src/Scene/SHSceneGraph.cpp | 337 ++++++------------ SHADE_Engine/src/Scene/SHSceneGraph.h | 109 ++---- SHADE_Engine/src/Scene/SHSceneNode.cpp | 143 ++++++++ SHADE_Engine/src/Scene/SHSceneNode.h | 82 +++++ SHADE_Managed/src/Engine/GameObject.cxx | 2 +- 7 files changed, 405 insertions(+), 356 deletions(-) create mode 100644 SHADE_Engine/src/Scene/SHSceneNode.cpp create mode 100644 SHADE_Engine/src/Scene/SHSceneNode.h diff --git a/Assets/Scenes/M2Scene.shade b/Assets/Scenes/M2Scene.shade index 30dea780..b2a5683f 100644 --- a/Assets/Scenes/M2Scene.shade +++ b/Assets/Scenes/M2Scene.shade @@ -124,48 +124,6 @@ Mesh: 144838771 Material: 123745521 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: ~ - EID: 6 Name: AI IsActive: true @@ -226,4 +184,46 @@ 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/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp index e2c39ad8..ff65ba58 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp @@ -419,7 +419,7 @@ namespace SHADE void SHEntityParentCommand::Execute() { - auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); + auto& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); for (auto const& eid : entities) { if (entityParentData[eid].newParentEID == MAX_EID) @@ -431,7 +431,7 @@ namespace SHADE void SHEntityParentCommand::Undo() { - auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); + auto& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); for (auto const& eid : entities) { if (entityParentData[eid].oldParentEID == MAX_EID) diff --git a/SHADE_Engine/src/Scene/SHSceneGraph.cpp b/SHADE_Engine/src/Scene/SHSceneGraph.cpp index df46b3fb..900d482a 100644 --- a/SHADE_Engine/src/Scene/SHSceneGraph.cpp +++ b/SHADE_Engine/src/Scene/SHSceneGraph.cpp @@ -16,8 +16,6 @@ // Project Headers #include "ECS_Base/Managers/SHEntityManager.h" #include "Events/SHEventManager.hpp" -#include "Tools/SHLogger.h" -#include "Tools/SHException.h" namespace SHADE { @@ -25,56 +23,6 @@ namespace SHADE /* Constructors & Destructor Definitions */ /*-----------------------------------------------------------------------------------*/ - SHSceneNode::SHSceneNode(EntityID eid, SHSceneNode* parent) noexcept - : active { true } - , entityID { eid } - , parent { parent } - {} - - - SHSceneNode::SHSceneNode(const SHSceneNode& rhs) noexcept - : active { rhs.active } - , entityID { rhs.entityID } - , parent { rhs.parent } - { - std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children)); - } - - SHSceneNode::SHSceneNode(SHSceneNode&& rhs) noexcept - : active { rhs.active } - , entityID { rhs.entityID } - , parent { rhs.parent } - { - std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children)); - } - - SHSceneNode& SHSceneNode::operator=(const SHSceneNode& rhs) noexcept - { - if (this == &rhs) - return *this; - - active = rhs.active; - entityID = rhs.entityID; - parent = rhs.parent; - - children.clear(); - std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children)); - - return *this; - } - - SHSceneNode& SHSceneNode::operator=(SHSceneNode&& rhs) noexcept - { - active = rhs.active; - entityID = rhs.entityID; - parent = rhs.parent; - - children.clear(); - std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children)); - - return *this; - } - SHSceneGraph::SHSceneGraph() noexcept : root { nullptr } { @@ -110,56 +58,6 @@ namespace SHADE /* Getter Function Definitions */ /*-----------------------------------------------------------------------------------*/ - bool SHSceneNode::IsActive() const noexcept - { - return active; - } - - EntityID SHSceneNode::GetEntityID() const noexcept - { - return entityID; - } - - SHSceneNode* SHSceneNode::GetParent() const noexcept - { - return parent; - } - - const std::vector& SHSceneNode::GetChildren() const noexcept - { - return children; - } - - SHSceneNode* SHSceneNode::GetChild(EntityID childID) const noexcept - { - //////////////////////////////////////// - // Error handling - if (!SHEntityManager::IsValidEID(childID)) - { - SHLOG_ERROR("Child Entity {} is invalid! Unable to get child from Entity {}", childID, entityID) - return nullptr; - } - - if (children.empty()) - { - SHLOG_WARNING("Entity {} has no children!", entityID) - return nullptr; - } - //////////////////////////////////////// - - // Find child - const auto ENTITY_MATCH = [&](const SHSceneNode* node) { return node->GetEntityID() == childID; }; - - const auto CHILD_ITER = std::ranges::find_if(children.begin(), children.end(),ENTITY_MATCH); - if (CHILD_ITER == children.end()) - { - SHLOG_WARNING("Entity {} is not a child of Entity {}! Unable to retrieve child node!", childID, entityID) - return nullptr; - } - - return *CHILD_ITER; - } - const SHSceneNode* SHSceneGraph::GetRoot() const noexcept { if (root != nullptr) @@ -313,41 +211,7 @@ namespace SHADE /* Setter Function Definitions */ /*-----------------------------------------------------------------------------------*/ - void SHSceneNode::SetParent(SHSceneNode* parentNode) noexcept - { - if (parentNode == nullptr) - { - SHLOG_WARNING("Removing Entity {}'s parent", entityID) - - if (parent) - parent->RemoveChild(this); - - return; - } - - // Handle self assignment - if (parent && parentNode->entityID == parent->entityID) - return; - - if (parent) - parent->RemoveChild(this); - - parent = parentNode; - // Update parent's children - parent->AddChild(this); - } - - void SHSceneNode::SetActive(bool newActiveState) noexcept - { - active = newActiveState; - - for (auto* child : children) - { - SetActive(newActiveState); - } - } - - void SHSceneGraph::SetParent(EntityID entityID, SHSceneNode* parent) const noexcept + void SHSceneGraph::SetParent(EntityID entityID, SHSceneNode* newParent) noexcept { //////////////////////////////////////// // Error Handling @@ -369,18 +233,33 @@ namespace SHADE { .node = NODE_ITER->second , .oldParent = NODE_ITER->second->GetParent() - , .newParent = parent ? parent : root + , .newParent = newParent ? newParent : root }; - if (parent == nullptr) - parent = root; + if (newParent == nullptr) + newParent = root; - NODE_ITER->second->SetParent(parent); + ChangeParent(NODE_ITER->second, newParent); SHEventManager::BroadcastEvent(EVENT_DATA, SH_SCENEGRAPH_CHANGE_PARENT_EVENT); } - void SHSceneGraph::SetParent(EntityID entityID, EntityID parent) const noexcept + void SHSceneGraph::SetParent(SHSceneNode* node, SHSceneNode* newParent) noexcept + { + const SHSceneGraphChangeParentEvent EVENT_DATA + { + .node = node + , .oldParent = node->parent + , .newParent = newParent ? newParent : root + }; + + if (newParent == nullptr) + newParent = root; + + ChangeParent(node, newParent); + } + + void SHSceneGraph::SetParent(EntityID entityID, EntityID newParent) noexcept { //////////////////////////////////////// // Error Handling @@ -390,9 +269,9 @@ namespace SHADE return; } - if (!SHEntityManager::IsValidEID(parent)) + if (!SHEntityManager::IsValidEID(newParent)) { - SHLOG_ERROR("Parent Entity {} is invalid! Unable to set Entity {}'s parent!", parent, entityID) + SHLOG_ERROR("Parent Entity {} is invalid! Unable to set Entity {}'s parent!", newParent, entityID) return; } @@ -403,10 +282,10 @@ namespace SHADE return; } - auto PARENT_ITER = entityNodeMap.find(parent); + auto PARENT_ITER = entityNodeMap.find(newParent); if (PARENT_ITER == entityNodeMap.end()) { - SHLOG_ERROR("Entity {} cannot be found in the scene! Unable to parent to Entity {}", parent, entityID) + SHLOG_ERROR("Entity {} cannot be found in the scene! Unable to parent to Entity {}", newParent, entityID) return; } //////////////////////////////////////// @@ -419,92 +298,46 @@ namespace SHADE }; SHSceneNode* currentNode = NODE_ITER->second; - currentNode->SetParent(PARENT_ITER->second); + ChangeParent(currentNode, PARENT_ITER->second); SHEventManager::BroadcastEvent(EVENT_DATA, SH_SCENEGRAPH_CHANGE_PARENT_EVENT); } - /*-----------------------------------------------------------------------------------*/ - /* Public Function Member Definitions */ - /*-----------------------------------------------------------------------------------*/ - - void SHSceneNode::AddChild(SHSceneNode* newChild) noexcept + void SHSceneGraph::SetParent(SHSceneNode* node, EntityID newParent) noexcept { //////////////////////////////////////// // Error Handling - if (newChild == nullptr) + + if (!SHEntityManager::IsValidEID(newParent)) { - SHLOG_WARNING("Attempting to add a non-existent child to an entity!") + SHLOG_ERROR("Parent Entity {} is invalid! Unable to set Entity {}'s parent!", newParent, node->entityID) + return; + } + + auto PARENT_ITER = entityNodeMap.find(newParent); + if (PARENT_ITER == entityNodeMap.end()) + { + SHLOG_ERROR("Entity {} cannot be found in the scene! Unable to parent to Entity {}", newParent, node->entityID) return; } //////////////////////////////////////// - if (newChild->parent) - newChild->parent->RemoveChild(newChild); - - newChild->parent = this; - children.emplace_back(newChild); + const SHSceneGraphChangeParentEvent EVENT_DATA + { + .node = node + , .oldParent = node->parent + , .newParent = PARENT_ITER->second + }; + + ChangeParent(node, PARENT_ITER->second); + + SHEventManager::BroadcastEvent(EVENT_DATA, SH_SCENEGRAPH_CHANGE_PARENT_EVENT); } - bool SHSceneNode::RemoveChild(EntityID childID) noexcept - { - //////////////////////////////////////// - // Error Handling - if (!SHEntityManager::IsValidEID(childID)) - { - SHLOG_ERROR("Entity {} is invalid!", childID) - return false; - } - //////////////////////////////////////// - auto childIter = std::find_if(children.begin(), children.end(), [&](SHSceneNode* node) - { - return node->GetEntityID() == childID; - }); - - if (childIter == children.end()) - { - SHLOG_WARNING("Unable to remove Entity {} from Entity {} since it is not it's child!", childID, entityID) - return false; - } - - (*childIter)->parent = nullptr; - childIter = children.erase(childIter); - - return true; - } - - bool SHSceneNode::RemoveChild(SHSceneNode* childToRemove) noexcept - { - //////////////////////////////////////// - // Error Handling - if (childToRemove == nullptr) - { - SHLOG_WARNING("Attempting to remove non-existent child from Entity {}", entityID) - return false; - } - //////////////////////////////////////// - - auto childIter = std::find(children.begin(), children.end(), childToRemove); - if (childIter == children.end()) - { - SHLOG_WARNING("Unable to remove Entity {} from Entity {} since it is not it's child!", childToRemove->entityID, entityID) - return false; - } - - childIter = children.erase(childIter); - childToRemove->parent = nullptr; - - return true; - } - - void SHSceneNode::RemoveAllChildren() noexcept - { - for (const auto child : children) - child->parent = nullptr; - - children.clear(); - } + /*-----------------------------------------------------------------------------------*/ + /* Public Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ SHSceneNode* SHSceneGraph::AddNode(EntityID entityID, SHSceneNode* parent) { @@ -528,13 +361,12 @@ namespace SHADE if (parent == nullptr) { // Specific handling for root to avoid a warning when removing a non-existent child - parent = root; newNode->parent = root; root->children.emplace_back(newNode); } else { - newNode->SetParent(parent); + ChangeParent(newNode, parent); } return newNode; @@ -557,9 +389,8 @@ namespace SHADE // Remove reference of current node from parent SHSceneNode* currentNode = NODE_ITER->second; - SHSceneNode* parent = currentNode->GetParent(); - if (parent != nullptr) - parent->RemoveChild(currentNode); + if (currentNode->parent != nullptr) + RemoveChild(currentNode->parent, currentNode); ReleaseNode(currentNode); return true; @@ -568,9 +399,8 @@ namespace SHADE bool SHSceneGraph::RemoveNode(SHSceneNode* nodeToRemove) noexcept { // Remove reference of current node from parent - SHSceneNode* parent = nodeToRemove->GetParent(); - if (parent != nullptr) - parent->RemoveChild(nodeToRemove); + if (nodeToRemove->parent != nullptr) + RemoveChild(nodeToRemove->parent, nodeToRemove); ReleaseNode(nodeToRemove); return true; @@ -594,11 +424,6 @@ namespace SHADE SHSceneNode* SHSceneGraph::AllocateNode(EntityID entityID) { SHSceneNode* newNode = new SHSceneNode{entityID}; - - //#ifdef _DEBUG - // SHLOG_INFO("Allocated a new Scene Node for Entity {}!", entityID) - //#endif - entityNodeMap.emplace(entityID, newNode); return newNode; } @@ -608,19 +433,65 @@ namespace SHADE SHASSERT(node != nullptr, "Attempting to release Invalid Node!") // Remove parent's reference to this node if there is a parent - if (node->GetParent() != nullptr) - node->GetParent()->RemoveChild(node); + if (node->parent != nullptr) + RemoveChild(node->parent, node); // Remove child's references to this node. Children end up as floating nodes. for (auto* child : node->GetChildren()) { - child->SetParent(nullptr); + ChangeParent(child, nullptr); } entityNodeMap.erase(node->GetEntityID()); delete node; } + void SHSceneGraph::ChangeParent(SHSceneNode* node, SHSceneNode* newParent) + { + // Handle self assignment + if (node->parent != nullptr && newParent != nullptr && node->parent->entityID == newParent->entityID) + return; + + // Remove child + if (node->parent) + RemoveChild(node->parent, node); + + if (newParent == nullptr) + { + SHLOG_WARNING("Removing Entity {}'s parent", node->entityID) + return; + } + + node->parent = newParent; + // Update parent's children + AddChild(newParent, node); + } + + void SHSceneGraph::AddChild(SHSceneNode* node, SHSceneNode* newChild) + { + SHASSERT(node != nullptr, "Attempting to modify a non-existent scene node!") + SHASSERT(newChild != nullptr, "Attempting to add a non-existent child to a SceneNode!") + + if (newChild->parent) + RemoveChild(newChild->parent, newChild); + + newChild->parent = node; + node->children.emplace_back(newChild); + } + + void SHSceneGraph::RemoveChild(SHSceneNode* node, SHSceneNode* childToRemove) + { + SHASSERT(node != nullptr, "Attempting to modify a non-existent scene node!") + SHASSERT(childToRemove != nullptr, "Attempting to remove a non-existent child from a SceneNode!") + + auto childIter = std::find(node->children.begin(), node->children.end(), childToRemove); + if (childIter == node->children.end()) + return; + + childIter = node->children.erase(childIter); + childToRemove->parent = nullptr; + } + void SHSceneGraph::TraverseAndInvokeFunction(const SHSceneNode* node, const UnaryFunction& function) { for (auto* child : node->children) diff --git a/SHADE_Engine/src/Scene/SHSceneGraph.h b/SHADE_Engine/src/Scene/SHSceneGraph.h index 45ab48e5..99de9c44 100644 --- a/SHADE_Engine/src/Scene/SHSceneGraph.h +++ b/SHADE_Engine/src/Scene/SHSceneGraph.h @@ -1,7 +1,7 @@ /**************************************************************************************** * \file SHSceneGraph.h * \author Diren D Bharwani, diren.dbharwani, 390002520 - * \brief Interface for a Scene Graph & Scene Nodes. + * \brief Interface for a Scene Graph. * * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or * disclosure of this file or its contents without the prior written consent @@ -15,81 +15,14 @@ // Project Headers #include "ECS_Base/Entity/SHEntity.h" #include "SH_API.h" +#include "SHSceneNode.h" namespace SHADE { - /*-----------------------------------------------------------------------------------*/ - /* Forward Declarations */ - /*-----------------------------------------------------------------------------------*/ - - class SHSceneGraph; - /*-----------------------------------------------------------------------------------*/ /* Type Definitions */ /*-----------------------------------------------------------------------------------*/ - class SH_API SHSceneNode - { - private: - /*---------------------------------------------------------------------------------*/ - /* Friends */ - /*---------------------------------------------------------------------------------*/ - - friend class SHSceneGraph; - - public: - /*---------------------------------------------------------------------------------*/ - /* Constructors & Destructor */ - /*---------------------------------------------------------------------------------*/ - - ~SHSceneNode () = default; - - SHSceneNode (EntityID eid, SHSceneNode* parent = nullptr) noexcept; - SHSceneNode (const SHSceneNode& rhs) noexcept; - SHSceneNode (SHSceneNode&& rhs) noexcept; - SHSceneNode& operator= (const SHSceneNode& rhs) noexcept; - SHSceneNode& operator= (SHSceneNode&& rhs) noexcept; - - /*---------------------------------------------------------------------------------*/ - /* Getter Functions */ - /*---------------------------------------------------------------------------------*/ - - [[nodiscard]] bool IsActive () const noexcept; - [[nodiscard]] EntityID GetEntityID () const noexcept; - [[nodiscard]] SHSceneNode* GetParent () const noexcept; - [[nodiscard]] const std::vector& GetChildren () const noexcept; - - [[nodiscard]] SHSceneNode* GetChild (EntityID childID) const noexcept; - - /*---------------------------------------------------------------------------------*/ - /* Setter Functions */ - /*---------------------------------------------------------------------------------*/ - - void SetParent (SHSceneNode* parentNode) noexcept; - void SetActive (bool newActiveState) noexcept; - - /*---------------------------------------------------------------------------------*/ - /* Function Members */ - /*---------------------------------------------------------------------------------*/ - - void AddChild (SHSceneNode* newChild) noexcept; - - bool RemoveChild (EntityID childID) noexcept; - bool RemoveChild (SHSceneNode* childToRemove) noexcept; - - void RemoveAllChildren () noexcept; - - private: - /*---------------------------------------------------------------------------------*/ - /* Data Members */ - /*---------------------------------------------------------------------------------*/ - - bool active; - EntityID entityID; - SHSceneNode* parent; - std::vector children; - }; - class SH_API SHSceneGraph { public: @@ -130,19 +63,22 @@ namespace SHADE /* Setter Functions */ /*---------------------------------------------------------------------------------*/ - void SetParent (EntityID entityID, SHSceneNode* parent) const noexcept; - void SetParent (EntityID entityID, EntityID parent) const noexcept; + void SetParent (EntityID entityID, SHSceneNode* newParent) noexcept; + void SetParent (SHSceneNode* node, SHSceneNode* newParent) noexcept; + + void SetParent (EntityID entityID, EntityID newParent) noexcept; + void SetParent (SHSceneNode* node, EntityID newParent) noexcept; /*---------------------------------------------------------------------------------*/ /* Function Members */ /*---------------------------------------------------------------------------------*/ SHSceneNode* AddNode (EntityID entityID, SHSceneNode* parent = nullptr); - bool RemoveNode (EntityID entityID) noexcept; - bool RemoveNode (SHSceneNode* nodeToRemove) noexcept; - void Reset () noexcept; + bool RemoveNode (EntityID entityID) noexcept; + bool RemoveNode (SHSceneNode* nodeToRemove) noexcept; + void Reset () noexcept; - void Traverse (const UnaryFunction& function) const; + void Traverse (const UnaryFunction& function) const; private: /*---------------------------------------------------------------------------------*/ @@ -156,9 +92,14 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ - SHSceneNode* AllocateNode (EntityID entityID); - void ReleaseNode (SHSceneNode* node) noexcept; - static void TraverseAndInvokeFunction (const SHSceneNode* node, const UnaryFunction& function); + SHSceneNode* AllocateNode (EntityID entityID); + void ReleaseNode (SHSceneNode* node) noexcept; + + void ChangeParent (SHSceneNode* node, SHSceneNode* newParent); + void AddChild (SHSceneNode* node, SHSceneNode* newChild); + void RemoveChild (SHSceneNode* node, SHSceneNode* childToRemove); + + static void TraverseAndInvokeFunction (const SHSceneNode* node, const UnaryFunction& function); }; /*-----------------------------------------------------------------------------------*/ @@ -172,4 +113,16 @@ namespace SHADE SHSceneNode* newParent; }; + struct SHSceneGraphAddChildEvent + { + SHSceneNode* parent; + SHSceneNode* addedChild; + }; + + struct SHSceneGraphRemoveChildEvent + { + SHSceneNode* parent; + SHSceneNode* removedChild; + }; + } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Scene/SHSceneNode.cpp b/SHADE_Engine/src/Scene/SHSceneNode.cpp new file mode 100644 index 00000000..b619d464 --- /dev/null +++ b/SHADE_Engine/src/Scene/SHSceneNode.cpp @@ -0,0 +1,143 @@ +/**************************************************************************************** + * \file SHSceneNode.c[[ + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for a Scene Node. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#include + +// Primary Header +#include "SHSceneNode.h" + +// Project Headers +#include "ECS_Base/Managers/SHEntityManager.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Constructors & Destructor Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHSceneNode::SHSceneNode(EntityID eid, SHSceneNode* parent) noexcept + : active { true } + , entityID { eid } + , parent { parent } + {} + + + SHSceneNode::SHSceneNode(const SHSceneNode& rhs) noexcept + : active { rhs.active } + , entityID { rhs.entityID } + , parent { rhs.parent } + { + std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children)); + } + + SHSceneNode::SHSceneNode(SHSceneNode&& rhs) noexcept + : active { rhs.active } + , entityID { rhs.entityID } + , parent { rhs.parent } + { + std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children)); + } + + SHSceneNode& SHSceneNode::operator=(const SHSceneNode& rhs) noexcept + { + if (this == &rhs) + return *this; + + active = rhs.active; + entityID = rhs.entityID; + parent = rhs.parent; + + children.clear(); + std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children)); + + return *this; + } + + SHSceneNode& SHSceneNode::operator=(SHSceneNode&& rhs) noexcept + { + active = rhs.active; + entityID = rhs.entityID; + parent = rhs.parent; + + children.clear(); + std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children)); + + return *this; + } + + /*-----------------------------------------------------------------------------------*/ + /* Getter Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + bool SHSceneNode::IsActive() const noexcept + { + return active; + } + + EntityID SHSceneNode::GetEntityID() const noexcept + { + return entityID; + } + + SHSceneNode* SHSceneNode::GetParent() const noexcept + { + return parent; + } + + const std::vector& SHSceneNode::GetChildren() const noexcept + { + return children; + } + + SHSceneNode* SHSceneNode::GetChild(EntityID childID) const noexcept + { + //////////////////////////////////////// + // Error handling + if (!SHEntityManager::IsValidEID(childID)) + { + SHLOG_ERROR("Child Entity {} is invalid! Unable to get child from Entity {}", childID, entityID) + return nullptr; + } + + if (children.empty()) + { + SHLOG_WARNING("Entity {} has no children!", entityID) + return nullptr; + } + //////////////////////////////////////// + + // Find child + const auto ENTITY_MATCH = [&](const SHSceneNode* node) { return node->GetEntityID() == childID; }; + + const auto CHILD_ITER = std::ranges::find_if(children.begin(), children.end(),ENTITY_MATCH); + if (CHILD_ITER == children.end()) + { + SHLOG_WARNING("Entity {} is not a child of Entity {}! Unable to retrieve child node!", childID, entityID) + return nullptr; + } + + return *CHILD_ITER; + } + + /*-----------------------------------------------------------------------------------*/ + /* Setter Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHSceneNode::SetActive(bool newActiveState) noexcept + { + active = newActiveState; + + for (auto* child : children) + { + SetActive(newActiveState); + } + } + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Scene/SHSceneNode.h b/SHADE_Engine/src/Scene/SHSceneNode.h new file mode 100644 index 00000000..87bd8d0b --- /dev/null +++ b/SHADE_Engine/src/Scene/SHSceneNode.h @@ -0,0 +1,82 @@ +/**************************************************************************************** + * \file SHSceneNode.h + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for a Scene Node. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#pragma once + +#include + +// Project Headers +#include "ECS_Base/Entity/SHEntity.h" +#include "SH_API.h" +#include "SHSceneGraph.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Forward Declarations */ + /*-----------------------------------------------------------------------------------*/ + + class SHSceneGraph; + + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + + class SH_API SHSceneNode + { + private: + /*---------------------------------------------------------------------------------*/ + /* Friends */ + /*---------------------------------------------------------------------------------*/ + + friend class SHSceneGraph; + + public: + /*---------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*---------------------------------------------------------------------------------*/ + + ~SHSceneNode () = default; + + SHSceneNode (EntityID eid, SHSceneNode* parent = nullptr) noexcept; + SHSceneNode (const SHSceneNode& rhs) noexcept; + SHSceneNode (SHSceneNode&& rhs) noexcept; + SHSceneNode& operator= (const SHSceneNode& rhs) noexcept; + SHSceneNode& operator= (SHSceneNode&& rhs) noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Getter Functions */ + /*---------------------------------------------------------------------------------*/ + + [[nodiscard]] bool IsActive () const noexcept; + [[nodiscard]] EntityID GetEntityID () const noexcept; + [[nodiscard]] SHSceneNode* GetParent () const noexcept; + [[nodiscard]] const std::vector& GetChildren () const noexcept; + + [[nodiscard]] SHSceneNode* GetChild (EntityID childID) const noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Setter Functions */ + /*---------------------------------------------------------------------------------*/ + + void SetActive (bool newActiveState) noexcept; + + private: + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + + bool active; + EntityID entityID; + SHSceneNode* parent; + std::vector children; + }; +} // namespace SHADE + diff --git a/SHADE_Managed/src/Engine/GameObject.cxx b/SHADE_Managed/src/Engine/GameObject.cxx index 9f15c6c9..bc17be8b 100644 --- a/SHADE_Managed/src/Engine/GameObject.cxx +++ b/SHADE_Managed/src/Engine/GameObject.cxx @@ -105,7 +105,7 @@ namespace SHADE { if (!valid) throw gcnew System::NullReferenceException(); - const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph(); + auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph(); if (newParent == nullptr) SCENE_GRAPH.SetParent(entity, nullptr); From ac217ffe973910baba4bf958bc87406030b834b3 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 10 Nov 2022 09:06:38 +0800 Subject: [PATCH 35/59] Added Add and Remove Child Events to SceneGraph --- SHADE_Engine/src/Events/SHEventDefines.h | 12 +++--- SHADE_Engine/src/Scene/SHSceneGraph.cpp | 18 ++++++++- SHADE_Engine/src/Scene/SHSceneGraph.h | 24 +----------- SHADE_Engine/src/Scene/SHSceneGraphEvents.h | 41 +++++++++++++++++++++ 4 files changed, 66 insertions(+), 29 deletions(-) create mode 100644 SHADE_Engine/src/Scene/SHSceneGraphEvents.h diff --git a/SHADE_Engine/src/Events/SHEventDefines.h b/SHADE_Engine/src/Events/SHEventDefines.h index d649fabf..d7bbf5f0 100644 --- a/SHADE_Engine/src/Events/SHEventDefines.h +++ b/SHADE_Engine/src/Events/SHEventDefines.h @@ -11,9 +11,11 @@ constexpr SHEventIdentifier SH_ENTITY_CREATION_EVENT { 2 }; constexpr SHEventIdentifier SH_COMPONENT_ADDED_EVENT { 3 }; constexpr SHEventIdentifier SH_COMPONENT_REMOVED_EVENT { 4 }; constexpr SHEventIdentifier SH_SCENEGRAPH_CHANGE_PARENT_EVENT { 5 }; -constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_ADDED_EVENT { 6 }; -constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_REMOVED_EVENT { 7 }; -constexpr SHEventIdentifier SH_EDITOR_ON_PLAY_EVENT { 8 }; -constexpr SHEventIdentifier SH_EDITOR_ON_PAUSE_EVENT { 9 }; -constexpr SHEventIdentifier SH_EDITOR_ON_STOP_EVENT { 10 }; +constexpr SHEventIdentifier SH_SCENEGRAPH_ADD_CHILD_EVENT { 6 }; +constexpr SHEventIdentifier SH_SCENEGRAPH_REMOVE_CHILD_EVENT { 7 }; +constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_ADDED_EVENT { 8 }; +constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_REMOVED_EVENT { 9 }; +constexpr SHEventIdentifier SH_EDITOR_ON_PLAY_EVENT { 10 }; +constexpr SHEventIdentifier SH_EDITOR_ON_PAUSE_EVENT { 11 }; +constexpr SHEventIdentifier SH_EDITOR_ON_STOP_EVENT { 12 }; diff --git a/SHADE_Engine/src/Scene/SHSceneGraph.cpp b/SHADE_Engine/src/Scene/SHSceneGraph.cpp index 900d482a..ff479eec 100644 --- a/SHADE_Engine/src/Scene/SHSceneGraph.cpp +++ b/SHADE_Engine/src/Scene/SHSceneGraph.cpp @@ -1,7 +1,7 @@ /**************************************************************************************** * \file SHSceneGraph.cpp * \author Diren D Bharwani, diren.dbharwani, 390002520 - * \brief Implementation for a Scene Graph & Scene Nodes. + * \brief Implementation for a Scene Graph. * * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or * disclosure of this file or its contents without the prior written consent @@ -477,6 +477,14 @@ namespace SHADE newChild->parent = node; node->children.emplace_back(newChild); + + const SHSceneGraphAddChildEvent EVENT_DATA + { + .parent = node + , .childAdded = newChild + }; + + SHEventManager::BroadcastEvent(EVENT_DATA, SH_SCENEGRAPH_ADD_CHILD_EVENT); } void SHSceneGraph::RemoveChild(SHSceneNode* node, SHSceneNode* childToRemove) @@ -490,6 +498,14 @@ namespace SHADE childIter = node->children.erase(childIter); childToRemove->parent = nullptr; + + const SHSceneGraphRemoveChildEvent EVENT_DATA + { + .parent = node + , .childRemoved = childToRemove + }; + + SHEventManager::BroadcastEvent(EVENT_DATA, SH_SCENEGRAPH_REMOVE_CHILD_EVENT); } void SHSceneGraph::TraverseAndInvokeFunction(const SHSceneNode* node, const UnaryFunction& function) diff --git a/SHADE_Engine/src/Scene/SHSceneGraph.h b/SHADE_Engine/src/Scene/SHSceneGraph.h index 99de9c44..1d448b37 100644 --- a/SHADE_Engine/src/Scene/SHSceneGraph.h +++ b/SHADE_Engine/src/Scene/SHSceneGraph.h @@ -16,6 +16,7 @@ #include "ECS_Base/Entity/SHEntity.h" #include "SH_API.h" #include "SHSceneNode.h" +#include "SHSceneGraphEvents.h" namespace SHADE { @@ -102,27 +103,4 @@ namespace SHADE static void TraverseAndInvokeFunction (const SHSceneNode* node, const UnaryFunction& function); }; - /*-----------------------------------------------------------------------------------*/ - /* Event Data Definitions */ - /*-----------------------------------------------------------------------------------*/ - - struct SHSceneGraphChangeParentEvent - { - SHSceneNode* node; - SHSceneNode* oldParent; - SHSceneNode* newParent; - }; - - struct SHSceneGraphAddChildEvent - { - SHSceneNode* parent; - SHSceneNode* addedChild; - }; - - struct SHSceneGraphRemoveChildEvent - { - SHSceneNode* parent; - SHSceneNode* removedChild; - }; - } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Scene/SHSceneGraphEvents.h b/SHADE_Engine/src/Scene/SHSceneGraphEvents.h new file mode 100644 index 00000000..ccdf06be --- /dev/null +++ b/SHADE_Engine/src/Scene/SHSceneGraphEvents.h @@ -0,0 +1,41 @@ +/**************************************************************************************** + * \file SHSceneGraphEvents.h + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for Scene Graph Events. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#pragma once + +// Project Headers +#include "SHSceneNode.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Event Data Definitions */ + /*-----------------------------------------------------------------------------------*/ + + struct SHSceneGraphChangeParentEvent + { + SHSceneNode* node; + SHSceneNode* oldParent; + SHSceneNode* newParent; + }; + + struct SHSceneGraphAddChildEvent + { + SHSceneNode* parent; + SHSceneNode* childAdded; + }; + + struct SHSceneGraphRemoveChildEvent + { + SHSceneNode* parent; + SHSceneNode* childRemoved; + }; + +} // namespace SHADE \ No newline at end of file From 08b3cbafcd4e2a08fd5701179fce20c700b89704 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 10 Nov 2022 10:20:54 +0800 Subject: [PATCH 36/59] Added IsChildOf method to SceneGraph --- SHADE_Engine/src/Scene/SHSceneGraph.cpp | 147 ++++++++++++++++++++++++ SHADE_Engine/src/Scene/SHSceneGraph.h | 14 ++- 2 files changed, 156 insertions(+), 5 deletions(-) diff --git a/SHADE_Engine/src/Scene/SHSceneGraph.cpp b/SHADE_Engine/src/Scene/SHSceneGraph.cpp index ff479eec..e2bd58e2 100644 --- a/SHADE_Engine/src/Scene/SHSceneGraph.cpp +++ b/SHADE_Engine/src/Scene/SHSceneGraph.cpp @@ -263,6 +263,7 @@ namespace SHADE { //////////////////////////////////////// // Error Handling + if (!SHEntityManager::IsValidEID(entityID)) { SHLOG_ERROR("Entity {} is invalid! Unable to set parent of an invalid entity!", entityID) @@ -374,6 +375,8 @@ namespace SHADE bool SHSceneGraph::RemoveNode(EntityID entityID) noexcept { + //////////////////////////////////////// + // Error Handling if (!SHEntityManager::IsValidEID(entityID)) { SHLOG_ERROR("Entity {} is invalid!", entityID) @@ -386,6 +389,7 @@ namespace SHADE SHLOG_ERROR("Entity {} does not exist in the scene!", entityID) return false; } + //////////////////////////////////////// // Remove reference of current node from parent SHSceneNode* currentNode = NODE_ITER->second; @@ -412,6 +416,149 @@ namespace SHADE ReleaseNode(node); } + bool SHSceneGraph::IsChildOf(EntityID entityID, SHSceneNode* targetNode) noexcept + { + //////////////////////////////////////// + // Error Handling + + if (!SHEntityManager::IsValidEID(entityID)) + { + SHLOG_ERROR("Entity {} is invalid!", entityID) + return false; + } + + auto NODE_ITER = entityNodeMap.find(entityID); + if (NODE_ITER == entityNodeMap.end()) + { + SHLOG_ERROR("Entity {} cannot be found in the scene! Unable to check child!", entityID) + return false; + } + + //////////////////////////////////////// + + // Handle self-checks + if (NODE_ITER->second == targetNode) + { + SHLOG_WARNING("Entity {} cannot be a child of itself!", entityID) + return false; + } + + // Search for a matching target until the root + const SHSceneNode* CURRENT_TARGET = NODE_ITER->second->parent; + while (CURRENT_TARGET != root) + { + if (CURRENT_TARGET == targetNode) + return true; + + CURRENT_TARGET = CURRENT_TARGET->parent; + } + + return false; + } + + bool SHSceneGraph::IsChildOf(SHSceneNode* node, SHSceneNode* targetNode) noexcept + { + if (!node || !targetNode) + { + SHLOG_ERROR("Attempting to check for invalid scene nodes!") + return false; + } + + if (node == targetNode) + { + SHLOG_WARNING("Entity {} cannot be a child of itself!", node->entityID) + return false; + } + + const SHSceneNode* CURRENT_TARGET = node->parent; + while (CURRENT_TARGET != root) + { + if (CURRENT_TARGET == targetNode) + return true; + + CURRENT_TARGET = CURRENT_TARGET->parent; + } + + return false; + } + + bool SHSceneGraph::IsChildOf(EntityID entityID, EntityID targetID) noexcept + { + //////////////////////////////////////// + // Error Handling + + if (!SHEntityManager::IsValidEID(entityID)) + { + SHLOG_ERROR("Entity {} is invalid!", entityID) + return false; + } + + if (!SHEntityManager::IsValidEID(targetID)) + { + SHLOG_ERROR("Entity {} is invalid!", targetID) + return false; + } + + auto NODE_ITER = entityNodeMap.find(entityID); + if (NODE_ITER == entityNodeMap.end()) + { + SHLOG_ERROR("Entity {} cannot be found in the scene! Unable to check child!", entityID) + return false; + } + + auto TARGET_ITER = entityNodeMap.find(targetID); + if (TARGET_ITER == entityNodeMap.end()) + { + SHLOG_ERROR("Entity {} cannot be found in the scene! Unable to check child!", targetID) + return false; + } + + //////////////////////////////////////// + + const SHSceneNode* CURRENT_TARGET = NODE_ITER->second->parent; + while (CURRENT_TARGET != root) + { + if (CURRENT_TARGET == TARGET_ITER->second) + return true; + + CURRENT_TARGET = CURRENT_TARGET->parent; + } + + return false; + } + + bool SHSceneGraph::IsChildOf(SHSceneNode* node, EntityID targetID) noexcept + { + //////////////////////////////////////// + // Error Handling + + if (!SHEntityManager::IsValidEID(targetID)) + { + SHLOG_ERROR("Entity {} is invalid!", targetID) + return false; + } + + auto TARGET_ITER = entityNodeMap.find(targetID); + if (TARGET_ITER == entityNodeMap.end()) + { + SHLOG_ERROR("Entity {} cannot be found in the scene! Unable to check child!", targetID) + return false; + } + + //////////////////////////////////////// + + const SHSceneNode* CURRENT_TARGET = node->parent; + while (CURRENT_TARGET != root) + { + if (CURRENT_TARGET == TARGET_ITER->second) + return true; + + CURRENT_TARGET = CURRENT_TARGET->parent; + } + + return false; + } + void SHSceneGraph::Traverse (const UnaryFunction& function) const { TraverseAndInvokeFunction(root, function); diff --git a/SHADE_Engine/src/Scene/SHSceneGraph.h b/SHADE_Engine/src/Scene/SHSceneGraph.h index 1d448b37..494f480e 100644 --- a/SHADE_Engine/src/Scene/SHSceneGraph.h +++ b/SHADE_Engine/src/Scene/SHSceneGraph.h @@ -66,7 +66,6 @@ namespace SHADE void SetParent (EntityID entityID, SHSceneNode* newParent) noexcept; void SetParent (SHSceneNode* node, SHSceneNode* newParent) noexcept; - void SetParent (EntityID entityID, EntityID newParent) noexcept; void SetParent (SHSceneNode* node, EntityID newParent) noexcept; @@ -75,11 +74,16 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ SHSceneNode* AddNode (EntityID entityID, SHSceneNode* parent = nullptr); - bool RemoveNode (EntityID entityID) noexcept; - bool RemoveNode (SHSceneNode* nodeToRemove) noexcept; - void Reset () noexcept; + bool RemoveNode (EntityID entityID) noexcept; + bool RemoveNode (SHSceneNode* nodeToRemove) noexcept; + void Reset () noexcept; - void Traverse (const UnaryFunction& function) const; + bool IsChildOf (EntityID entityID, SHSceneNode* targetNode) noexcept; + bool IsChildOf (SHSceneNode* node, SHSceneNode* targetNode) noexcept; + bool IsChildOf (EntityID entityID, EntityID targetID) noexcept; + bool IsChildOf (SHSceneNode* node, EntityID targetID) noexcept; + + void Traverse (const UnaryFunction& function) const; private: /*---------------------------------------------------------------------------------*/ From 578f384808fe1f5fe26fed136cb033e2104e8490 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 10 Nov 2022 10:24:09 +0800 Subject: [PATCH 37/59] Removed redundant overloads to restrict potential bad function calls --- SHADE_Engine/src/Scene/SHSceneGraph.cpp | 105 ------------------------ SHADE_Engine/src/Scene/SHSceneGraph.h | 6 +- 2 files changed, 1 insertion(+), 110 deletions(-) diff --git a/SHADE_Engine/src/Scene/SHSceneGraph.cpp b/SHADE_Engine/src/Scene/SHSceneGraph.cpp index e2bd58e2..6240b7bf 100644 --- a/SHADE_Engine/src/Scene/SHSceneGraph.cpp +++ b/SHADE_Engine/src/Scene/SHSceneGraph.cpp @@ -244,21 +244,6 @@ namespace SHADE SHEventManager::BroadcastEvent(EVENT_DATA, SH_SCENEGRAPH_CHANGE_PARENT_EVENT); } - void SHSceneGraph::SetParent(SHSceneNode* node, SHSceneNode* newParent) noexcept - { - const SHSceneGraphChangeParentEvent EVENT_DATA - { - .node = node - , .oldParent = node->parent - , .newParent = newParent ? newParent : root - }; - - if (newParent == nullptr) - newParent = root; - - ChangeParent(node, newParent); - } - void SHSceneGraph::SetParent(EntityID entityID, EntityID newParent) noexcept { //////////////////////////////////////// @@ -304,38 +289,6 @@ namespace SHADE SHEventManager::BroadcastEvent(EVENT_DATA, SH_SCENEGRAPH_CHANGE_PARENT_EVENT); } - void SHSceneGraph::SetParent(SHSceneNode* node, EntityID newParent) noexcept - { - //////////////////////////////////////// - // Error Handling - - if (!SHEntityManager::IsValidEID(newParent)) - { - SHLOG_ERROR("Parent Entity {} is invalid! Unable to set Entity {}'s parent!", newParent, node->entityID) - return; - } - - auto PARENT_ITER = entityNodeMap.find(newParent); - if (PARENT_ITER == entityNodeMap.end()) - { - SHLOG_ERROR("Entity {} cannot be found in the scene! Unable to parent to Entity {}", newParent, node->entityID) - return; - } - //////////////////////////////////////// - - const SHSceneGraphChangeParentEvent EVENT_DATA - { - .node = node - , .oldParent = node->parent - , .newParent = PARENT_ITER->second - }; - - ChangeParent(node, PARENT_ITER->second); - - SHEventManager::BroadcastEvent(EVENT_DATA, SH_SCENEGRAPH_CHANGE_PARENT_EVENT); - } - - /*-----------------------------------------------------------------------------------*/ /* Public Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ @@ -456,32 +409,6 @@ namespace SHADE return false; } - bool SHSceneGraph::IsChildOf(SHSceneNode* node, SHSceneNode* targetNode) noexcept - { - if (!node || !targetNode) - { - SHLOG_ERROR("Attempting to check for invalid scene nodes!") - return false; - } - - if (node == targetNode) - { - SHLOG_WARNING("Entity {} cannot be a child of itself!", node->entityID) - return false; - } - - const SHSceneNode* CURRENT_TARGET = node->parent; - while (CURRENT_TARGET != root) - { - if (CURRENT_TARGET == targetNode) - return true; - - CURRENT_TARGET = CURRENT_TARGET->parent; - } - - return false; - } - bool SHSceneGraph::IsChildOf(EntityID entityID, EntityID targetID) noexcept { //////////////////////////////////////// @@ -527,38 +454,6 @@ namespace SHADE return false; } - bool SHSceneGraph::IsChildOf(SHSceneNode* node, EntityID targetID) noexcept - { - //////////////////////////////////////// - // Error Handling - - if (!SHEntityManager::IsValidEID(targetID)) - { - SHLOG_ERROR("Entity {} is invalid!", targetID) - return false; - } - - auto TARGET_ITER = entityNodeMap.find(targetID); - if (TARGET_ITER == entityNodeMap.end()) - { - SHLOG_ERROR("Entity {} cannot be found in the scene! Unable to check child!", targetID) - return false; - } - - //////////////////////////////////////// - - const SHSceneNode* CURRENT_TARGET = node->parent; - while (CURRENT_TARGET != root) - { - if (CURRENT_TARGET == TARGET_ITER->second) - return true; - - CURRENT_TARGET = CURRENT_TARGET->parent; - } - - return false; - } - void SHSceneGraph::Traverse (const UnaryFunction& function) const { TraverseAndInvokeFunction(root, function); diff --git a/SHADE_Engine/src/Scene/SHSceneGraph.h b/SHADE_Engine/src/Scene/SHSceneGraph.h index 494f480e..5747be7b 100644 --- a/SHADE_Engine/src/Scene/SHSceneGraph.h +++ b/SHADE_Engine/src/Scene/SHSceneGraph.h @@ -65,9 +65,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ void SetParent (EntityID entityID, SHSceneNode* newParent) noexcept; - void SetParent (SHSceneNode* node, SHSceneNode* newParent) noexcept; void SetParent (EntityID entityID, EntityID newParent) noexcept; - void SetParent (SHSceneNode* node, EntityID newParent) noexcept; /*---------------------------------------------------------------------------------*/ /* Function Members */ @@ -79,9 +77,7 @@ namespace SHADE void Reset () noexcept; bool IsChildOf (EntityID entityID, SHSceneNode* targetNode) noexcept; - bool IsChildOf (SHSceneNode* node, SHSceneNode* targetNode) noexcept; - bool IsChildOf (EntityID entityID, EntityID targetID) noexcept; - bool IsChildOf (SHSceneNode* node, EntityID targetID) noexcept; + bool IsChildOf (EntityID entityID, EntityID targetID) noexcept; void Traverse (const UnaryFunction& function) const; From fa0787d349900ee3fb097baf7901c08b1168bbb7 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Thu, 10 Nov 2022 10:33:21 +0800 Subject: [PATCH 38/59] Changed hardcoded paths to use defined asset root folder Shifted scripts and project into folder in assets --- .../Scripts}/AIPrototype.cs | 0 .../Scripts}/CameraControl.cs | 0 {TempScriptsFolder => Assets/Scripts}/CameraFix.cs | 0 {TempScriptsFolder => Assets/Scripts}/Item.cs | 0 .../Scripts}/PhysicsTest.cs | 0 .../Scripts}/PickAndThrow.cs | 0 .../Scripts}/PlayerController.cs | 0 .../Scripts}/PrintWhenActive.cs | 0 .../Scripts}/RaccoonShowcase.cs | 0 .../Scripts}/RaccoonSpin.cs | 0 .../Scripts}/ThirdPersonCamera.cs | 0 SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp | 10 ++++++---- .../EditorWindow/MenuBar/SHEditorMenuBar.cpp | 6 ++++-- SHADE_Engine/src/Editor/SHEditor.cpp | 14 +++++++++----- SHADE_Engine/src/Scripting/SHScriptEngine.cpp | 4 +++- 15 files changed, 22 insertions(+), 12 deletions(-) rename {TempScriptsFolder => Assets/Scripts}/AIPrototype.cs (100%) rename {TempScriptsFolder => Assets/Scripts}/CameraControl.cs (100%) rename {TempScriptsFolder => Assets/Scripts}/CameraFix.cs (100%) rename {TempScriptsFolder => Assets/Scripts}/Item.cs (100%) rename {TempScriptsFolder => Assets/Scripts}/PhysicsTest.cs (100%) rename {TempScriptsFolder => Assets/Scripts}/PickAndThrow.cs (100%) rename {TempScriptsFolder => Assets/Scripts}/PlayerController.cs (100%) rename {TempScriptsFolder => Assets/Scripts}/PrintWhenActive.cs (100%) rename {TempScriptsFolder => Assets/Scripts}/RaccoonShowcase.cs (100%) rename {TempScriptsFolder => Assets/Scripts}/RaccoonSpin.cs (100%) rename {TempScriptsFolder => Assets/Scripts}/ThirdPersonCamera.cs (100%) diff --git a/TempScriptsFolder/AIPrototype.cs b/Assets/Scripts/AIPrototype.cs similarity index 100% rename from TempScriptsFolder/AIPrototype.cs rename to Assets/Scripts/AIPrototype.cs diff --git a/TempScriptsFolder/CameraControl.cs b/Assets/Scripts/CameraControl.cs similarity index 100% rename from TempScriptsFolder/CameraControl.cs rename to Assets/Scripts/CameraControl.cs diff --git a/TempScriptsFolder/CameraFix.cs b/Assets/Scripts/CameraFix.cs similarity index 100% rename from TempScriptsFolder/CameraFix.cs rename to Assets/Scripts/CameraFix.cs diff --git a/TempScriptsFolder/Item.cs b/Assets/Scripts/Item.cs similarity index 100% rename from TempScriptsFolder/Item.cs rename to Assets/Scripts/Item.cs diff --git a/TempScriptsFolder/PhysicsTest.cs b/Assets/Scripts/PhysicsTest.cs similarity index 100% rename from TempScriptsFolder/PhysicsTest.cs rename to Assets/Scripts/PhysicsTest.cs diff --git a/TempScriptsFolder/PickAndThrow.cs b/Assets/Scripts/PickAndThrow.cs similarity index 100% rename from TempScriptsFolder/PickAndThrow.cs rename to Assets/Scripts/PickAndThrow.cs diff --git a/TempScriptsFolder/PlayerController.cs b/Assets/Scripts/PlayerController.cs similarity index 100% rename from TempScriptsFolder/PlayerController.cs rename to Assets/Scripts/PlayerController.cs diff --git a/TempScriptsFolder/PrintWhenActive.cs b/Assets/Scripts/PrintWhenActive.cs similarity index 100% rename from TempScriptsFolder/PrintWhenActive.cs rename to Assets/Scripts/PrintWhenActive.cs diff --git a/TempScriptsFolder/RaccoonShowcase.cs b/Assets/Scripts/RaccoonShowcase.cs similarity index 100% rename from TempScriptsFolder/RaccoonShowcase.cs rename to Assets/Scripts/RaccoonShowcase.cs diff --git a/TempScriptsFolder/RaccoonSpin.cs b/Assets/Scripts/RaccoonSpin.cs similarity index 100% rename from TempScriptsFolder/RaccoonSpin.cs rename to Assets/Scripts/RaccoonSpin.cs diff --git a/TempScriptsFolder/ThirdPersonCamera.cs b/Assets/Scripts/ThirdPersonCamera.cs similarity index 100% rename from TempScriptsFolder/ThirdPersonCamera.cs rename to Assets/Scripts/ThirdPersonCamera.cs diff --git a/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp b/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp index c3c7ef03..c913030b 100644 --- a/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp +++ b/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp @@ -17,6 +17,8 @@ #include #include +const std::string AUDIO_FOLDER_PATH{ std::string(ASSET_ROOT)+ "/Audio/" }; + namespace SHADE { SHAudioSystem::SHAudioSystem() @@ -79,10 +81,10 @@ namespace SHADE //SHResourceManager::LoadAllAudio(system, soundList); - LoadBank("../../Assets/Audio/Master.bank"); - LoadBank("../../Assets/Audio/Master.strings.bank"); - //LoadBank("../../Assets/Audio/Music.bank"); - LoadBank("../../Assets/Audio/footsteps.bank"); + LoadBank((AUDIO_FOLDER_PATH + "Master.bank").data()); + LoadBank((AUDIO_FOLDER_PATH + "Master.strings.bank").data()); + //LoadBank((AUDIO_FOLDER_PATH + "Music.bank").data()); + LoadBank((AUDIO_FOLDER_PATH + "footsteps.bank").data()); //auto clip = CreateAudioClip("event:/Characters/sfx_footsteps_human"); //clip->Play(); diff --git a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp index c18f0c8c..cfb36cd0 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp @@ -24,6 +24,9 @@ #include "Serialization/SHSerialization.h" #include "Serialization/Configurations/SHConfigurationManager.h" + +const std::string LAYOUT_FOLDER_PATH{ std::string(ASSET_ROOT) + "/Editor/Layouts" }; + namespace SHADE { constexpr ImGuiWindowFlags editorMenuBarFlags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | @@ -43,8 +46,7 @@ namespace SHADE void SHEditorMenuBar::Init() { SHEditorWindow::Init(); - constexpr std::string_view path = "../../Assets/Editor/Layouts"; - for(auto const& entry : std::filesystem::directory_iterator(path)) + for(auto const& entry : std::filesystem::directory_iterator(LAYOUT_FOLDER_PATH)) { layoutPaths.push_back(entry.path()); } diff --git a/SHADE_Engine/src/Editor/SHEditor.cpp b/SHADE_Engine/src/Editor/SHEditor.cpp index 19d147e6..c4ad3459 100644 --- a/SHADE_Engine/src/Editor/SHEditor.cpp +++ b/SHADE_Engine/src/Editor/SHEditor.cpp @@ -65,6 +65,10 @@ RTTR_REGISTRATION ); } +const std::string USER_LAYOUT_PATH{ std::string(ASSET_ROOT) + "/Editor/Layouts/UserLayout.ini" }; +const std::string DEFAULT_LAYOUT_PATH{ std::string(ASSET_ROOT) + "/Editor/Layouts/Default.ini" }; +const std::string FONT_FOLDER_PATH{ std::string(ASSET_ROOT) + "/Editor/Fonts/"}; + namespace SHADE { @@ -106,7 +110,7 @@ namespace SHADE io->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls io->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; //Enable for Multi-Viewports io->ConfigFlags |= ImGuiConfigFlags_DockingEnable; //Enable docking - io->IniFilename = "../../Assets/Editor/Layouts/UserLayout.ini"; + io->IniFilename = USER_LAYOUT_PATH.data(); io->ConfigWindowsMoveFromTitleBarOnly = true; InitLayout(); @@ -236,20 +240,20 @@ namespace SHADE { if(!std::filesystem::exists(io->IniFilename)) { - std::filesystem::copy_file("../../Assets/Editor/Layouts/Default.ini", io->IniFilename); + std::filesystem::copy_file(DEFAULT_LAYOUT_PATH.data(), io->IniFilename); } //eventually load preferred layout here } void SHEditor::InitFonts() noexcept { - ImFont* mainFont = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/Segoe UI.ttf", 20.f);//TODO: Change to config based assets path + ImFont* mainFont = io->Fonts->AddFontFromFileTTF(std::string(FONT_FOLDER_PATH + "Segoe UI.ttf").data(), 20.f);//TODO: Change to config based assets path ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.GlyphOffset.y = 5.f; constexpr ImWchar icon_ranges_fa[] = { ICON_MIN_FA, ICON_MAX_FA, 0 }; - ImFont* UIFontFA = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/fa-solid-900.ttf", 20.f, &icons_config, icon_ranges_fa); //TODO: Change to config based assets path + ImFont* UIFontFA = io->Fonts->AddFontFromFileTTF(std::string(FONT_FOLDER_PATH + "fa-solid-900.ttf").data(), 20.f, &icons_config, icon_ranges_fa); //TODO: Change to config based assets path constexpr ImWchar icon_ranges_md[] = { ICON_MIN_MD, ICON_MAX_16_MD, 0 }; - ImFont* UIFontMD = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/MaterialIcons-Regular.ttf", 20.f, &icons_config, icon_ranges_md); //TODO: Change to config based assets path + ImFont* UIFontMD = io->Fonts->AddFontFromFileTTF(std::string(FONT_FOLDER_PATH + "MaterialIcons-Regular.ttf").data(), 20.f, &icons_config, icon_ranges_md); //TODO: Change to config based assets path io->Fonts->Build(); } diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp index 827f45a2..4f3fbce6 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp @@ -26,13 +26,15 @@ of DigiPen Institute of Technology is prohibited. #include "Events/SHEventManager.hpp" #include "Physics/SHPhysicsSystem.h" +#include "Assets/SHAssetMacros.h" + namespace SHADE { /*-----------------------------------------------------------------------------------*/ /* Static Definitions */ /*----------------------------------------------------------------------------------*/ const std::string SHScriptEngine::DEFAULT_CSHARP_NAMESPACE = std::string("SHADE"); - const std::string SHScriptEngine::CSPROJ_DIR = "..\\..\\TempScriptsFolder"; + const std::string SHScriptEngine::CSPROJ_DIR = std::string(ASSET_ROOT) + "/Scripts"; const std::string SHScriptEngine::CSPROJ_PATH = std::string(CSPROJ_DIR) + "\\SHADE_Scripting.csproj"; /*-----------------------------------------------------------------------------------*/ From 35bcdc5239ca3cd86ea697504f98c3355d122a9e Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Thu, 10 Nov 2022 11:14:40 +0800 Subject: [PATCH 39/59] Missed out path for config --- .../src/Serialization/Configurations/SHConfigurationManager.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SHADE_Engine/src/Serialization/Configurations/SHConfigurationManager.h b/SHADE_Engine/src/Serialization/Configurations/SHConfigurationManager.h index abf679ca..767b8c2b 100644 --- a/SHADE_Engine/src/Serialization/Configurations/SHConfigurationManager.h +++ b/SHADE_Engine/src/Serialization/Configurations/SHConfigurationManager.h @@ -25,8 +25,8 @@ namespace SHADE class SH_API SHConfigurationManager { public: - static constexpr std::string_view applicationConfigPath{"../../Assets/Application.SHConfig"}; - static constexpr std::string_view editorConfigPath{"../../Assets/Editor/Editor.SHConfig"}; + static inline std::string applicationConfigPath{ std::string(ASSET_ROOT) + "/Application.SHConfig"}; + static inline std::string editorConfigPath{ std::string(ASSET_ROOT) + "/Editor/Editor.SHConfig"}; static void SaveApplicationConfig(); static SHApplicationConfig& LoadApplicationConfig(WindowData* wndData = nullptr); From 0e5609995fd5f39ec956ec149649b27995f762ed Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Thu, 10 Nov 2022 16:44:16 +0800 Subject: [PATCH 40/59] Added data member to signal whether asset file can be compiled Properly linked meta file to file in directory Fixed extension to type conversion bug --- SHADE_Engine/src/Assets/SHAssetMacros.h | 9 +++--- SHADE_Engine/src/Assets/SHAssetManager.cpp | 8 +++-- SHADE_Engine/src/Assets/SHAssetManager.h | 2 +- SHADE_Engine/src/Filesystem/SHFileSystem.cpp | 31 ++++++++++++++++---- SHADE_Engine/src/Filesystem/SHFileSystem.h | 2 +- SHADE_Engine/src/Filesystem/SHFolder.h | 1 + 6 files changed, 38 insertions(+), 15 deletions(-) diff --git a/SHADE_Engine/src/Assets/SHAssetMacros.h b/SHADE_Engine/src/Assets/SHAssetMacros.h index 92c4b69e..e0551262 100644 --- a/SHADE_Engine/src/Assets/SHAssetMacros.h +++ b/SHADE_Engine/src/Assets/SHAssetMacros.h @@ -51,6 +51,7 @@ enum class AssetType : AssetTypeMeta SCENE, PREFAB, MATERIAL, + SCRIPT, MESH, MAX_COUNT }; @@ -91,12 +92,12 @@ constexpr std::string_view EXTENSIONS[] = { AUDIO_EXTENSION, SHADER_EXTENSION, SHADER_BUILT_IN_EXTENSION, - MATERIAL_EXTENSION, - TEXTURE_EXTENSION, + TEXTURE_EXTENSION, MODEL_EXTENSION, - SCRIPT_EXTENSION, - SCENE_EXTENSION, + SCENE_EXTENSION, PREFAB_EXTENSION, + MATERIAL_EXTENSION, + SCRIPT_EXTENSION, AUDIO_WAV_EXTENSION, }; diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index 3fd71a8e..dbe9dd27 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -338,7 +338,7 @@ namespace SHADE return result; } - void SHAssetManager::CompileAsset(AssetPath const& path) noexcept + void SHAssetManager::CompileAsset(AssetPath const& path, bool genMeta) noexcept { if (!std::filesystem::exists(path)) { @@ -360,10 +360,12 @@ namespace SHADE std::string modelPath = path.string().substr(0, path.string().find_last_of('.')); modelPath += MODEL_EXTENSION; newPath = modelPath; - - GenerateNewMeta(newPath); } + if (genMeta) + { + GenerateNewMeta(newPath); + } } FolderPointer SHAssetManager::GetRootFolder() noexcept diff --git a/SHADE_Engine/src/Assets/SHAssetManager.h b/SHADE_Engine/src/Assets/SHAssetManager.h index ba10d84f..7fd7d039 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.h +++ b/SHADE_Engine/src/Assets/SHAssetManager.h @@ -87,7 +87,7 @@ namespace SHADE static std::vector GetAllDataOfType(AssetType type) noexcept; static std::vector GetAllRecordOfType(AssetType type) noexcept; - static void CompileAsset(AssetPath const& path) noexcept; + static void CompileAsset(AssetPath const& path, bool genMeta) noexcept; static FolderPointer GetRootFolder() noexcept; diff --git a/SHADE_Engine/src/Filesystem/SHFileSystem.cpp b/SHADE_Engine/src/Filesystem/SHFileSystem.cpp index 4c0971e6..fe9b67f5 100644 --- a/SHADE_Engine/src/Filesystem/SHFileSystem.cpp +++ b/SHADE_Engine/src/Filesystem/SHFileSystem.cpp @@ -24,7 +24,20 @@ namespace SHADE return true; } - void SHFileSystem::BuildDirectory(FolderPath path, FolderPointer& root, std::unordered_map& assetCollection) noexcept + bool SHFileSystem::IsCompilable(std::string ext) noexcept + { + for (auto const& external : EXTERNALS) + { + if (ext == external) + { + return true; + } + } + + return false; + } + + void SHFileSystem::BuildDirectory(FolderPath path, FolderPointer& root, std::unordered_map& assetCollection) noexcept { std::queue folderQueue; root = new SHFolder("root"); @@ -38,9 +51,10 @@ namespace SHADE std::vector assets; - for (auto const& dirEntry : std::filesystem::directory_iterator(folder->path)) + for (auto& dirEntry : std::filesystem::directory_iterator(folder->path)) { - auto const& path = dirEntry.path(); + auto path = dirEntry.path(); + path.make_preferred(); if (!dirEntry.is_directory()) { if (path.extension().string() == META_EXTENSION) @@ -55,7 +69,8 @@ namespace SHADE path.stem().string(), path.string(), path.extension().string(), - nullptr + nullptr, + IsCompilable(path.extension().string()) ); } continue; @@ -72,8 +87,12 @@ namespace SHADE { if (file.name == asset.name) { - file.assetMeta = &assetCollection[asset.id]; - break; + AssetPath path{ file.path }; + if (SHAssetMetaHandler::GetTypeFromExtension(path.extension().string()) == asset.type) + { + file.assetMeta = &assetCollection[asset.id]; + break; + } } } } diff --git a/SHADE_Engine/src/Filesystem/SHFileSystem.h b/SHADE_Engine/src/Filesystem/SHFileSystem.h index 956d3916..3f2e1c5b 100644 --- a/SHADE_Engine/src/Filesystem/SHFileSystem.h +++ b/SHADE_Engine/src/Filesystem/SHFileSystem.h @@ -23,6 +23,6 @@ namespace SHADE private: static bool DeleteFolder(FolderPointer location) noexcept; - + static bool IsCompilable(std::string ext) noexcept; }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Filesystem/SHFolder.h b/SHADE_Engine/src/Filesystem/SHFolder.h index 54e95033..5c702b51 100644 --- a/SHADE_Engine/src/Filesystem/SHFolder.h +++ b/SHADE_Engine/src/Filesystem/SHFolder.h @@ -33,6 +33,7 @@ namespace SHADE FilePath path; FileExt ext; SHAsset const* assetMeta; + bool compilable; }; class SHFolder From 03f9c593b6637c807071c0d3b685c9d7891cbbab Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Thu, 10 Nov 2022 17:09:55 +0800 Subject: [PATCH 41/59] Function to call to refresh asset directory --- SHADE_Engine/src/Assets/SHAssetManager.cpp | 7 +++++ SHADE_Engine/src/Assets/SHAssetManager.h | 1 + SHADE_Engine/src/Filesystem/SHFileSystem.cpp | 32 ++++++++++++++++---- SHADE_Engine/src/Filesystem/SHFileSystem.h | 2 +- 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index dbe9dd27..f4727417 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -373,6 +373,13 @@ namespace SHADE return folderRoot; } + void SHAssetManager::RefreshDirectory() noexcept + { + SHFileSystem::DestroyDirectory(folderRoot); + assetCollection.clear(); + BuildAssetCollection(); + } + bool SHAssetManager::IsRecognised(char const* ext) noexcept { for (auto const& e : EXTENSIONS) diff --git a/SHADE_Engine/src/Assets/SHAssetManager.h b/SHADE_Engine/src/Assets/SHAssetManager.h index 7fd7d039..a891ec23 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.h +++ b/SHADE_Engine/src/Assets/SHAssetManager.h @@ -90,6 +90,7 @@ namespace SHADE static void CompileAsset(AssetPath const& path, bool genMeta) noexcept; static FolderPointer GetRootFolder() noexcept; + static void RefreshDirectory() noexcept; private: diff --git a/SHADE_Engine/src/Filesystem/SHFileSystem.cpp b/SHADE_Engine/src/Filesystem/SHFileSystem.cpp index fe9b67f5..c4bcc5dc 100644 --- a/SHADE_Engine/src/Filesystem/SHFileSystem.cpp +++ b/SHADE_Engine/src/Filesystem/SHFileSystem.cpp @@ -12,6 +12,7 @@ #include "SHFileSystem.h" #include #include +#include #include "Assets/SHAssetMetaHandler.h" @@ -39,15 +40,15 @@ namespace SHADE void SHFileSystem::BuildDirectory(FolderPath path, FolderPointer& root, std::unordered_map& assetCollection) noexcept { - std::queue folderQueue; + std::stack folderStack; root = new SHFolder("root"); root->path = path; - folderQueue.push(root); + folderStack.push(root); - while (!folderQueue.empty()) + while (!folderStack.empty()) { - auto const folder = folderQueue.front(); - folderQueue.pop(); + auto const folder = folderStack.top(); + folderStack.pop(); std::vector assets; @@ -77,7 +78,7 @@ namespace SHADE } auto newFolder{ folder->CreateSubFolderHere(path.stem().string()) }; - folderQueue.push(newFolder); + folderStack.push(newFolder); } for (auto const& asset : assets) @@ -98,4 +99,23 @@ namespace SHADE } } } + + void SHFileSystem::DestroyDirectory(FolderPointer root) noexcept + { + std::stack folderStack; + folderStack.push(root); + + while(!folderStack.empty()) + { + auto const folder = folderStack.top(); + folderStack.pop(); + + for (auto const& ptr : folder->subFolders) + { + folderStack.push(ptr); + } + + delete folder; + } + } } diff --git a/SHADE_Engine/src/Filesystem/SHFileSystem.h b/SHADE_Engine/src/Filesystem/SHFileSystem.h index 3f2e1c5b..87d13f42 100644 --- a/SHADE_Engine/src/Filesystem/SHFileSystem.h +++ b/SHADE_Engine/src/Filesystem/SHFileSystem.h @@ -20,7 +20,7 @@ namespace SHADE { public: static void BuildDirectory(FolderPath path, FolderPointer& root, std::unordered_map& assetCollection) noexcept; - + static void DestroyDirectory(FolderPointer root) noexcept; private: static bool DeleteFolder(FolderPointer location) noexcept; static bool IsCompilable(std::string ext) noexcept; From ed1bc7c62d31a62980adc029f96c0ecbe605d80d Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Thu, 10 Nov 2022 17:34:33 +0800 Subject: [PATCH 42/59] Changed scripting project relative path to managed and csharp dlls --- SHADE_Engine/src/Scripting/SHScriptEngine.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp index 4f3fbce6..dc779334 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp @@ -264,12 +264,12 @@ namespace SHADE \n\ \n\ \n\ - ..\\bin\\Debug\\SHADE_Managed.dll\n\ - ..\\bin\\Release\\SHADE_Managed.dll\n\ + ..\\..\\bin\\Debug\\SHADE_Managed.dll\n\ + ..\\..\\bin\\Release\\SHADE_Managed.dll\n\ \n\ \n\ - ..\\bin\\Debug\\SHADE_CSharp.dll\n\ - ..\\bin\\Release\\SHADE_CSharp.dll\n\ + ..\\..\\bin\\Debug\\SHADE_CSharp.dll\n\ + ..\\..\\bin\\Release\\SHADE_CSharp.dll\n\ \n\ \n\ "; From c95a6a2492da4e01555c23ed52441c4c33fc29e5 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Thu, 10 Nov 2022 17:37:59 +0800 Subject: [PATCH 43/59] Added open modes for ofstream when building csharp project --- SHADE_Engine/src/Scripting/SHScriptEngine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp index dc779334..276eeb24 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp @@ -275,7 +275,7 @@ namespace SHADE "; // Attempt to create the file - std::ofstream file(path); + std::ofstream file(path, std::ios::out | std::ios::trunc); if (!file.is_open()) throw std::runtime_error("Unable to create CsProj file!"); From 2fdff77420bade71a1e8bfa3bf03d9af68722ec7 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Thu, 10 Nov 2022 23:01:09 +0800 Subject: [PATCH 44/59] Asset browser is wonky now Refresh asset browser Compile asset --- .../AssetBrowser/SHAssetBrowser.cpp | 73 +++++++++++++++---- .../AssetBrowser/SHAssetBrowser.h | 4 +- 2 files changed, 61 insertions(+), 16 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp index 37b8ecd4..9159be7e 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp @@ -36,13 +36,27 @@ namespace SHADE DrawCurrentFolder(); } ImGui::End(); + if (queueReset) + { + SHAssetManager::RefreshDirectory(); + rootFolder = SHAssetManager::GetRootFolder(); + queueReset = false; + } + } + + void SHAssetBrowser::Refresh() + { + queueReset = true; } void SHAssetBrowser::DrawMenuBar() { if (ImGui::BeginMenuBar()) { - + if(ImGui::SmallButton("Refresh")) + { + Refresh(); + } ImGui::EndMenuBar(); } } @@ -102,16 +116,14 @@ namespace SHADE } for (auto const& file : files) { - if(file.assetMeta == nullptr) - continue; const float horizontalLineSize = 25.0f; - const ImRect childRect = DrawFile(file.assetMeta); + 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); vertLineEnd.y = midPoint; } drawList->AddLine(vertLineStart, vertLineEnd, treeLineColor, 1); - if(assetBeingCreated.has_value() && std::get<0>(assetBeingCreated.value()) == folder) + if (assetBeingCreated.has_value() && std::get<0>(assetBeingCreated.value()) == folder) DrawAssetBeingCreated(); ImGui::TreePop(); @@ -148,12 +160,40 @@ namespace SHADE //} } - ImRect SHAssetBrowser::DrawFile(SHAsset const* const asset) noexcept + ImRect SHAssetBrowser::DrawFile(SHFile file) noexcept { - if (asset == nullptr) - return ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax()); - const bool isSelected = std::ranges::find(selectedAssets, asset->id) != selectedAssets.end(); - ImGuiTreeNodeFlags flags = (!asset->subAssets.empty()) ? ImGuiTreeNodeFlags_OpenOnArrow : ImGuiTreeNodeFlags_Leaf; + + SHAsset const* const asset = file.assetMeta; + if (file.compilable) + { + ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_Leaf; + std::string icon{ ICON_MD_FILE_PRESENT }; + + bool const isOpen = ImGui::TreeNodeEx(file.name.data(), flags, "%s %s%s", icon.data(), file.name.data(), file.ext.data()); + const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax()); + + if (ImGui::BeginPopupContextItem()) + { + if (ImGui::Selectable("Compile")) + { + SHAssetManager::CompileAsset(file.path, true); + Refresh(); + } + ImGui::EndPopup(); + } + + ImGui::TreePop(); + + return nodeRect; + } + if (asset) + DrawAsset(asset); + } + + ImRect SHAssetBrowser::DrawAsset(SHAsset const* const asset) + { + const bool isSelected = asset ? std::ranges::find(selectedAssets, asset->id) != selectedAssets.end() : false; + ImGuiTreeNodeFlags flags = (asset && !asset->subAssets.empty()) ? ImGuiTreeNodeFlags_OpenOnArrow : ImGuiTreeNodeFlags_Leaf; if (isSelected) flags |= ImGuiTreeNodeFlags_Selected; std::string icon{}; @@ -172,9 +212,11 @@ namespace SHADE case AssetType::MAX_COUNT: break; default:; } - + bool const isOpen = ImGui::TreeNodeEx(asset, flags, "%s %s", icon.data(), asset->name.data()); const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax()); + + if (SHDragDrop::BeginSource()) { auto id = asset->id; @@ -197,7 +239,7 @@ namespace SHADE case AssetType::TEXTURE: break; case AssetType::MESH: break; case AssetType::SCENE: - if(auto editor = SHSystemManager::GetSystem()) + if (auto editor = SHSystemManager::GetSystem()) { editor->LoadScene(asset->id); } @@ -222,12 +264,12 @@ namespace SHADE ImVec2 vertLineStart = ImGui::GetCursorScreenPos(); vertLineStart.x += horizontalOffset; ImVec2 vertLineEnd = vertLineStart; - if(isOpen) + if (isOpen) { - for(auto const& subAsset : asset->subAssets) + for (auto const& subAsset : asset->subAssets) { const float horizontalLineSize = 25.0f; - const ImRect childRect = DrawFile(subAsset); + const ImRect childRect = DrawAsset(subAsset); const float midPoint = (childRect.Min.y + childRect.Max.y) * 0.5f; drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1); vertLineEnd.y = midPoint; @@ -253,6 +295,7 @@ namespace SHADE matInspector->OpenMaterial(assetId, true); } assetBeingCreated.reset(); + Refresh(); } } } diff --git a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h index 00023ebe..8258a6c7 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h +++ b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h @@ -21,7 +21,8 @@ namespace SHADE void DrawMenuBar(); ImRect RecursivelyDrawTree(FolderPointer folder); void DrawCurrentFolder(); - ImRect DrawFile(SHAsset const* const asset) noexcept; + ImRect DrawFile(SHFile file) noexcept; + ImRect DrawAsset(SHAsset const* const asset); void DrawAssetBeingCreated() noexcept; FolderPointer rootFolder, prevFolder, currentFolder; @@ -29,5 +30,6 @@ namespace SHADE std::vector selectedFolders; std::vector selectedAssets; static constexpr float tileWidth = 50.0f; + bool queueReset = false; }; } From aad83d9e32508f1900d050b4d7980842510cceca Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Thu, 10 Nov 2022 23:01:09 +0800 Subject: [PATCH 46/59] Revert "Asset browser is wonky now" This reverts commit 2fdff77420bade71a1e8bfa3bf03d9af68722ec7. --- .../AssetBrowser/SHAssetBrowser.cpp | 73 ++++--------------- .../AssetBrowser/SHAssetBrowser.h | 4 +- 2 files changed, 16 insertions(+), 61 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp index 9159be7e..37b8ecd4 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp @@ -36,27 +36,13 @@ namespace SHADE DrawCurrentFolder(); } ImGui::End(); - if (queueReset) - { - SHAssetManager::RefreshDirectory(); - rootFolder = SHAssetManager::GetRootFolder(); - queueReset = false; - } - } - - void SHAssetBrowser::Refresh() - { - queueReset = true; } void SHAssetBrowser::DrawMenuBar() { if (ImGui::BeginMenuBar()) { - if(ImGui::SmallButton("Refresh")) - { - Refresh(); - } + ImGui::EndMenuBar(); } } @@ -116,14 +102,16 @@ namespace SHADE } for (auto const& file : files) { + if(file.assetMeta == nullptr) + continue; const float horizontalLineSize = 25.0f; - const ImRect childRect = DrawFile(file); + const ImRect childRect = DrawFile(file.assetMeta); const float midPoint = (childRect.Min.y + childRect.Max.y) * 0.5f; drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1); vertLineEnd.y = midPoint; } drawList->AddLine(vertLineStart, vertLineEnd, treeLineColor, 1); - if (assetBeingCreated.has_value() && std::get<0>(assetBeingCreated.value()) == folder) + if(assetBeingCreated.has_value() && std::get<0>(assetBeingCreated.value()) == folder) DrawAssetBeingCreated(); ImGui::TreePop(); @@ -160,40 +148,12 @@ namespace SHADE //} } - ImRect SHAssetBrowser::DrawFile(SHFile file) noexcept + ImRect SHAssetBrowser::DrawFile(SHAsset const* const asset) noexcept { - - SHAsset const* const asset = file.assetMeta; - if (file.compilable) - { - ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_Leaf; - std::string icon{ ICON_MD_FILE_PRESENT }; - - bool const isOpen = ImGui::TreeNodeEx(file.name.data(), flags, "%s %s%s", icon.data(), file.name.data(), file.ext.data()); - const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax()); - - if (ImGui::BeginPopupContextItem()) - { - if (ImGui::Selectable("Compile")) - { - SHAssetManager::CompileAsset(file.path, true); - Refresh(); - } - ImGui::EndPopup(); - } - - ImGui::TreePop(); - - return nodeRect; - } - if (asset) - DrawAsset(asset); - } - - ImRect SHAssetBrowser::DrawAsset(SHAsset const* const asset) - { - const bool isSelected = asset ? std::ranges::find(selectedAssets, asset->id) != selectedAssets.end() : false; - ImGuiTreeNodeFlags flags = (asset && !asset->subAssets.empty()) ? ImGuiTreeNodeFlags_OpenOnArrow : ImGuiTreeNodeFlags_Leaf; + if (asset == nullptr) + return ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax()); + const bool isSelected = std::ranges::find(selectedAssets, asset->id) != selectedAssets.end(); + ImGuiTreeNodeFlags flags = (!asset->subAssets.empty()) ? ImGuiTreeNodeFlags_OpenOnArrow : ImGuiTreeNodeFlags_Leaf; if (isSelected) flags |= ImGuiTreeNodeFlags_Selected; std::string icon{}; @@ -212,11 +172,9 @@ namespace SHADE case AssetType::MAX_COUNT: break; default:; } - + bool const isOpen = ImGui::TreeNodeEx(asset, flags, "%s %s", icon.data(), asset->name.data()); const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax()); - - if (SHDragDrop::BeginSource()) { auto id = asset->id; @@ -239,7 +197,7 @@ namespace SHADE case AssetType::TEXTURE: break; case AssetType::MESH: break; case AssetType::SCENE: - if (auto editor = SHSystemManager::GetSystem()) + if(auto editor = SHSystemManager::GetSystem()) { editor->LoadScene(asset->id); } @@ -264,12 +222,12 @@ namespace SHADE ImVec2 vertLineStart = ImGui::GetCursorScreenPos(); vertLineStart.x += horizontalOffset; ImVec2 vertLineEnd = vertLineStart; - if (isOpen) + if(isOpen) { - for (auto const& subAsset : asset->subAssets) + for(auto const& subAsset : asset->subAssets) { const float horizontalLineSize = 25.0f; - const ImRect childRect = DrawAsset(subAsset); + const ImRect childRect = DrawFile(subAsset); const float midPoint = (childRect.Min.y + childRect.Max.y) * 0.5f; drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1); vertLineEnd.y = midPoint; @@ -295,7 +253,6 @@ namespace SHADE matInspector->OpenMaterial(assetId, true); } assetBeingCreated.reset(); - Refresh(); } } } diff --git a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h index 8258a6c7..00023ebe 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h +++ b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h @@ -21,8 +21,7 @@ namespace SHADE void DrawMenuBar(); ImRect RecursivelyDrawTree(FolderPointer folder); void DrawCurrentFolder(); - ImRect DrawFile(SHFile file) noexcept; - ImRect DrawAsset(SHAsset const* const asset); + ImRect DrawFile(SHAsset const* const asset) noexcept; void DrawAssetBeingCreated() noexcept; FolderPointer rootFolder, prevFolder, currentFolder; @@ -30,6 +29,5 @@ namespace SHADE std::vector selectedFolders; std::vector selectedAssets; static constexpr float tileWidth = 50.0f; - bool queueReset = false; }; } From d93ea8e49bb36ae96c33e71497b1d3697487fe89 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 10 Nov 2022 23:34:53 +0800 Subject: [PATCH 47/59] Child caches are now updated when scene hierarchy changes --- SHADE_Engine/src/Scripting/SHScriptEngine.cpp | 38 ++++++++++++++++++- SHADE_Engine/src/Scripting/SHScriptEngine.h | 3 ++ SHADE_Managed/src/Engine/GameObject.cxx | 3 +- 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp index 276eeb24..f279bec1 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp @@ -318,6 +318,20 @@ namespace SHADE return eventData->handle; } + SHEventHandle SHScriptEngine::onSceneNodeChildrenAdded(SHEventPtr eventPtr) + { + auto eventData = reinterpret_cast*>(eventPtr.get()); + csSceneNodeChildrenChanged(eventData->data->parent->GetEntityID()); + return eventData->handle; + } + + SHEventHandle SHScriptEngine::onSceneNodeChildrenRemoved(SHEventPtr eventPtr) + { + auto eventData = reinterpret_cast*>(eventPtr.get()); + csSceneNodeChildrenChanged(eventData->data->parent->GetEntityID()); + return eventData->handle; + } + /*-----------------------------------------------------------------------------------*/ /* Helper Functions */ /*-----------------------------------------------------------------------------------*/ @@ -442,6 +456,12 @@ namespace SHADE DEFAULT_CSHARP_NAMESPACE + ".Collider", "OnCollisionShapeRemoved" ); + csSceneNodeChildrenChanged = dotNet.GetFunctionPtr + ( + DEFAULT_CSHARP_LIB_NAME, + DEFAULT_CSHARP_NAMESPACE + ".ChildListCache", + "OnChildrenChanged" + ); csEditorRenderScripts = dotNet.GetFunctionPtr ( DEFAULT_CSHARP_LIB_NAME, @@ -464,6 +484,7 @@ namespace SHADE void SHScriptEngine::registerEvents() { + /* Entity */ // Register for entity destroyed event std::shared_ptr> destroyedEventReceiver { @@ -471,26 +492,39 @@ namespace SHADE }; SHEventManager::SubscribeTo(SH_ENTITY_DESTROYED_EVENT, std::dynamic_pointer_cast(destroyedEventReceiver)); + /* Colliders */ // Register for collider added event std::shared_ptr> addedColliderEventReceiver { std::make_shared>(this, &SHScriptEngine::onColliderAdded) }; SHEventManager::SubscribeTo(SH_PHYSICS_COLLIDER_ADDED_EVENT, std::dynamic_pointer_cast(addedColliderEventReceiver)); - // Register for collider removed event std::shared_ptr> removedColliderEventReceiver { std::make_shared>(this, &SHScriptEngine::onColliderRemoved) }; SHEventManager::SubscribeTo(SH_PHYSICS_COLLIDER_REMOVED_EVENT, std::dynamic_pointer_cast(removedColliderEventReceiver)); - // Register for collider component removed event std::shared_ptr> removedColliderComponentEventReceiver { std::make_shared>(this, &SHScriptEngine::onColliderComponentRemoved) }; SHEventManager::SubscribeTo(SH_COMPONENT_REMOVED_EVENT, std::dynamic_pointer_cast(removedColliderComponentEventReceiver)); + + /* SceneGraph */ + // Register for SceneNode child added event + std::shared_ptr> addChildEventReceiver + { + std::make_shared>(this, &SHScriptEngine::onSceneNodeChildrenAdded) + }; + SHEventManager::SubscribeTo(SH_SCENEGRAPH_ADD_CHILD_EVENT, std::dynamic_pointer_cast(addChildEventReceiver)); + // Register for SceneNode child removed event + std::shared_ptr> removeChildEventReceiver + { + std::make_shared>(this, &SHScriptEngine::onSceneNodeChildrenRemoved) + }; + SHEventManager::SubscribeTo(SH_SCENEGRAPH_REMOVE_CHILD_EVENT, std::dynamic_pointer_cast(removeChildEventReceiver)); } void SHScriptEngine::dumpBuildLog(const std::string_view& buildLogPath) diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.h b/SHADE_Engine/src/Scripting/SHScriptEngine.h index 7d83606e..ef778627 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.h +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.h @@ -267,6 +267,7 @@ namespace SHADE // - Events CsEventRelayFuncPtr csColliderOnListChanged = nullptr; CsEventRelayFuncPtr csColliderOnRemoved = nullptr; + CsEventRelayFuncPtr csSceneNodeChildrenChanged = nullptr; // - Editor CsScriptEditorFuncPtr csEditorRenderScripts = nullptr; CsFuncPtr csEditorUndo = nullptr; @@ -279,6 +280,8 @@ namespace SHADE SHEventHandle onColliderAdded(SHEventPtr eventPtr); SHEventHandle onColliderRemoved(SHEventPtr eventPtr); SHEventHandle onColliderComponentRemoved(SHEventPtr eventPtr); + SHEventHandle onSceneNodeChildrenAdded(SHEventPtr eventPtr); + SHEventHandle onSceneNodeChildrenRemoved(SHEventPtr eventPtr); /*-----------------------------------------------------------------------------*/ /* Helper Functions */ diff --git a/SHADE_Managed/src/Engine/GameObject.cxx b/SHADE_Managed/src/Engine/GameObject.cxx index 79960ff6..017366fe 100644 --- a/SHADE_Managed/src/Engine/GameObject.cxx +++ b/SHADE_Managed/src/Engine/GameObject.cxx @@ -244,8 +244,7 @@ namespace SHADE // Unparent all children to the root for (auto child : node->GetChildren()) { - child->SetParent(nullptr); - ChildListCache::UpdateChildList(child->GetEntityID()); + SHSceneManager::GetCurrentSceneGraph().SetParent(child->GetEntityID(), nullptr); } ChildListCache::UpdateChildList(entity); } From e824c174056f008cf4fe56f9bc08a29e4fb23c85 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Fri, 11 Nov 2022 10:06:26 +0800 Subject: [PATCH 48/59] Fixed asset type conversion bug when loading from meta files Removed compile all function Set parent id to 0 for non sub assets --- SHADE_Engine/src/Assets/SHAssetMacros.h | 3 +- SHADE_Engine/src/Assets/SHAssetManager.cpp | 45 ------------------- SHADE_Engine/src/Assets/SHAssetManager.h | 2 - .../src/Assets/SHAssetMetaHandler.cpp | 1 + 4 files changed, 3 insertions(+), 48 deletions(-) diff --git a/SHADE_Engine/src/Assets/SHAssetMacros.h b/SHADE_Engine/src/Assets/SHAssetMacros.h index e0551262..7ffdb5f1 100644 --- a/SHADE_Engine/src/Assets/SHAssetMacros.h +++ b/SHADE_Engine/src/Assets/SHAssetMacros.h @@ -51,8 +51,8 @@ enum class AssetType : AssetTypeMeta SCENE, PREFAB, MATERIAL, - SCRIPT, MESH, + SCRIPT, MAX_COUNT }; constexpr size_t TYPE_COUNT{ static_cast(AssetType::MAX_COUNT) }; @@ -97,6 +97,7 @@ constexpr std::string_view EXTENSIONS[] = { SCENE_EXTENSION, PREFAB_EXTENSION, MATERIAL_EXTENSION, + "dummy", SCRIPT_EXTENSION, AUDIO_WAV_EXTENSION, }; diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index f4727417..5a1bd5db 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -405,51 +405,6 @@ namespace SHADE return result; } - void SHAssetManager::CompileAll() noexcept - { - std::vector paths; - - for (auto const& dir : std::filesystem::recursive_directory_iterator{ ASSET_ROOT }) - { - if (dir.is_regular_file()) - { - for (auto const& ext : EXTERNALS) - { - if (dir.path().extension().string() == ext.data()) - { - paths.push_back(dir.path()); - } - } - } - } - - for (auto const& path : paths) - { - AssetPath newPath; - auto const ext{ path.extension().string() }; - if (ext == GLSL_EXTENSION.data()) - { - newPath = SHShaderSourceCompiler::LoadAndCompileShader(path).value(); - } - else if (ext == DDS_EXTENSION.data()) - { - newPath = SHTextureCompiler::CompileTextureAsset(path).value(); - } - else if (ext == GLTF_EXTENSION.data() || ext == FBX_EXTENSION.data()) - { - std::string command = MODEL_COMPILER_EXE.data(); - command += " " + path.string(); - std::system(command.c_str()); - - std::string modelPath = path.string().substr(0, path.string().find_last_of('.')); - modelPath += MODEL_EXTENSION; - newPath = modelPath; - } - - GenerateNewMeta(newPath); - } - } - bool SHAssetManager::DeleteLocalFile(AssetPath path) noexcept { //TODO Move this to dedicated library diff --git a/SHADE_Engine/src/Assets/SHAssetManager.h b/SHADE_Engine/src/Assets/SHAssetManager.h index a891ec23..5af648e4 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.h +++ b/SHADE_Engine/src/Assets/SHAssetManager.h @@ -107,8 +107,6 @@ namespace SHADE static SHAsset CreateAssetFromPath(AssetPath path) noexcept; - static void CompileAll() noexcept; - static bool DeleteLocalFile(AssetPath path) noexcept; //TODO use this function to create asset data internall at all calls to generate id diff --git a/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp b/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp index 9ae8cde2..b75ee1ad 100644 --- a/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp +++ b/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp @@ -98,6 +98,7 @@ namespace SHADE meta.type = static_cast(type); meta.isSubAsset = false; + meta.parent = 0; // Burn Line if (std::getline(metaFile, line)) From 6df3f3d4174c7ae4f5e5e4b3c2f50eeb7c46ef5a Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Fri, 11 Nov 2022 10:47:03 +0800 Subject: [PATCH 49/59] Fixed get type from extension bug in asset handler --- SHADE_Engine/src/Assets/SHAssetMacros.h | 2 ++ SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/SHADE_Engine/src/Assets/SHAssetMacros.h b/SHADE_Engine/src/Assets/SHAssetMacros.h index 7ffdb5f1..7e5befab 100644 --- a/SHADE_Engine/src/Assets/SHAssetMacros.h +++ b/SHADE_Engine/src/Assets/SHAssetMacros.h @@ -102,6 +102,8 @@ constexpr std::string_view EXTENSIONS[] = { AUDIO_WAV_EXTENSION, }; +constexpr size_t EXTENSIONS_COUNT{ 11 }; + // EXTERNAL EXTENSIONS constexpr std::string_view GLSL_EXTENSION{ ".glsl" }; constexpr std::string_view DDS_EXTENSION{ ".dds" }; diff --git a/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp b/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp index b75ee1ad..f3b24ed1 100644 --- a/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp +++ b/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp @@ -38,7 +38,7 @@ namespace SHADE ****************************************************************************/ AssetType SHAssetMetaHandler::GetTypeFromExtension(AssetExtension ext) noexcept { - for (int i{0}; i < EXTENSIONS->size(); ++i) + for (auto i{0}; i < EXTENSIONS_COUNT; ++i) { if (strcmp(ext.c_str(), EXTENSIONS[i].data()) == 0) { From 9fe5dc385bf6f55b1e91f461cead7743877882b0 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Fri, 11 Nov 2022 10:52:57 +0800 Subject: [PATCH 50/59] Implemented check for raw asset if compiled --- SHADE_Engine/src/Filesystem/SHFileSystem.cpp | 63 +++++++++++++++++++- SHADE_Engine/src/Filesystem/SHFileSystem.h | 1 + SHADE_Engine/src/Filesystem/SHFolder.h | 3 +- 3 files changed, 64 insertions(+), 3 deletions(-) diff --git a/SHADE_Engine/src/Filesystem/SHFileSystem.cpp b/SHADE_Engine/src/Filesystem/SHFileSystem.cpp index c4bcc5dc..9144b0d8 100644 --- a/SHADE_Engine/src/Filesystem/SHFileSystem.cpp +++ b/SHADE_Engine/src/Filesystem/SHFileSystem.cpp @@ -38,6 +38,41 @@ namespace SHADE return false; } + bool SHFileSystem::MatchExtention(FileExt raw, FileExt compiled) noexcept + { + if (raw == GLSL_EXTENSION) + { + if (compiled == SHADER_EXTENSION || + compiled == SHADER_BUILT_IN_EXTENSION) + { + return true; + } + } + else if (raw == DDS_EXTENSION) + { + if (compiled == TEXTURE_EXTENSION) + { + return true; + } + } + else if (raw == FBX_EXTENSION) + { + if (compiled == MODEL_EXTENSION) + { + return true; + } + } + else if (raw == GLTF_EXTENSION) + { + if (compiled == MODEL_EXTENSION) + { + return true; + } + } + + return false; + } + void SHFileSystem::BuildDirectory(FolderPath path, FolderPointer& root, std::unordered_map& assetCollection) noexcept { std::stack folderStack; @@ -52,6 +87,7 @@ namespace SHADE std::vector assets; + // Get all subfolders/files in this current folder for (auto& dirEntry : std::filesystem::directory_iterator(folder->path)) { auto path = dirEntry.path(); @@ -60,8 +96,6 @@ namespace SHADE { if (path.extension().string() == META_EXTENSION) { - //auto asset = SHAssetMetaHandler::RetrieveMetaData(path); - //assetCollection.insert({ asset.id, asset }); assets.push_back(SHAssetMetaHandler::RetrieveMetaData(path)); } else @@ -77,6 +111,7 @@ namespace SHADE continue; } + // If item is folder auto newFolder{ folder->CreateSubFolderHere(path.stem().string()) }; folderStack.push(newFolder); } @@ -97,6 +132,30 @@ namespace SHADE } } } + + for (auto i {0}; i < folder->files.size(); ++i) + { + auto& file = folder->files[i]; + if (file.compilable) + { + for (auto j{ 0 }; j < folder->files.size(); ++j) + { + auto& check = folder->files[j]; + if (i == j || check.compilable) + { + continue; + } + + if (file.name == check.name) + { + if (MatchExtention(file.ext, check.ext)) + { + file.compiled = true; + } + } + } + } + } } } diff --git a/SHADE_Engine/src/Filesystem/SHFileSystem.h b/SHADE_Engine/src/Filesystem/SHFileSystem.h index 87d13f42..d30f2164 100644 --- a/SHADE_Engine/src/Filesystem/SHFileSystem.h +++ b/SHADE_Engine/src/Filesystem/SHFileSystem.h @@ -24,5 +24,6 @@ namespace SHADE private: static bool DeleteFolder(FolderPointer location) noexcept; static bool IsCompilable(std::string ext) noexcept; + static bool MatchExtention(FileExt raw, FileExt compiled) noexcept; }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Filesystem/SHFolder.h b/SHADE_Engine/src/Filesystem/SHFolder.h index 5c702b51..234e6f19 100644 --- a/SHADE_Engine/src/Filesystem/SHFolder.h +++ b/SHADE_Engine/src/Filesystem/SHFolder.h @@ -33,7 +33,8 @@ namespace SHADE FilePath path; FileExt ext; SHAsset const* assetMeta; - bool compilable; + bool compilable; + bool compiled; }; class SHFolder From 94b64e92dd51ac837aadaa266d696f93dc49a9a8 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Fri, 11 Nov 2022 10:55:19 +0800 Subject: [PATCH 51/59] Initialise files to not compiled --- SHADE_Engine/src/Filesystem/SHFileSystem.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SHADE_Engine/src/Filesystem/SHFileSystem.cpp b/SHADE_Engine/src/Filesystem/SHFileSystem.cpp index 9144b0d8..9aaf72a4 100644 --- a/SHADE_Engine/src/Filesystem/SHFileSystem.cpp +++ b/SHADE_Engine/src/Filesystem/SHFileSystem.cpp @@ -105,7 +105,8 @@ namespace SHADE path.string(), path.extension().string(), nullptr, - IsCompilable(path.extension().string()) + IsCompilable(path.extension().string()), + false ); } continue; From 3b22f95e29a04129d025be57ec6b120862219e30 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Fri, 11 Nov 2022 13:21:22 +0800 Subject: [PATCH 52/59] Added font identifiers --- SHADE_Engine/src/Assets/SHAssetMacros.h | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/SHADE_Engine/src/Assets/SHAssetMacros.h b/SHADE_Engine/src/Assets/SHAssetMacros.h index 7e5befab..44dfd5c5 100644 --- a/SHADE_Engine/src/Assets/SHAssetMacros.h +++ b/SHADE_Engine/src/Assets/SHAssetMacros.h @@ -53,6 +53,7 @@ enum class AssetType : AssetTypeMeta MATERIAL, MESH, SCRIPT, + FONT, MAX_COUNT }; constexpr size_t TYPE_COUNT{ static_cast(AssetType::MAX_COUNT) }; @@ -86,7 +87,8 @@ constexpr std::string_view SCENE_EXTENSION {".shade"}; constexpr std::string_view PREFAB_EXTENSION {".shprefab"}; constexpr std::string_view MATERIAL_EXTENSION {".shmat"}; constexpr std::string_view TEXTURE_EXTENSION {".shtex"}; -constexpr std::string_view MODEL_EXTENSION {".shmodel"}; +constexpr std::string_view MODEL_EXTENSION{ ".shmodel" }; +constexpr std::string_view FONT_EXTENSION{ ".shfont" }; constexpr std::string_view EXTENSIONS[] = { AUDIO_EXTENSION, @@ -99,6 +101,7 @@ constexpr std::string_view EXTENSIONS[] = { MATERIAL_EXTENSION, "dummy", SCRIPT_EXTENSION, + FONT_EXTENSION, AUDIO_WAV_EXTENSION, }; @@ -109,12 +112,14 @@ constexpr std::string_view GLSL_EXTENSION{ ".glsl" }; constexpr std::string_view DDS_EXTENSION{ ".dds" }; constexpr std::string_view FBX_EXTENSION{ ".fbx" }; constexpr std::string_view GLTF_EXTENSION{ ".gltf" }; +constexpr std::string_view TTF_EXTENSION{ ".ttf" }; constexpr std::string_view EXTERNALS[] = { GLSL_EXTENSION, DDS_EXTENSION, FBX_EXTENSION, - GLTF_EXTENSION + GLTF_EXTENSION, + TTF_EXTENSION }; // SHADER IDENTIFIERS @@ -129,11 +134,4 @@ constexpr std::pair SHADER_IDENTIFIERS[ }; constexpr size_t SHADER_TYPE_MAX_COUNT{ 3 }; - -// Error flags -constexpr std::string_view FILE_NOT_FOUND_ERR {"FILE NOT FOUND"}; -constexpr std::string_view META_NOT_FOUND_ERR {"META NOT FOUND"}; -constexpr std::string_view ASSET_NOT_FOUND_ERR {"ASSET NOT FOUND"}; -constexpr std::string_view EXT_DOES_NOT_EXIST {"TYPE DOES NOT HAVE EXTENSION DEFINED"}; - #endif // !SH_ASSET_MACROS_H From c9db3b283d4b47a18a0857e64681efe025b37687 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Fri, 11 Nov 2022 14:00:51 +0800 Subject: [PATCH 53/59] asset browser --- .../AssetBrowser/SHAssetBrowser.cpp | 42 +++++++++++++++---- .../AssetBrowser/SHAssetBrowser.h | 3 +- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp index 37b8ecd4..0f17d2db 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp @@ -47,10 +47,12 @@ namespace SHADE } } + //if !compiled, set genMeta to true + ImRect SHAssetBrowser::RecursivelyDrawTree(FolderPointer folder) { auto const& subFolders = folder->subFolders; - auto const& files = folder->files; + auto files = folder->files; const bool isSelected = std::ranges::find(selectedFolders, folder) != selectedFolders.end(); ImGuiTreeNodeFlags flags = (subFolders.empty() && files.empty()) ? ImGuiTreeNodeFlags_Leaf : ImGuiTreeNodeFlags_OpenOnArrow; if (isSelected) @@ -100,12 +102,10 @@ namespace SHADE drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1); vertLineEnd.y = midPoint; } - for (auto const& file : files) + for (auto& file : files) { - if(file.assetMeta == nullptr) - continue; const float horizontalLineSize = 25.0f; - const ImRect childRect = DrawFile(file.assetMeta); + 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); vertLineEnd.y = midPoint; @@ -148,7 +148,32 @@ namespace SHADE //} } - ImRect SHAssetBrowser::DrawFile(SHAsset const* const asset) noexcept + ImRect SHAssetBrowser::DrawFile(SHFile& file) noexcept + { + if(file.compilable) + { + ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_Leaf; + static constexpr std::string_view icon = ICON_MD_FILE_PRESENT; + ImGui::PushID(file.name.data()); + bool const isOpen = ImGui::TreeNodeEx(file.name.data(), flags, "%s %s%s", icon.data(), file.name.data(), file.ext.data()); + const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax()); + if(ImGui::BeginPopupContextItem()) + { + if(ImGui::Selectable("Compile")) + { + SHAssetManager::CompileAsset(file.path, !file.compiled); + } + ImGui::EndPopup(); + } + ImGui::TreePop(); + ImGui::PopID(); + return nodeRect; + } + if(file.assetMeta) + DrawAsset(file.assetMeta, file.ext); + } + + ImRect SHAssetBrowser::DrawAsset(SHAsset const* const asset, FileExt const& ext /*= ""*/) noexcept { if (asset == nullptr) return ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax()); @@ -173,7 +198,7 @@ namespace SHADE default:; } - bool const isOpen = ImGui::TreeNodeEx(asset, flags, "%s %s", icon.data(), asset->name.data()); + bool const isOpen = ImGui::TreeNodeEx(asset, flags, "%s %s%s", icon.data(), asset->name.data(), ext.data()); const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax()); if (SHDragDrop::BeginSource()) { @@ -212,7 +237,6 @@ namespace SHADE case AssetType::MAX_COUNT: break; default:; } - } //TODO: Combine Draw asset and Draw Folder recursive drawing @@ -227,7 +251,7 @@ namespace SHADE for(auto const& subAsset : asset->subAssets) { const float horizontalLineSize = 25.0f; - const ImRect childRect = DrawFile(subAsset); + const ImRect childRect = DrawAsset(subAsset); const float midPoint = (childRect.Min.y + childRect.Max.y) * 0.5f; drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1); vertLineEnd.y = midPoint; diff --git a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h index 00023ebe..6b6316c8 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h +++ b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h @@ -21,7 +21,8 @@ namespace SHADE void DrawMenuBar(); ImRect RecursivelyDrawTree(FolderPointer folder); void DrawCurrentFolder(); - ImRect DrawFile(SHAsset const* const asset) noexcept; + ImRect DrawFile(SHFile& file) noexcept; + ImRect DrawAsset(SHAsset const* const asset, FileExt const& ext = "") noexcept; void DrawAssetBeingCreated() noexcept; FolderPointer rootFolder, prevFolder, currentFolder; From 153f040c407909acb18010dc81de37b7990a4836 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Fri, 11 Nov 2022 20:41:05 +0800 Subject: [PATCH 54/59] Refresh --- .../AssetBrowser/SHAssetBrowser.cpp | 26 ++++++++++++++++--- .../AssetBrowser/SHAssetBrowser.h | 5 +++- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp index 0f17d2db..dca8a34b 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp @@ -36,13 +36,30 @@ namespace SHADE DrawCurrentFolder(); } ImGui::End(); + if(refreshQueued) + Refresh(); + } + + void SHAssetBrowser::QueueRefresh() noexcept + { + refreshQueued = true; + } + + void SHAssetBrowser::Refresh() noexcept + { + SHAssetManager::RefreshDirectory(); + rootFolder = SHAssetManager::GetRootFolder(); + refreshQueued = false; } void SHAssetBrowser::DrawMenuBar() { if (ImGui::BeginMenuBar()) { - + if(ImGui::SmallButton(ICON_MD_SYNC)) + { + QueueRefresh(); + } ImGui::EndMenuBar(); } } @@ -71,7 +88,7 @@ namespace SHADE //TODO: Change to rttr type enum align if (ImGui::Selectable("Material")) { - assetBeingCreated = { folder, AssetType::MATERIAL, "New Material" }; + assetBeingCreated = { folder, AssetType::MATERIAL, "NewMaterial" }; ImGui::TreeNodeSetOpen(folderID, true); isOpen = true; } @@ -162,6 +179,7 @@ namespace SHADE if(ImGui::Selectable("Compile")) { SHAssetManager::CompileAsset(file.path, !file.compiled); + QueueRefresh(); } ImGui::EndPopup(); } @@ -269,7 +287,7 @@ namespace SHADE auto& path = std::get<0>(assetBeingCreated.value()); auto& type = std::get<1>(assetBeingCreated.value()); auto& assetName = std::get<2>(assetBeingCreated.value()); - if (ImGui::InputText("##newAssetName", &assetName, ImGuiInputTextFlags_EnterReturnsTrue)) + if (ImGui::InputText("##newAssetName", &assetName, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CharsNoBlank)) { AssetID assetId = SHAssetManager::CreateNewAsset(type, assetName); if (auto matInspector = SHEditorWindowManager::GetEditorWindow()) @@ -277,6 +295,8 @@ namespace SHADE matInspector->OpenMaterial(assetId, true); } assetBeingCreated.reset(); + QueueRefresh(); } + ImGui::ActivateItem(ImGui::GetItemID()); } } diff --git a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h index 6b6316c8..d6c2c191 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h +++ b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h @@ -16,7 +16,7 @@ namespace SHADE void Init(); void Update(); - void Refresh(); + void QueueRefresh() noexcept; private: void DrawMenuBar(); ImRect RecursivelyDrawTree(FolderPointer folder); @@ -25,10 +25,13 @@ namespace SHADE ImRect DrawAsset(SHAsset const* const asset, FileExt const& ext = "") noexcept; void DrawAssetBeingCreated() noexcept; + void Refresh() noexcept; + FolderPointer rootFolder, prevFolder, currentFolder; std::optional assetBeingCreated; std::vector selectedFolders; std::vector selectedAssets; static constexpr float tileWidth = 50.0f; + bool refreshQueued = false; }; } From 7c7589ce8e01a4120fcd66b15ffc18ec6a977311 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Fri, 11 Nov 2022 21:12:08 +0800 Subject: [PATCH 55/59] idk why creation of new material is not working here send help. Change to popup for asset creation --- .../AssetBrowser/SHAssetBrowser.cpp | 84 ++++++++++++------- .../AssetBrowser/SHAssetBrowser.h | 5 +- 2 files changed, 57 insertions(+), 32 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp index dca8a34b..37521581 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp @@ -17,7 +17,7 @@ namespace SHADE { SHAssetBrowser::SHAssetBrowser() - :SHEditorWindow("\xee\x8b\x87 Asset Browser", ImGuiWindowFlags_MenuBar), rootFolder(SHAssetManager::GetRootFolder()), prevFolder(rootFolder), currentFolder(rootFolder), assetBeingCreated(std::nullopt) + :SHEditorWindow("\xee\x8b\x87 Asset Browser", ImGuiWindowFlags_MenuBar), rootFolder(SHAssetManager::GetRootFolder()), prevFolder(rootFolder), currentFolder(rootFolder) { } @@ -34,6 +34,8 @@ namespace SHADE RecursivelyDrawTree(rootFolder); DrawMenuBar(); DrawCurrentFolder(); + DrawAssetBeingCreated(); + } ImGui::End(); if(refreshQueued) @@ -60,6 +62,10 @@ namespace SHADE { QueueRefresh(); } + if(ImGui::SmallButton(ICON_FA_CIRCLE_PLUS)) + { + isAssetBeingCreated = true; + } ImGui::EndMenuBar(); } } @@ -81,21 +87,10 @@ namespace SHADE ImGuiID folderID = ImGui::GetItemID(); const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax()); - if (ImGui::BeginPopupContextItem()) - { - if (ImGui::BeginMenu("Create Asset")) - { - //TODO: Change to rttr type enum align - if (ImGui::Selectable("Material")) - { - assetBeingCreated = { folder, AssetType::MATERIAL, "NewMaterial" }; - ImGui::TreeNodeSetOpen(folderID, true); - isOpen = true; - } - ImGui::EndMenu(); - } - ImGui::EndPopup(); - } + //if (ImGui::BeginPopupContextItem()) + //{ + // ImGui::EndPopup(); + //} if (ImGui::IsItemClicked()) { @@ -128,8 +123,6 @@ namespace SHADE vertLineEnd.y = midPoint; } drawList->AddLine(vertLineStart, vertLineEnd, treeLineColor, 1); - if(assetBeingCreated.has_value() && std::get<0>(assetBeingCreated.value()) == folder) - DrawAssetBeingCreated(); ImGui::TreePop(); } @@ -282,21 +275,52 @@ namespace SHADE void SHAssetBrowser::DrawAssetBeingCreated() noexcept { - if (!assetBeingCreated.has_value()) - return; - auto& path = std::get<0>(assetBeingCreated.value()); - auto& type = std::get<1>(assetBeingCreated.value()); - auto& assetName = std::get<2>(assetBeingCreated.value()); - if (ImGui::InputText("##newAssetName", &assetName, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CharsNoBlank)) + if(isAssetBeingCreated) + ImGui::OpenPopup(newAssetPopup.data()); + + if(ImGui::BeginPopupModal(newAssetPopup.data(), &isAssetBeingCreated)) { - AssetID assetId = SHAssetManager::CreateNewAsset(type, assetName); - if (auto matInspector = SHEditorWindowManager::GetEditorWindow()) + ImGui::RadioButton("Material", true); + ImGui::SameLine(); + if (ImGui::InputText("##newAssetName", &nameOfAssetBeingCreated, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CharsNoBlank | ImGuiInputTextFlags_AutoSelectAll)) { - matInspector->OpenMaterial(assetId, true); + AssetID assetId = SHAssetManager::CreateNewAsset(AssetType::MATERIAL, nameOfAssetBeingCreated); + if (auto matInspector = SHEditorWindowManager::GetEditorWindow()) + { + matInspector->OpenMaterial(assetId, true); + } + nameOfAssetBeingCreated.clear(); + QueueRefresh(); + isAssetBeingCreated = false; + ImGui::CloseCurrentPopup(); } - assetBeingCreated.reset(); - QueueRefresh(); + ImGui::EndPopup(); } - ImGui::ActivateItem(ImGui::GetItemID()); + //if (ImGui::BeginMenu("Create Asset")) + //{ + // //TODO: Change to rttr type enum align + // if (ImGui::Selectable("Material")) + // { + // assetBeingCreated = { folder, AssetType::MATERIAL, "NewMaterial" }; + // ImGui::TreeNodeSetOpen(folderID, true); + // isOpen = true; + // } + // ImGui::EndMenu(); + //} + //if (!assetBeingCreated.has_value()) + // return; + //auto& path = std::get<0>(assetBeingCreated.value()); + //auto& type = std::get<1>(assetBeingCreated.value()); + //auto& assetName = std::get<2>(assetBeingCreated.value()); + //if (ImGui::InputText("##newAssetName", &assetName, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CharsNoBlank | ImGuiInputTextFlags_AutoSelectAll)) + //{ + // AssetID assetId = SHAssetManager::CreateNewAsset(type, assetName); + // if (auto matInspector = SHEditorWindowManager::GetEditorWindow()) + // { + // matInspector->OpenMaterial(assetId, true); + // } + // assetBeingCreated.reset(); + // QueueRefresh(); + //} } } diff --git a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h index d6c2c191..6d3c5eb4 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h +++ b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h @@ -10,7 +10,6 @@ namespace SHADE class SHAssetBrowser final : public SHEditorWindow { public: - using AssetEntry = std::tuple; SHAssetBrowser(); void Init(); @@ -28,10 +27,12 @@ namespace SHADE void Refresh() noexcept; FolderPointer rootFolder, prevFolder, currentFolder; - std::optional assetBeingCreated; std::vector selectedFolders; std::vector selectedAssets; static constexpr float tileWidth = 50.0f; bool refreshQueued = false; + bool isAssetBeingCreated = false; + static constexpr std::string_view newAssetPopup = "Create New Asset"; + std::string nameOfAssetBeingCreated; }; } From 340299218995a652dfe311af4de3cfc7a33de760 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Sat, 12 Nov 2022 18:09:55 +0800 Subject: [PATCH 56/59] dont draw gizmos on play --- .../ViewportWindow/SHEditorViewport.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp index d6ef8d19..7b3b5411 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp @@ -40,6 +40,7 @@ namespace SHADE shouldUpdateCamera = false; } ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); + SHEditor* editor = SHSystemManager::GetSystem(); if (Begin()) { @@ -51,7 +52,6 @@ namespace SHADE beginCursorPos = ImGui::GetCursorScreenPos(); viewportMousePos = { mousePos.x - beginCursorPos.x, mousePos.y - beginCursorPos.y }; gfxSystem->GetMousePickSystem()->SetViewportMousePos(viewportMousePos); - ImGui::Image((ImTextureID)descriptorSet, { beginContentRegionAvailable.x, beginContentRegionAvailable.y }); if (ImGui::IsWindowHovered() && ImGui::IsMouseDown(ImGuiMouseButton_Right)) @@ -64,24 +64,25 @@ namespace SHADE shouldUpdateCamera = true; } - if (ImGui::IsWindowFocused() && !ImGui::IsMouseDown(ImGuiMouseButton_Right)) + if (editor->editorState != SHEditor::State::PLAY && ImGui::IsWindowFocused() && !ImGui::IsMouseDown(ImGuiMouseButton_Right)) { - if (ImGui::IsKeyReleased(ImGuiKey_Q)) + if (ImGui::IsKeyReleased(ImGuiKey_W)) { transformGizmo.operation = SHTransformGizmo::Operation::TRANSLATE; } - if (ImGui::IsKeyReleased(ImGuiKey_W)) + if (ImGui::IsKeyReleased(ImGuiKey_E)) { transformGizmo.operation = SHTransformGizmo::Operation::ROTATE; } - if (ImGui::IsKeyReleased(ImGuiKey_E)) + if (ImGui::IsKeyReleased(ImGuiKey_R)) { transformGizmo.operation = SHTransformGizmo::Operation::SCALE; } } } ImGuizmo::SetRect(beginCursorPos.x, beginCursorPos.y, beginContentRegionAvailable.x, beginContentRegionAvailable.y); - transformGizmo.Draw(); + if(editor->editorState != SHEditor::State::PLAY) + transformGizmo.Draw(); ImGui::End(); ImGui::PopStyleVar(); } From 78ca464c6537823445e2683f05455051be0bdbc1 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Sat, 12 Nov 2022 18:22:45 +0800 Subject: [PATCH 57/59] Editor now uses separate stacks; 1 set of stacks when in play and another set of stacks otherwise. CommandStack now uses SHDeque --- .../src/Editor/Command/SHCommandManager.cpp | 77 ++++++++++++++----- .../src/Editor/Command/SHCommandManager.h | 13 +++- .../EditorWindow/MenuBar/SHEditorMenuBar.cpp | 4 +- SHADE_Engine/src/Tools/SHDeque.h | 69 +++++++++++++++++ 4 files changed, 141 insertions(+), 22 deletions(-) create mode 100644 SHADE_Engine/src/Tools/SHDeque.h diff --git a/SHADE_Engine/src/Editor/Command/SHCommandManager.cpp b/SHADE_Engine/src/Editor/Command/SHCommandManager.cpp index 3c0ee5dd..b86f9247 100644 --- a/SHADE_Engine/src/Editor/Command/SHCommandManager.cpp +++ b/SHADE_Engine/src/Editor/Command/SHCommandManager.cpp @@ -10,63 +10,102 @@ namespace SHADE { - SHCommandManager::CommandStack SHCommandManager::undoStack{}; - SHCommandManager::CommandStack SHCommandManager::redoStack{}; + + SHCommandManager::CommandStack SHCommandManager::undoStack(defaultStackSize); + SHCommandManager::CommandStack SHCommandManager::redoStack(defaultStackSize); + SHCommandManager::CommandStack SHCommandManager::secondaryUndoStack(defaultStackSize); + SHCommandManager::CommandStack SHCommandManager::secondaryRedoStack(defaultStackSize); + + SHCommandManager::CommandStackPtr SHCommandManager::pCurrUndoStack(&undoStack); + SHCommandManager::CommandStackPtr SHCommandManager::pCurrRedoStack(&redoStack); void SHCommandManager::PerformCommand(BaseCommandPtr commandPtr, bool const& overrideValue) { - redoStack = CommandStack(); + *pCurrRedoStack = CommandStack(defaultStackSize); commandPtr->Execute(); - if (overrideValue && !undoStack.empty()) + if (overrideValue && !pCurrUndoStack->Empty()) { - undoStack.top()->Merge(commandPtr); + pCurrUndoStack->Top()->Merge(commandPtr); } else { - undoStack.push(commandPtr); + pCurrUndoStack->Push(commandPtr); } } void SHCommandManager::RegisterCommand(BaseCommandPtr commandPtr) { - undoStack.push(commandPtr); + pCurrUndoStack->Push(commandPtr); } void SHCommandManager::UndoCommand() { - if (undoStack.empty()) + if (pCurrUndoStack->Empty()) return; - undoStack.top()->Undo(); - redoStack.push(undoStack.top()); - undoStack.pop(); + pCurrUndoStack->Top()->Undo(); + pCurrRedoStack->Push(pCurrUndoStack->Top()); + pCurrUndoStack->Pop(); } void SHCommandManager::RedoCommand() { - if (redoStack.empty()) + if (pCurrRedoStack->Empty()) return; - redoStack.top()->Execute(); - undoStack.push(redoStack.top()); - redoStack.pop(); + pCurrRedoStack->Top()->Execute(); + pCurrUndoStack->Push(pCurrRedoStack->Top()); + pCurrRedoStack->Pop(); } std::size_t SHCommandManager::GetUndoStackSize() { - return undoStack.size(); + return pCurrUndoStack->Size(); } std::size_t SHCommandManager::GetRedoStackSize() { - return redoStack.size(); + return pCurrRedoStack->Size(); } void SHCommandManager::PopLatestCommandFromRedoStack() { - redoStack.pop(); + pCurrRedoStack->Pop(); } void SHCommandManager::PopLatestCommandFromUndoStack() { - undoStack.pop(); + pCurrUndoStack->Pop(); } + + void SHCommandManager::SwapStacks() + { + if (pCurrUndoStack == &undoStack) + { + pCurrUndoStack = &secondaryUndoStack; + } + else + { + secondaryUndoStack.Clear(); + pCurrUndoStack = &undoStack; + } + + if (pCurrRedoStack == &redoStack) + { + pCurrRedoStack = &secondaryRedoStack; + } + else + { + secondaryRedoStack.Clear(); + pCurrRedoStack = &redoStack; + } + } + + void SHCommandManager::ClearAll() + { + undoStack.Clear(); + redoStack.Clear(); + + secondaryUndoStack.Clear(); + secondaryRedoStack.Clear(); + } + }//namespace SHADE diff --git a/SHADE_Engine/src/Editor/Command/SHCommandManager.h b/SHADE_Engine/src/Editor/Command/SHCommandManager.h index a514c464..178347b5 100644 --- a/SHADE_Engine/src/Editor/Command/SHCommandManager.h +++ b/SHADE_Engine/src/Editor/Command/SHCommandManager.h @@ -10,6 +10,7 @@ //#==============================================================# #include "SHCommand.hpp" #include "SH_API.h" +#include "Tools/SHDeque.h" namespace SHADE { @@ -22,7 +23,8 @@ namespace SHADE using BaseCommandPtr = std::shared_ptr; template using SHCommandPtr = std::shared_ptr>; - using CommandStack = std::stack; + using CommandStack = SHDeque; + using CommandStackPtr = CommandStack*; static void PerformCommand(BaseCommandPtr commandPtr, bool const& overrideValue = false); static void RegisterCommand(BaseCommandPtr commandPtr); @@ -34,8 +36,17 @@ namespace SHADE static void PopLatestCommandFromRedoStack(); static void PopLatestCommandFromUndoStack(); + static void SwapStacks(); + static void ClearAll(); + + static constexpr CommandStack::SizeType defaultStackSize = 100; private: + static CommandStackPtr pCurrUndoStack; + static CommandStackPtr pCurrRedoStack; + static CommandStack undoStack; + static CommandStack secondaryUndoStack; static CommandStack redoStack; + static CommandStack secondaryRedoStack; }; }//namespace SHADE diff --git a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp index cfb36cd0..fdde55e1 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp @@ -228,7 +228,7 @@ namespace SHADE .previousState = editor->editorState }; editor->editorState = SHEditor::State::PLAY; - + SHCommandManager::SwapStacks(); SHEventManager::BroadcastEvent(STATE_CHANGE_EVENT, SH_EDITOR_ON_PLAY_EVENT); } } @@ -253,7 +253,7 @@ namespace SHADE .previousState = editor->editorState }; editor->editorState = SHEditor::State::STOP; - + SHCommandManager::SwapStacks(); SHEventManager::BroadcastEvent(STATE_CHANGE_EVENT, SH_EDITOR_ON_STOP_EVENT); editor->LoadScene(SHSceneManager::GetCurrentSceneAssetID()); } diff --git a/SHADE_Engine/src/Tools/SHDeque.h b/SHADE_Engine/src/Tools/SHDeque.h new file mode 100644 index 00000000..99df910a --- /dev/null +++ b/SHADE_Engine/src/Tools/SHDeque.h @@ -0,0 +1,69 @@ +#pragma once +#pragma once + +#include "SH_API.h" +#include + +namespace SHADE +{ + template + class SH_API SHDeque + { + public: + using ValueType = T; + using Pointer = T*; + using ValueRef = T&; + using ValueConstRef = T const&; + using SizeType = uint32_t; + using ContainerType = std::deque; + using ContainerTypeConstRef = std::deque; + + SHDeque(SizeType n) : max_size(n) {} + + ContainerTypeConstRef const& GetDeque() const + { + return deque; + } + + void Push(ValueConstRef obj) + { + if (deque.size() < max_size) + deque.push_front(std::move(obj)); + else + { + deque.pop_back(); + deque.push_front(std::move(obj)); + } + } + + bool Empty() + { + return deque.empty(); + } + + void Pop() + { + deque.pop_front(); + } + + ValueConstRef Top() + { + return deque.front(); + } + + SizeType Size() const noexcept + { + return deque.size(); + } + + void Clear() + { + deque.clear(); + } + + private: + int max_size; + ContainerType deque{}; + + }; +} \ No newline at end of file From 69ac074926530530d640798462ecc170c2e7503d Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Sat, 12 Nov 2022 18:38:57 +0800 Subject: [PATCH 58/59] change entity active to scene node active --- .../src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp | 5 +++-- SHADE_Engine/src/Scene/SHSceneNode.cpp | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp index 2fecae25..dde49838 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp @@ -93,13 +93,14 @@ namespace SHADE { EntityID const& eid = editor->selectedEntities[0]; SHEntity* entity = SHEntityManager::GetEntityByID(eid); - if(!entity) + SHSceneNode* entityNode = SHSceneManager::GetCurrentSceneGraph().GetNode(eid); + if(!entity || !entityNode) { ImGui::End(); return; } ImGui::TextColored(ImGuiColors::green, "EID: %zu", eid); - SHEditorWidgets::CheckBox("##IsActive", [entity]()->bool {return entity->GetActive(); }, [entity](bool const& active) {entity->SetActive(active); }); + SHEditorWidgets::CheckBox("##IsActive", [entityNode]()->bool {return entityNode->IsActive(); }, [entityNode](bool const& active) {entityNode->SetActive(active); }); ImGui::SameLine(); ImGui::InputText("##EntityName", &entity->name); diff --git a/SHADE_Engine/src/Scene/SHSceneNode.cpp b/SHADE_Engine/src/Scene/SHSceneNode.cpp index b619d464..8dac20bd 100644 --- a/SHADE_Engine/src/Scene/SHSceneNode.cpp +++ b/SHADE_Engine/src/Scene/SHSceneNode.cpp @@ -136,7 +136,7 @@ namespace SHADE for (auto* child : children) { - SetActive(newActiveState); + child->SetActive(newActiveState); } } From e2bcb0bbbbc192dd121189257c5eeeabaac4dda5 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Sat, 12 Nov 2022 23:57:12 +0800 Subject: [PATCH 59/59] play pause stop bound to F5 F6 F7 --- .../EditorWindow/MenuBar/SHEditorMenuBar.cpp | 25 +-------- SHADE_Engine/src/Editor/SHEditor.cpp | 56 ++++++++++++++++++- SHADE_Engine/src/Editor/SHEditor.h | 4 ++ 3 files changed, 62 insertions(+), 23 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp index fdde55e1..ce3ca8b5 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp @@ -223,39 +223,20 @@ namespace SHADE { if(editor->SaveScene()) { - const SHEditorStateChangeEvent STATE_CHANGE_EVENT - { - .previousState = editor->editorState - }; - editor->editorState = SHEditor::State::PLAY; - SHCommandManager::SwapStacks(); - SHEventManager::BroadcastEvent(STATE_CHANGE_EVENT, SH_EDITOR_ON_PLAY_EVENT); + editor->Play(); } } ImGui::EndDisabled(); ImGui::BeginDisabled(editor->editorState == SHEditor::State::PAUSE); if(ImGui::SmallButton(ICON_MD_PAUSE)) { - const SHEditorStateChangeEvent STATE_CHANGE_EVENT - { - .previousState = editor->editorState - }; - editor->editorState = SHEditor::State::PAUSE; - - SHEventManager::BroadcastEvent(STATE_CHANGE_EVENT, SH_EDITOR_ON_PAUSE_EVENT); + editor->Pause(); } ImGui::EndDisabled(); ImGui::BeginDisabled(editor->editorState == SHEditor::State::STOP); if(ImGui::SmallButton(ICON_MD_STOP)) { - const SHEditorStateChangeEvent STATE_CHANGE_EVENT - { - .previousState = editor->editorState - }; - editor->editorState = SHEditor::State::STOP; - SHCommandManager::SwapStacks(); - SHEventManager::BroadcastEvent(STATE_CHANGE_EVENT, SH_EDITOR_ON_STOP_EVENT); - editor->LoadScene(SHSceneManager::GetCurrentSceneAssetID()); + editor->Stop(); } ImGui::EndDisabled(); ImGui::EndMenuBar(); diff --git a/SHADE_Engine/src/Editor/SHEditor.cpp b/SHADE_Engine/src/Editor/SHEditor.cpp index c4ad3459..90655a62 100644 --- a/SHADE_Engine/src/Editor/SHEditor.cpp +++ b/SHADE_Engine/src/Editor/SHEditor.cpp @@ -168,7 +168,19 @@ namespace SHADE { SHCommandManager::UndoCommand(); } - + if(ImGui::IsKeyReleased(ImGuiKey_F5)) + { + Play(); + } + else if (ImGui::IsKeyReleased(ImGuiKey_F6)) + { + Pause(); + } + else if (ImGui::IsKeyReleased(ImGuiKey_F7)) + { + Stop(); + } + Render(); } @@ -597,6 +609,48 @@ namespace SHADE } } + void SHEditor::Play() + { + if(editorState == State::PLAY) + return; + if (SaveScene()) + { + const SHEditorStateChangeEvent STATE_CHANGE_EVENT + { + .previousState = editorState + }; + editorState = State::PLAY; + SHCommandManager::SwapStacks(); + SHEventManager::BroadcastEvent(STATE_CHANGE_EVENT, SH_EDITOR_ON_PLAY_EVENT); + } + } + + void SHEditor::Pause() + { + if (editorState == State::PAUSE) + return; + const SHEditorStateChangeEvent STATE_CHANGE_EVENT + { + .previousState = editorState + }; + editorState = State::PAUSE; + SHEventManager::BroadcastEvent(STATE_CHANGE_EVENT, SH_EDITOR_ON_PAUSE_EVENT); + } + + void SHEditor::Stop() + { + if (editorState == State::STOP) + return; + const SHEditorStateChangeEvent STATE_CHANGE_EVENT + { + .previousState = editorState + }; + editorState = SHEditor::State::STOP; + SHCommandManager::SwapStacks(); + SHEventManager::BroadcastEvent(STATE_CHANGE_EVENT, SH_EDITOR_ON_STOP_EVENT); + LoadScene(SHSceneManager::GetCurrentSceneAssetID()); + } + void SHEditor::NewFrame() { SDL_Event event; diff --git a/SHADE_Engine/src/Editor/SHEditor.h b/SHADE_Engine/src/Editor/SHEditor.h index 0f5a3aaa..0de7796a 100644 --- a/SHADE_Engine/src/Editor/SHEditor.h +++ b/SHADE_Engine/src/Editor/SHEditor.h @@ -184,6 +184,10 @@ namespace SHADE void LoadScene(AssetID const& assetID) noexcept; + void Play(); + void Pause(); + void Stop(); + // List of selected entities std::vector selectedEntities;