From 0e518c52a953da2023a4fef789ff175ea89dd565 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Sun, 2 Oct 2022 04:22:32 +0800 Subject: [PATCH 01/50] Fixed bug when SceneGraph is destroyed --- SHADE_Engine/src/Scene/SHSceneGraph.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/SHADE_Engine/src/Scene/SHSceneGraph.cpp b/SHADE_Engine/src/Scene/SHSceneGraph.cpp index da2dcffd..60f0794d 100644 --- a/SHADE_Engine/src/Scene/SHSceneGraph.cpp +++ b/SHADE_Engine/src/Scene/SHSceneGraph.cpp @@ -312,6 +312,11 @@ namespace SHADE if (parentNode == nullptr) { SHLOG_WARNING("Removing Entity {}'s parent", entityID) + + if (parent) + parent->RemoveChild(this); + + return; } // Handle self assignment From 51eba31ad4d5a5ea6a9ca3a6637c0e5de41a57a4 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Wed, 19 Oct 2022 18:38:11 +0800 Subject: [PATCH 02/50] Added animation asset class Added animation reading from assimp scene Separated assimp loading from mesh loader in preparation for exe use --- SHADE_Engine/SHAnimationAsset.h | 30 ++++ .../src/Assets/Asset Types/SHAnimationAsset.h | 30 ++++ .../src/Assets/Libraries/SHAssimpLibrary.cpp | 143 ++++++++++++++++ .../src/Assets/Libraries/SHAssimpLibrary.h | 36 ++++ .../src/Assets/Libraries/SHMeshLoader.cpp | 162 ------------------ .../src/Assets/Libraries/SHMeshLoader.h | 16 +- SHADE_Engine/src/Assets/SHAssetManager.cpp | 77 +++++---- SHADE_Engine/src/Assets/SHAssetManager.h | 9 +- 8 files changed, 287 insertions(+), 216 deletions(-) create mode 100644 SHADE_Engine/SHAnimationAsset.h create mode 100644 SHADE_Engine/src/Assets/Asset Types/SHAnimationAsset.h create mode 100644 SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.cpp create mode 100644 SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.h diff --git a/SHADE_Engine/SHAnimationAsset.h b/SHADE_Engine/SHAnimationAsset.h new file mode 100644 index 00000000..d8d0ffb1 --- /dev/null +++ b/SHADE_Engine/SHAnimationAsset.h @@ -0,0 +1,30 @@ +/*************************************************************************//** + * \file SHAnimationAsset.h + * \author Loh Xiao Qi + * \date October 2022 + * \brief + * + * 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 +#include +#include "SH_API.power h" + +namespace SHADE +{ + struct SH_API SHAnimationAsset + { + std::string name; + + std::vector nodeChannels; + std::vector meshChannels; + std::vector morphMeshChannels; + + double duration; + double ticksPerSecond; + }; +} \ No newline at end of file diff --git a/SHADE_Engine/src/Assets/Asset Types/SHAnimationAsset.h b/SHADE_Engine/src/Assets/Asset Types/SHAnimationAsset.h new file mode 100644 index 00000000..76f4c0ac --- /dev/null +++ b/SHADE_Engine/src/Assets/Asset Types/SHAnimationAsset.h @@ -0,0 +1,30 @@ +/*************************************************************************//** + * \file SHAnimationAsset.h + * \author Loh Xiao Qi + * \date October 2022 + * \brief + * + * 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 +#include +#include "SH_API.h" + +namespace SHADE +{ + struct SH_API SHAnimationAsset + { + std::string name; + + std::vector nodeChannels; + std::vector meshChannels; + std::vector morphMeshChannels; + + double duration; + double ticksPerSecond; + }; +} \ No newline at end of file diff --git a/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.cpp b/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.cpp new file mode 100644 index 00000000..feea9f35 --- /dev/null +++ b/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.cpp @@ -0,0 +1,143 @@ +/*************************************************************************//** + * \file SHAssimpLibrary.cpp + * \author Loh Xiao Qi + * \date October 2022 + * \brief + * + * 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 "SHpch.h" +#include "SHAssimpLibrary.h" +#include + +namespace SHADE +{ + Assimp::Importer SHAssimpLibrary::aiImporter; + + void SHAssimpLibrary::ProcessNode(aiNode const& node, aiScene const& scene, MeshVectorRef meshes) noexcept + { + for (size_t i {0}; i < node.mNumMeshes; ++i) + { + aiMesh* mesh = scene.mMeshes[node.mMeshes[i]]; + meshes.push_back(ProcessMesh(*mesh)); + } + + for (size_t i{ 0 }; i < node.mNumChildren; ++i) + { + ProcessNode(*node.mChildren[i], scene, meshes); + } + } + + void SHAssimpLibrary::ExtractAnimations(aiScene const& scene, AnimVectorRef anims) noexcept + { + if (scene.HasAnimations()) + { + std::vector anims(scene.mNumAnimations); + for (auto i{0}; i < scene.mNumAnimations; ++i) + { + auto const& anim {*scene.mAnimations[i]}; + + anims[i].name = anim.mName.C_Str(); + + anims[i].duration = anim.mDuration; + anims[i].ticksPerSecond = anim.mTicksPerSecond; + + std::copy_n(anim.mChannels, anim.mNumChannels, anims[i].nodeChannels.data()); + std::copy_n(anim.mMeshChannels, anim.mNumMeshChannels, anims[i].meshChannels.data()); + std::copy_n(anim.mMorphMeshChannels, anim.mNumMorphMeshChannels, anims[i].morphMeshChannels.data()); + } + } + } + + SHMeshAsset SHAssimpLibrary::ProcessMesh(aiMesh const& mesh) noexcept + { + SHMeshAsset result + { + .compiled { false}, + .changed { false } + }; + + for (size_t i{0}; i < mesh.mNumVertices; ++i) + { + // Vertex position + SHVec3 vertex; + vertex.x = mesh.mVertices[i].x; + vertex.y = mesh.mVertices[i].y; + vertex.z = mesh.mVertices[i].z; + result.vertexPosition.push_back(vertex); + + // Tex coords + SHVec2 texCoord{0.f, 0.f}; + if (mesh.mTextureCoords[0]) + { + texCoord.x = mesh.mTextureCoords[0][i].x; + texCoord.y = mesh.mTextureCoords[0][i].y; + } + result.texCoords.push_back(texCoord); + + // Normals + SHVec3 normal{0.f, 0.f, 0.f}; + if (mesh.mNormals) + { + normal.x = mesh.mNormals[i].x; + normal.y = mesh.mNormals[i].y; + normal.z = mesh.mNormals[i].z; + } + result.vertexNormal.push_back(normal); + + // Tangent + SHVec3 tangent{0.f, 0.f, 0.f}; + if (mesh.mTangents) + { + tangent.x = mesh.mTangents[i].x; + tangent.y = mesh.mTangents[i].y; + tangent.z = mesh.mTangents[i].z; + } + result.vertexTangent.push_back(tangent); + } + + for (size_t i {0}; i < mesh.mNumFaces; ++i) + { + aiFace face = mesh.mFaces[i]; + for (size_t j{0}; j < face.mNumIndices; ++j) + { + result.indices.push_back(face.mIndices[j]); + } + } + + result.header.vertexCount = static_cast(result.vertexPosition.size()); + result.header.indexCount = static_cast(result.indices.size()); + result.header.meshName = mesh.mName.C_Str(); + + return result; + } + + void SHAssimpLibrary::LoadFromFile(AssetPath path, MeshVectorRef meshes, AnimVectorRef anims) noexcept + { + const aiScene* scene = aiImporter.ReadFile(path.string().c_str(), + aiProcess_Triangulate // Make sure we get triangles rather than nvert polygons + | aiProcess_GenUVCoords // Convert any type of mapping to uv mapping + | aiProcess_TransformUVCoords // preprocess UV transformations (scaling, translation ...) + | aiProcess_FindInstances // search for instanced meshes and remove them by references to one master + | aiProcess_CalcTangentSpace // calculate tangents and bitangents if possible + | aiProcess_JoinIdenticalVertices // join identical vertices/ optimize indexing + | aiProcess_RemoveRedundantMaterials // remove redundant materials + | aiProcess_FindInvalidData // detect invalid model data, such as invalid normal vectors + | aiProcess_FlipUVs // flip the V to match the Vulkans way of doing UVs + ); + + if (!scene || !scene->HasMeshes()) + { + SHLOG_ERROR("ERROR in GLTF::ASSIMP: {}\nFile: {}", aiImporter.GetErrorString(), path.string()); + return; + } + + ExtractAnimations(*scene, anims); + + ProcessNode(*scene->mRootNode, *scene, meshes); + + aiImporter.FreeScene(); + } +} diff --git a/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.h b/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.h new file mode 100644 index 00000000..a4a0447a --- /dev/null +++ b/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.h @@ -0,0 +1,36 @@ +/*************************************************************************//** + * \file SHAssimpLibrary.h + * \author Loh Xiao Qi + * \date October 2022 + * \brief + * + * 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 +#include +#include +#include "../SHAssetMacros.h" +#include "../Asset Types/SHMeshAsset.h" +#include "../Asset Types/SHAnimationAsset.h" + +namespace SHADE +{ + class SHAssimpLibrary + { + private: + using MeshVectorRef = std::vector&; + using AnimVectorRef = std::vector&; + + static Assimp::Importer aiImporter; + static void ProcessNode(aiNode const& node, aiScene const& scene,MeshVectorRef meshes) noexcept; + static void ExtractAnimations(aiScene const& scene, AnimVectorRef anims) noexcept; + static SHMeshAsset ProcessMesh(aiMesh const& mesh) noexcept; + + public: + static void LoadFromFile(AssetPath path, MeshVectorRef meshes, AnimVectorRef anims) noexcept; + }; +} \ No newline at end of file diff --git a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp index 4bfa2d9b..73fed1fb 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp +++ b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp @@ -12,128 +12,10 @@ *****************************************************************************/ #include "SHpch.h" #include "SHMeshLoader.h" -#include #include namespace SHADE { - Assimp::Importer SHMeshLoader::aiImporter; - - void SHMeshLoader::ProcessNode(aiNode const& node, aiScene const& scene, std::vector& meshes) noexcept - { - for (size_t i {0}; i < node.mNumMeshes; ++i) - { - aiMesh* mesh = scene.mMeshes[node.mMeshes[i]]; - meshes.push_back(ProcessMesh(*mesh, scene)); - } - - for (size_t i{ 0 }; i < node.mNumChildren; ++i) - { - ProcessNode(*node.mChildren[i], scene, meshes); - } - } - - SHMeshAsset SHMeshLoader::ProcessMesh(aiMesh const& mesh, aiScene const& scene) noexcept - { - (void)scene; - - SHMeshAsset result - { - .compiled { false}, - .changed { false } - }; - - for (size_t i{0}; i < mesh.mNumVertices; ++i) - { - // Vertex position - SHVec3 vertex; - vertex.x = mesh.mVertices[i].x; - vertex.y = mesh.mVertices[i].y; - vertex.z = mesh.mVertices[i].z; - result.vertexPosition.push_back(vertex); - - // Tex coords - SHVec2 texCoord{0.f, 0.f}; - if (mesh.mTextureCoords[0]) - { - texCoord.x = mesh.mTextureCoords[0][i].x; - texCoord.y = mesh.mTextureCoords[0][i].y; - } - result.texCoords.push_back(texCoord); - - // Normals - SHVec3 normal{0.f, 0.f, 0.f}; - if (mesh.mNormals) - { - normal.x = mesh.mNormals[i].x; - normal.y = mesh.mNormals[i].y; - normal.z = mesh.mNormals[i].z; - } - result.vertexNormal.push_back(normal); - - // Tangent - SHVec3 tangent{0.f, 0.f, 0.f}; - if (mesh.mTangents) - { - tangent.x = mesh.mTangents[i].x; - tangent.y = mesh.mTangents[i].y; - tangent.z = mesh.mTangents[i].z; - } - result.vertexTangent.push_back(tangent); - } - - for (size_t i {0}; i < mesh.mNumFaces; ++i) - { - aiFace face = mesh.mFaces[i]; - for (size_t j{0}; j < face.mNumIndices; ++j) - { - result.indices.push_back(face.mIndices[j]); - } - } - - result.header.vertexCount = static_cast(result.vertexPosition.size()); - result.header.indexCount = static_cast(result.indices.size()); - result.header.meshName = mesh.mName.C_Str(); - - return result; - } - - void SHMeshLoader::LoadExternal(std::vector& meshes, AssetPath path) noexcept - { - const aiScene* scene = aiImporter.ReadFile(path.string().c_str(), - aiProcess_Triangulate // Make sure we get triangles rather than nvert polygons - | aiProcess_GenUVCoords // Convert any type of mapping to uv mapping - | aiProcess_TransformUVCoords // preprocess UV transformations (scaling, translation ...) - | aiProcess_FindInstances // search for instanced meshes and remove them by references to one master - | aiProcess_CalcTangentSpace // calculate tangents and bitangents if possible - | aiProcess_JoinIdenticalVertices // join identical vertices/ optimize indexing - | aiProcess_RemoveRedundantMaterials // remove redundant materials - | aiProcess_FindInvalidData // detect invalid model data, such as invalid normal vectors - | aiProcess_FlipUVs // flip the V to match the Vulkans way of doing UVs - ); - - if (!scene || !scene->HasMeshes()) - { - SHLOG_ERROR("ERROR in GLTF::ASSIMP: {}\nFile: {}", aiImporter.GetErrorString(), path.string()); - return; - } - - //TODO MATERIALS FROM MESHES - //if (scene->HasMaterials()) - //{ - // for (int i{0}; i < scene->mNumMaterials; ++i) - // { - // if (scene->mMaterials[i]->mNumProperties > 0) - // { - // for (int j{0}; j < scene->mMaterials[i]->mProperties[j].) - // } - //std::cout << scene->mMaterials[i]->; - // } - //} - - ProcessNode(*scene->mRootNode, *scene, meshes); - } - void SHMeshLoader::LoadSHMesh(SHMeshAsset& mesh, AssetPath path) noexcept { std::ifstream file{ path.string(), std::ios::in | std::ios::binary }; @@ -168,38 +50,6 @@ namespace SHADE file.read(reinterpret_cast(vertNorm.data()), vertexVec3Byte); file.read(reinterpret_cast(texCoord.data()), vertexVec2Byte); file.read(reinterpret_cast(indices.data()), sizeof(uint32_t) * indexCount); - - //for (auto i{ 0 }; i < vertCount; ++i) - //{ - // file >> vertPos[i].x; - // file >> vertPos[i].y; - // file >> vertPos[i].z; - //} - // - //for (auto i{ 0 }; i < vertCount; ++i) - //{ - // file >> vertTan[i].x; - // file >> vertTan[i].y; - // file >> vertTan[i].z; - //} - - //for (auto i{ 0 }; i < vertCount; ++i) - //{ - // file >> vertNorm[i].x; - // file >> vertNorm[i].y; - // file >> vertNorm[i].z; - //} - - //for (auto i{ 0 }; i < vertCount; ++i) - //{ - // file >> texCoord[i].x; - // file >> texCoord[i].y; - //} - - //for (auto i{ 0 }; i < indexCount; ++i) - //{ - // file >> indices[i]; - //} mesh.compiled = true; mesh.changed = false; @@ -216,16 +66,4 @@ namespace SHADE file.close(); } - - void SHMeshLoader::LoadMesh(std::vector& meshes, AssetPath path) noexcept - { - if (path.extension().string() == GLTF_EXTENSION) - { - LoadExternal(meshes, path); - return; - } - - meshes.emplace_back(); - LoadSHMesh(meshes.back(), path); - } } diff --git a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.h b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.h index a27d63ea..f01b942a 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.h +++ b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.h @@ -10,27 +10,13 @@ * of DigiPen Institute of Technology is prohibited. *****************************************************************************/ #pragma once -#include -#include #include "../SHAssetMacros.h" #include "../Asset Types/SHMeshAsset.h" -#include namespace SHADE { - class SHMeshLoader + struct SHMeshLoader { - private: - static Assimp::Importer aiImporter; - - static void ProcessNode(aiNode const& node, aiScene const& scene, std::vector& meshes) noexcept; - - static SHMeshAsset ProcessMesh(aiMesh const& mesh, aiScene const& scene) noexcept; - - static void LoadExternal(std::vector& meshes, AssetPath path) noexcept; - - public: - static void LoadMesh(std::vector& meshes, AssetPath path) noexcept; static void LoadSHMesh(SHMeshAsset& meshes, AssetPath path) noexcept; }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index aa9772dd..faca24b2 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -14,6 +14,7 @@ #include "SHAssetMetaHandler.h" #include "Filesystem/SHFileSystem.h" +#include "Libraries/SHAssimpLibrary.h" #include "Libraries/SHMeshLoader.h" #include "Libraries/SHTextureLoader.h" @@ -200,38 +201,38 @@ namespace SHADE } - void SHAssetManager::LoadDataTemp(std::string p) noexcept - { - AssetPath path{ p }; + //void SHAssetManager::LoadDataTemp(std::string p) noexcept + //{ + // AssetPath path{ p }; - if (path.extension().string() == FBX_EXTENSION - || path.extension().string() == GLTF_EXTENSION - || path.extension().string() == MESH_EXTENSION) - { - LoadGLTF( - { - .name {path.filename().string()}, - .id {0}, - .type {AssetType::MESH}, - .path {path}, - .location {0} - } - ); - } - else if (path.extension().string() == DDS_EXTENSION - || path.extension().string() == TEXTURE_EXTENSION) - { - LoadDDS( - { - .name {path.filename().string()}, - .id {0}, - .type {AssetType::DDS}, - .path {path}, - .location {0} - } - ); - } - } + // if (path.extension().string() == FBX_EXTENSION + // || path.extension().string() == GLTF_EXTENSION + // || path.extension().string() == MESH_EXTENSION) + // { + // LoadGLTF( + // { + // .name {path.filename().string()}, + // .id {0}, + // .type {AssetType::MESH}, + // .path {path}, + // .location {0} + // } + // ); + // } + // else if (path.extension().string() == DDS_EXTENSION + // || path.extension().string() == TEXTURE_EXTENSION) + // { + // LoadDDS( + // { + // .name {path.filename().string()}, + // .id {0}, + // .type {AssetType::DDS}, + // .path {path}, + // .location {0} + // } + // ); + // } + //} std::vector SHAssetManager::GetAllMeshes() noexcept { @@ -319,11 +320,12 @@ namespace SHADE return false; } - void SHAssetManager::LoadGLTF(SHAsset asset) noexcept + void SHAssetManager::LoadGLTF(AssetPath path) noexcept { std::vector meshes; - - SHMeshLoader::LoadMesh(meshes, asset.path); + std::vector anims; + + SHAssimpLibrary::LoadFromFile(path, meshes, anims); for (auto const& mesh : meshes) { @@ -333,7 +335,7 @@ namespace SHADE AssetPath path; if (!mesh.compiled) { - path = SHMeshCompiler::CompileMeshBinary(mesh, asset.path); + path = SHMeshCompiler::CompileMeshBinary(mesh, path); } assetCollection.emplace_back( @@ -344,6 +346,11 @@ namespace SHADE 0 ); } + + for (auto const& anim : anims) + { + //TODO Register anim resource and compile into binary + } } void SHAssetManager::LoadDDS(SHAsset asset) noexcept diff --git a/SHADE_Engine/src/Assets/SHAssetManager.h b/SHADE_Engine/src/Assets/SHAssetManager.h index 50549e01..b2c4216b 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.h +++ b/SHADE_Engine/src/Assets/SHAssetManager.h @@ -71,12 +71,16 @@ namespace SHADE // -------------------------------------------------------------------------/ //TODO: TEMPORARY FOR TESTING GLTF & DDS - static void LoadDataTemp(std::string path) noexcept; + //static void LoadDataTemp(std::string path) noexcept; static std::vector GetAllMeshes() noexcept; static std::vector GetAllTextures() noexcept; static SHMeshAsset const* GetMesh(AssetID id) noexcept; static SHTextureAsset const* GetTexture(AssetID id) noexcept; + + // Specialised load calls + static void LoadGLTF(AssetPath path) noexcept; + static void LoadDDS(SHAsset asset) noexcept; private: /**************************************************************************** * \brief Load resource data into memory @@ -118,9 +122,6 @@ namespace SHADE static bool IsRecognised(char const*) noexcept; - // Specialised load calls - static void LoadGLTF(SHAsset asset) noexcept; - static void LoadDDS(SHAsset asset) noexcept; static FMOD::System* audioSystem; static std::unordered_map* audioSoundList; From 5a0b34ceea63dd80bdedda43e6c74611424b5517 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 20 Oct 2022 17:47:32 +0800 Subject: [PATCH 03/50] Added Event for Scene Graph Change Parent --- SHADE_Engine/src/Events/SHEventDefines.h | 11 ++++++----- SHADE_Engine/src/Scene/SHSceneGraph.cpp | 21 +++++++++++++++++++-- SHADE_Engine/src/Scene/SHSceneGraph.h | 15 +++++++++------ 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/SHADE_Engine/src/Events/SHEventDefines.h b/SHADE_Engine/src/Events/SHEventDefines.h index 317b67c1..fc9f41e1 100644 --- a/SHADE_Engine/src/Events/SHEventDefines.h +++ b/SHADE_Engine/src/Events/SHEventDefines.h @@ -5,8 +5,9 @@ typedef uint32_t SHEventIdentifier; typedef uint32_t SHEventHandle; //Add your event identifiers here: -constexpr SHEventIdentifier SH_EXAMPLE_EVENT{0}; -constexpr SHEventIdentifier SH_ENTITY_DESTROYED_EVENT{ 1 }; -constexpr SHEventIdentifier SH_ENTITY_CREATION_EVENT{ 2 }; -constexpr SHEventIdentifier SH_COMPONENT_ADDED_EVENT{ 3 }; -constexpr SHEventIdentifier SH_COMPONENT_REMOVED_EVENT{ 4 }; +constexpr SHEventIdentifier SH_EXAMPLE_EVENT { 0 }; +constexpr SHEventIdentifier SH_ENTITY_DESTROYED_EVENT { 1 }; +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 }; diff --git a/SHADE_Engine/src/Scene/SHSceneGraph.cpp b/SHADE_Engine/src/Scene/SHSceneGraph.cpp index 572e5927..291b5b2b 100644 --- a/SHADE_Engine/src/Scene/SHSceneGraph.cpp +++ b/SHADE_Engine/src/Scene/SHSceneGraph.cpp @@ -15,6 +15,7 @@ // Project Headers #include "ECS_Base/Managers/SHEntityManager.h" +#include "Events/SHEventManager.hpp" #include "Tools/SHLogger.h" #include "Tools/SHException.h" @@ -364,10 +365,18 @@ namespace SHADE } //////////////////////////////////////// + const SHSceneGraphChangeParentEvent EVENT_DATA + { + .oldParentID = NODE_ITER->second->GetParent()->GetEntityID(), + .newParentID = parent->GetEntityID() + }; + if (parent == nullptr) parent = root; NODE_ITER->second->SetParent(parent); + + SHEventManager::BroadcastEvent(EVENT_DATA, SH_SCENEGRAPH_CHANGE_PARENT_EVENT); } void SHSceneGraph::SetParent(EntityID entityID, EntityID parent) const noexcept @@ -401,8 +410,16 @@ namespace SHADE } //////////////////////////////////////// + const SHSceneGraphChangeParentEvent EVENT_DATA + { + .oldParentID = NODE_ITER->second->GetParent()->GetEntityID(), + .newParentID = parent + }; + SHSceneNode* currentNode = NODE_ITER->second; currentNode->SetParent(PARENT_ITER->second); + + SHEventManager::BroadcastEvent(EVENT_DATA, SH_SCENEGRAPH_CHANGE_PARENT_EVENT); } /*-----------------------------------------------------------------------------------*/ @@ -563,7 +580,7 @@ namespace SHADE ReleaseNode(node); } - void SHSceneGraph::Traverse (const UnaryPredicate& predicate) const + void SHSceneGraph::Traverse (const UnaryFunction& predicate) const { TraverseAndInvokePredicate(root, predicate); } @@ -602,7 +619,7 @@ namespace SHADE delete node; } - void SHSceneGraph::TraverseAndInvokePredicate(const SHSceneNode* node, const UnaryPredicate& predicate) + void SHSceneGraph::TraverseAndInvokePredicate(const SHSceneNode* node, const UnaryFunction& predicate) { for (auto* child : node->children) { diff --git a/SHADE_Engine/src/Scene/SHSceneGraph.h b/SHADE_Engine/src/Scene/SHSceneGraph.h index 3f3ebf92..62715f72 100644 --- a/SHADE_Engine/src/Scene/SHSceneGraph.h +++ b/SHADE_Engine/src/Scene/SHSceneGraph.h @@ -97,9 +97,8 @@ namespace SHADE /* Type Definitions */ /*---------------------------------------------------------------------------------*/ - using EntityNodeMap = std::unordered_map; - - using UnaryPredicate = std::function; + using EntityNodeMap = std::unordered_map; + using UnaryFunction = std::function; /*---------------------------------------------------------------------------------*/ @@ -143,8 +142,7 @@ namespace SHADE bool RemoveNode (SHSceneNode* nodeToRemove) noexcept; void Reset () noexcept; - void Traverse (const UnaryPredicate& predicate) const; - + void Traverse (const UnaryFunction& predicate) const; private: /*---------------------------------------------------------------------------------*/ @@ -160,8 +158,13 @@ namespace SHADE SHSceneNode* AllocateNode (EntityID entityID); void ReleaseNode (SHSceneNode* node) noexcept; - static void TraverseAndInvokePredicate (const SHSceneNode* node, const UnaryPredicate& predicate); + static void TraverseAndInvokePredicate (const SHSceneNode* node, const UnaryFunction& predicate); }; + struct SHSceneGraphChangeParentEvent + { + EntityID oldParentID; + EntityID newParentID; + }; } // namespace SHADE \ No newline at end of file From 314d497b66c93cf21c5f245e4846961297eb6a60 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 20 Oct 2022 18:35:57 +0800 Subject: [PATCH 04/50] Reparenting objects maintain world transforms --- Assets/Editor/Layouts/UserLayout.ini | 20 ++++----- SHADE_Application/src/Scenes/SBTestScene.cpp | 6 +-- .../src/Math/Transform/SHTransformSystem.cpp | 43 ++++++++++++++++++- .../src/Math/Transform/SHTransformSystem.h | 6 ++- SHADE_Engine/src/Scene/SHSceneGraph.cpp | 10 +++-- SHADE_Engine/src/Scene/SHSceneGraph.h | 1 + 6 files changed, 65 insertions(+), 21 deletions(-) diff --git a/Assets/Editor/Layouts/UserLayout.ini b/Assets/Editor/Layouts/UserLayout.ini index 530ee770..7b0a70f8 100644 --- a/Assets/Editor/Layouts/UserLayout.ini +++ b/Assets/Editor/Layouts/UserLayout.ini @@ -10,7 +10,7 @@ Collapsed=0 [Window][Hierarchy Panel] Pos=0,142 -Size=571,918 +Size=349,918 Collapsed=0 DockId=0x00000004,0 @@ -20,29 +20,29 @@ Size=400,400 Collapsed=0 [Window][Inspector] -Pos=1649,48 -Size=271,1012 +Pos=1483,48 +Size=437,1012 Collapsed=0 DockId=0x00000006,0 [Window][Profiler] Pos=0,48 -Size=571,92 +Size=349,92 Collapsed=0 DockId=0x00000003,0 [Window][Viewport] -Pos=573,48 -Size=1074,1012 +Pos=351,48 +Size=1130,1012 Collapsed=0 DockId=0x00000002,0 [Docking][Data] DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,79 Size=1920,1012 Split=X - DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1992,1036 Split=X - DockNode ID=0x00000001 Parent=0x00000005 SizeRef=571,1036 Split=Y Selected=0x1E6EB881 + DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1481,1036 Split=X + DockNode ID=0x00000001 Parent=0x00000005 SizeRef=349,1036 Split=Y Selected=0x1E6EB881 DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,94 Selected=0x1E6EB881 DockNode ID=0x00000004 Parent=0x00000001 SizeRef=225,940 Selected=0xE096E5AE - DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1074,1036 CentralNode=1 Selected=0x13926F0B - DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=271,1036 Selected=0xE7039252 + DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1130,1036 CentralNode=1 Selected=0x13926F0B + DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=437,1036 Selected=0xE7039252 diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index f1d656ee..d81550e1 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -77,9 +77,9 @@ namespace Sandbox customMat->SetProperty("data.alpha", 0.1f); // Create Stress Test Objects - static const SHVec3 TEST_OBJ_SCALE = SHVec3::One * 0.5f; - constexpr int NUM_ROWS = 10; - constexpr int NUM_COLS = 10; + static const SHVec3 TEST_OBJ_SCALE = SHVec3::One; + constexpr int NUM_ROWS = 2; + constexpr int NUM_COLS = 1; static const SHVec3 TEST_OBJ_SPACING = { 0.1f, 0.1f, 0.1f }; static const SHVec3 TEST_OBJ_START_POS = { -(NUM_COLS / 2 * TEST_OBJ_SPACING.x) + 1.0f, -2.0f, -1.0f }; diff --git a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp index 6b05e323..448fa60d 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp +++ b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp @@ -17,7 +17,6 @@ #include "Scene/SHSceneManager.h" #include "ECS_Base/Managers/SHComponentManager.h" #include "ECS_Base/Managers/SHEntityManager.h" -#include "Tools/SHException.h" namespace SHADE { @@ -47,7 +46,9 @@ namespace SHADE void SHTransformSystem::Init() { - + std::shared_ptr thisReceiver { std::make_shared>(this, &SHTransformSystem::ChangeParent) }; + ReceiverPtr receiver = std::dynamic_pointer_cast(thisReceiver); + SHEventManager::SubscribeTo(SH_SCENEGRAPH_CHANGE_PARENT_EVENT, receiver); } void SHTransformSystem::Exit() @@ -59,6 +60,44 @@ namespace SHADE /* Private Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ + SHEventHandle SHTransformSystem::ChangeParent(SHEventPtr changeParentEvent) + { + const auto& eventData = reinterpret_cast*>(changeParentEvent.get()); + + // Get Current Respective Components + auto* tf = SHComponentManager::GetComponent(eventData->data->entityID); + const auto* PARENT = SHComponentManager::GetComponent_s(eventData->data->newParentID); + + // Recompute local transform and store localToWorld Matrix + SHMatrix localToWorld = SHMatrix::Identity; + SHMatrix worldToLocal = SHMatrix::Identity; + + if (PARENT != nullptr) // Not the root + { + localToWorld = PARENT->GetTRS(); + worldToLocal = SHMatrix::Inverse(localToWorld); + } + + // Maintain World Transform and recompute Local Transform + + // Compute Local Position + tf->local.position = SHVec3::Transform(tf->world.position, worldToLocal); + + // Compute Local Rotation + tf->local.rotation = tf->world.rotation; + if (PARENT) + tf->local.rotation -= PARENT->GetLocalRotation(); + + // Compute Local Scale + tf->local.scale = tf->world.scale; + if (PARENT) + tf->local.scale /= PARENT->GetLocalScale(); + + tf->local.trs = localToWorld; + + return eventData->handle; + } + void SHTransformSystem::UpdateEntity(const SHSceneNode* node) { const auto* NODE_TRANSFORM = SHComponentManager::GetComponent_s(node->GetEntityID()); diff --git a/SHADE_Engine/src/Math/Transform/SHTransformSystem.h b/SHADE_Engine/src/Math/Transform/SHTransformSystem.h index 02c3b6c6..8a50b368 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformSystem.h +++ b/SHADE_Engine/src/Math/Transform/SHTransformSystem.h @@ -84,8 +84,10 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ - static void UpdateEntity (const SHSceneNode* node); - static void UpdateTransform(SHTransformComponent& tf, const SHTransformComponent* parent = nullptr); + SHEventHandle ChangeParent (SHEventPtr changeParentEvent); + + static void UpdateEntity (const SHSceneNode* node); + static void UpdateTransform (SHTransformComponent& tf, const SHTransformComponent* parent = nullptr); }; diff --git a/SHADE_Engine/src/Scene/SHSceneGraph.cpp b/SHADE_Engine/src/Scene/SHSceneGraph.cpp index 291b5b2b..ac6975fb 100644 --- a/SHADE_Engine/src/Scene/SHSceneGraph.cpp +++ b/SHADE_Engine/src/Scene/SHSceneGraph.cpp @@ -367,8 +367,9 @@ namespace SHADE const SHSceneGraphChangeParentEvent EVENT_DATA { - .oldParentID = NODE_ITER->second->GetParent()->GetEntityID(), - .newParentID = parent->GetEntityID() + .entityID = entityID + , .oldParentID = NODE_ITER->second->GetParent()->GetEntityID() + , .newParentID = parent ? parent->GetEntityID() : root->GetEntityID() }; if (parent == nullptr) @@ -412,8 +413,9 @@ namespace SHADE const SHSceneGraphChangeParentEvent EVENT_DATA { - .oldParentID = NODE_ITER->second->GetParent()->GetEntityID(), - .newParentID = parent + .entityID = entityID + , .oldParentID = NODE_ITER->second->GetParent()->GetEntityID() + , .newParentID = parent }; SHSceneNode* currentNode = NODE_ITER->second; diff --git a/SHADE_Engine/src/Scene/SHSceneGraph.h b/SHADE_Engine/src/Scene/SHSceneGraph.h index 62715f72..1dfc1542 100644 --- a/SHADE_Engine/src/Scene/SHSceneGraph.h +++ b/SHADE_Engine/src/Scene/SHSceneGraph.h @@ -163,6 +163,7 @@ namespace SHADE struct SHSceneGraphChangeParentEvent { + EntityID entityID; EntityID oldParentID; EntityID newParentID; }; From c177dabcd04890fbc9483c2fd066ab77b65a2725 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Thu, 20 Oct 2022 19:36:43 +0800 Subject: [PATCH 05/50] WIP (not working) --- .../Graphics/Devices/SHVkLogicalDevice.cpp | 9 +++++ .../src/Graphics/Devices/SHVkLogicalDevice.h | 7 +++- .../MiddleEnd/Pipeline/SHPipelineLibrary.cpp | 14 ++++---- .../MiddleEnd/Pipeline/SHPipelineLibrary.h | 8 ++--- .../Graphics/RenderGraph/SHRenderGraph.cpp | 31 +++++++++-------- .../src/Graphics/RenderGraph/SHRenderGraph.h | 11 ++++--- .../RenderGraph/SHRenderGraphNode.cpp | 30 ++++++++--------- .../Graphics/RenderGraph/SHRenderGraphNode.h | 9 ++--- .../RenderGraph/SHRenderGraphResource.cpp | 17 +++++----- .../RenderGraph/SHRenderGraphResource.h | 3 +- .../RenderGraph/SHRenderGraphStorage.h | 33 +++++++++++++++++++ .../src/Graphics/RenderGraph/SHSubpass.cpp | 16 +++++++-- .../src/Graphics/RenderGraph/SHSubpass.h | 13 +++++++- .../Graphics/RenderGraph/SHSubpassCompute.cpp | 21 +++++++++--- .../Graphics/RenderGraph/SHSubpassCompute.h | 22 ++++++++++--- 15 files changed, 172 insertions(+), 72 deletions(-) create mode 100644 SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp index 7c7acfc5..a6b415a9 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp @@ -233,6 +233,8 @@ namespace SHADE , vmaAllocator{rhs.vmaAllocator} , nonDedicatedBestIndex {0} , parentPhysicalDeviceHdl {rhs.parentPhysicalDeviceHdl} + , uboBufferMemoryAlignment{ 0 } + , ssboBufferMemoryAlignment{ 0 } { rhs.vkLogicalDevice = VK_NULL_HANDLE; } @@ -261,6 +263,8 @@ namespace SHADE vmaAllocator = rhs.vmaAllocator; nonDedicatedBestIndex = 0; parentPhysicalDeviceHdl = rhs.parentPhysicalDeviceHdl; + uboBufferMemoryAlignment = rhs.uboBufferMemoryAlignment; + ssboBufferMemoryAlignment = rhs.ssboBufferMemoryAlignment; rhs.vkLogicalDevice = VK_NULL_HANDLE; @@ -529,6 +533,11 @@ namespace SHADE } + Handle SHVkLogicalDevice::CreateComputePipeline(Handle const& pipelineLayoutHdl) noexcept + { + return SHVkInstance::GetResourceManager().Create (GetHandle(), pipelineLayoutHdl); + } + Handle SHVkLogicalDevice::CreateSampler(const SHVkSamplerParams& params) noexcept { return SHVkInstance::GetResourceManager().Create (GetHandle(), params); diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h index 6f7048b8..58d8b398 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h @@ -175,12 +175,17 @@ namespace SHADE std::string const& shaderName ) noexcept; - Handle CreateGraphicsPipeline ( + Handle CreateGraphicsPipeline ( Handle const& pipelineLayoutHdl, SHVkPipelineState const* const state, Handle const& renderpassHdl, Handle subpass ) noexcept; + + Handle CreateComputePipeline ( + Handle const& pipelineLayoutHdl + ) noexcept; + Handle CreateSampler (const SHVkSamplerParams& params) noexcept; Handle CreateRenderpass (std::span const vkDescriptions, std::vector const& subpasses) noexcept; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp index 682b549c..495a3d37 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp @@ -8,7 +8,7 @@ namespace SHADE { - Handle SHPipelineLibrary::CreateDrawPipeline(std::pair, Handle> const& vsFsPair, Handle renderpass, Handle subpass) noexcept + Handle SHPipelineLibrary::CreateGraphicsPipelines(std::pair, Handle> const& vsFsPair, Handle renderpass, Handle subpass) noexcept { SHPipelineLayoutParams params { @@ -52,7 +52,7 @@ namespace SHADE newPipeline->ConstructPipeline(); // Emplace the new pipeline - pipelines.emplace (vsFsPair, newPipeline); + graphicsPipelines.emplace (vsFsPair, newPipeline); return newPipeline; } @@ -62,19 +62,19 @@ namespace SHADE logicalDevice = device; } - Handle SHPipelineLibrary::GetDrawPipline(std::pair, Handle> const& vsFsPair) noexcept + Handle SHPipelineLibrary::GetGraphicsPipeline(std::pair, Handle> const& vsFsPair) noexcept { // return the pipeline requested for - if (pipelines.contains(vsFsPair)) - return pipelines.at(vsFsPair); + if (graphicsPipelines.contains(vsFsPair)) + return graphicsPipelines.at(vsFsPair); else return {}; } - bool SHPipelineLibrary::CheckDrawPipelineExistence(std::pair, Handle> const& vsFsPair) noexcept + bool SHPipelineLibrary::CheckGraphicsPipelineExistence(std::pair, Handle> const& vsFsPair) noexcept { // Returns if a pipeline exists or not - return pipelines.contains(vsFsPair); + return graphicsPipelines.contains(vsFsPair); } } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h index 9a411d25..aeb023c5 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h @@ -23,19 +23,19 @@ namespace SHADE Handle logicalDevice; //! a map of pipelines that are hashed using a pair of shader module handles - std::unordered_map, Handle>, Handle> pipelines; + std::unordered_map, Handle>, Handle> graphicsPipelines; public: void Init (Handle device) noexcept; // Draw pipeline functions. used only when creating pipelines for drawing using a vertex and fragment shader - Handle CreateDrawPipeline ( + Handle CreateGraphicsPipelines ( std::pair, Handle> const& vsFsPair, Handle renderpass, Handle subpass ) noexcept; - Handle GetDrawPipline (std::pair, Handle> const& vsFsPair) noexcept; - bool CheckDrawPipelineExistence (std::pair, Handle> const& vsFsPair) noexcept; + Handle GetGraphicsPipeline (std::pair, Handle> const& vsFsPair) noexcept; + bool CheckGraphicsPipelineExistence (std::pair, Handle> const& vsFsPair) noexcept; }; } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index 98cb6709..1db410c0 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -9,6 +9,7 @@ #include "Graphics/Buffers/SHVkBuffer.h" #include "Tools/SHLogger.h" #include "SHAttachmentDescInitParams.h" +#include "SHRenderGraphStorage.h" namespace SHADE { @@ -52,12 +53,12 @@ namespace SHADE // If we set to if (w == static_cast(-1) && h == static_cast(-1)) { - w = swapchainHdl->GetSwapchainImage(0)->GetWidth(); - h = swapchainHdl->GetSwapchainImage(0)->GetHeight(); - format = swapchainHdl->GetSurfaceFormatKHR().format; + w = renderGraphStorage->swapchain->GetSwapchainImage(0)->GetWidth(); + h = renderGraphStorage->swapchain->GetSwapchainImage(0)->GetHeight(); + format = renderGraphStorage->swapchain->GetSurfaceFormatKHR().format; } - graphResources.try_emplace(resourceName, resourceManager->Create(logicalDeviceHdl, swapchainHdl, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags)); + graphResources.try_emplace(resourceName, resourceManager->Create(renderGraphStorage, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags)); } /***************************************************************************/ @@ -343,10 +344,15 @@ namespace SHADE */ /***************************************************************************/ - void SHRenderGraph::Init(Handle const& logicalDevice, Handle const& swapchain) noexcept + void SHRenderGraph::Init(Handle logicalDevice, Handle swapchain) noexcept { - logicalDeviceHdl = logicalDevice; - swapchainHdl = swapchain; + renderGraphStorage = resourceManager->Create(); + + renderGraphStorage->logicalDevice = logicalDevice; + renderGraphStorage->swapchain = swapchain; + + renderGraphStorage->resourceManager = resourceManager; + renderGraphStorage->descriptorPool = logicalDevice->CreateDescriptorPools(); } /***************************************************************************/ @@ -361,8 +367,7 @@ namespace SHADE */ /***************************************************************************/ SHRenderGraph::SHRenderGraph(void) noexcept - : logicalDeviceHdl{ } - , swapchainHdl{ } + : renderGraphStorage{} , nodes{} , graphResources{} , resourceManager{nullptr} @@ -371,8 +376,7 @@ namespace SHADE } SHRenderGraph::SHRenderGraph(SHRenderGraph&& rhs) noexcept - : logicalDeviceHdl{ rhs.logicalDeviceHdl } - , swapchainHdl{ rhs.swapchainHdl } + : renderGraphStorage{ rhs.renderGraphStorage } , nodeIndexing{ std::move(rhs.nodeIndexing) } , nodes{ std::move(rhs.nodes) } , graphResources{ std::move(rhs.graphResources) } @@ -386,8 +390,7 @@ namespace SHADE if (&rhs == this) return *this; - logicalDeviceHdl = rhs.logicalDeviceHdl; - swapchainHdl = rhs.swapchainHdl; + renderGraphStorage = rhs.renderGraphStorage; nodeIndexing = std::move(rhs.nodeIndexing); nodes = std::move(rhs.nodes); graphResources = std::move(rhs.graphResources); @@ -456,7 +459,7 @@ namespace SHADE } } - nodes.emplace_back(resourceManager->Create(resourceManager, logicalDeviceHdl, swapchainHdl, std::move(descInitParams), std::move(predecessors), &graphResources)); + nodes.emplace_back(resourceManager->Create(renderGraphStorage, std::move(descInitParams), std::move(predecessors), &graphResources)); nodeIndexing.emplace(nodeName, static_cast(nodes.size()) - 1u); return nodes.at(nodeIndexing[nodeName]); } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h index 952c6d8f..9dbfa6d3 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h @@ -30,7 +30,8 @@ namespace SHADE class SHVkCommandBuffer; class SHRenderGraphNode; class SHGraphicsGlobalData; - + class SHVkDescriptorPool; + class SHRenderGraphStorage; class SH_API SHRenderGraph { @@ -56,10 +57,12 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER VARIABLES */ /*-----------------------------------------------------------------------*/ - Handle logicalDeviceHdl; + //Handle logicalDeviceHdl; //! swapchain used for querying image count - Handle swapchainHdl; + //Handle swapchainHdl; + + Handle renderGraphStorage; //! For indexing render graph node container std::map nodeIndexing; @@ -85,7 +88,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* PUBLIC MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ - void Init (Handle const& logicalDevice, Handle const& swapchain) noexcept; + void Init (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/SHRenderGraphNode.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp index ec184386..f9b3c42d 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp @@ -6,6 +6,7 @@ #include "Graphics/Framebuffer/SHVkFramebuffer.h" #include "SHRenderGraphResource.h" #include "SHSubpass.h" +#include "SHRenderGraphStorage.h" namespace SHADE { @@ -21,7 +22,7 @@ namespace SHADE /***************************************************************************/ void SHRenderGraphNode::CreateRenderpass(void) noexcept { - renderpass = logicalDeviceHdl->CreateRenderpass(attachmentDescriptions, spDescs, spDeps); + renderpass = graphStorage->logicalDevice->CreateRenderpass(attachmentDescriptions, spDescs, spDeps); } /***************************************************************************/ @@ -53,7 +54,7 @@ namespace SHADE } - framebuffers[i] = logicalDeviceHdl->CreateFramebuffer(renderpass, imageViews, fbWidth, fbHeight); + framebuffers[i] = graphStorage->logicalDevice->CreateFramebuffer(renderpass, imageViews, fbWidth, fbHeight); } } @@ -104,8 +105,8 @@ namespace SHADE */ /***************************************************************************/ - SHRenderGraphNode::SHRenderGraphNode(std::shared_ptr rm, Handle const& logicalDevice, Handle const& swapchain, std::vector attDescInitParams, std::vector> predecessors, std::unordered_map> const* resources) noexcept - : logicalDeviceHdl{ logicalDevice } + SHRenderGraphNode::SHRenderGraphNode(Handle renderGraphStorage, std::vector attDescInitParams, std::vector> predecessors, std::unordered_map> const* resources) noexcept + : graphStorage{ renderGraphStorage} , renderpass{} , framebuffers{} , prereqNodes{ std::move(predecessors) } @@ -115,11 +116,10 @@ namespace SHADE , subpasses{} , executed{ false } , configured{ false } - , resourceManager{ rm } , ptrToResources{ resources } { // pipeline library initialization - pipelineLibrary.Init(logicalDeviceHdl); + pipelineLibrary.Init(graphStorage->logicalDevice); // Store all the handles to resources attResources.reserve (attDescInitParams.size()); @@ -155,15 +155,14 @@ namespace SHADE if (!containsSwapchainImage) framebuffers.resize(1); else - framebuffers.resize(swapchain->GetNumImages()); + framebuffers.resize(graphStorage->swapchain->GetNumImages()); // At this point, we could configure framebuffers if we had the renderpass object but we don't so their creation has to be // deferred to when renderpasses are also created. } SHRenderGraphNode::SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept - : resourceManager{ std::move (rhs.resourceManager) } - , logicalDeviceHdl{ rhs.logicalDeviceHdl } + : graphStorage{ rhs.graphStorage} , renderpass{ rhs.renderpass } , framebuffers{ std::move(rhs.framebuffers) } , prereqNodes{ std::move(rhs.prereqNodes) } @@ -189,8 +188,7 @@ namespace SHADE if (&rhs == this) return *this; - resourceManager = std::move(rhs.resourceManager); - logicalDeviceHdl = rhs.logicalDeviceHdl; + graphStorage = rhs.graphStorage; renderpass = rhs.renderpass; framebuffers = std::move(rhs.framebuffers); prereqNodes = std::move(rhs.prereqNodes); @@ -235,10 +233,10 @@ namespace SHADE } // Add subpass to container and create mapping for it - subpasses.emplace_back(resourceManager->Create(GetHandle(), subpasses.size(), &resourceAttachmentMapping, ptrToResources)); + subpasses.emplace_back(graphStorage->resourceManager->Create(GetHandle(), subpasses.size(), &resourceAttachmentMapping, ptrToResources)); subpassIndexing.try_emplace(subpassName, static_cast(subpasses.size()) - 1u); Handle subpass = subpasses.back(); - subpass->Init(*resourceManager); + subpass->Init(*graphStorage->resourceManager); // Register the SuperBatch batcher.RegisterSuperBatch(subpass->GetSuperBatch()); @@ -273,10 +271,10 @@ namespace SHADE } - Handle pipeline = pipelineLibrary.GetDrawPipline(vsFsPair); + Handle pipeline = pipelineLibrary.GetGraphicsPipeline(vsFsPair); if (!pipeline) { - pipeline = pipelineLibrary.CreateDrawPipeline + pipeline = pipelineLibrary.CreateGraphicsPipelines ( vsFsPair, renderpass, @@ -289,7 +287,7 @@ namespace SHADE void SHRenderGraphNode::FinaliseBatch(uint32_t frameIndex, Handle descPool) { - batcher.FinaliseBatches(logicalDeviceHdl, descPool, frameIndex); + batcher.FinaliseBatches(graphStorage->logicalDevice, descPool, frameIndex); } /***************************************************************************/ diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h index 77861108..04638c37 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h @@ -19,6 +19,8 @@ namespace SHADE class SHVkLogicalDevice; class SHVkRenderpass; class SHVkDescriptorPool; + class SHGraphicsGlobalData; + class SHRenderGraphStorage; class SH_API SHRenderGraphNode : public ISelfHandle { @@ -26,10 +28,9 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER VARIABLES */ /*-----------------------------------------------------------------------*/ - std::shared_ptr resourceManager; - //! For Vulkan object creation - Handle logicalDeviceHdl; + //Handle logicalDeviceHdl; + Handle graphStorage; //! Each node will have a renderpass and each renderpass will have its own subpasses. //! These subpasses will execute sequentially. @@ -88,7 +89,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* CTORS AND DTORS */ /*-----------------------------------------------------------------------*/ - SHRenderGraphNode(std::shared_ptr rm, Handle const& logicalDevice, Handle const& swapchain, std::vector attDescInitParams, std::vector> predecessors, std::unordered_map> const* resources) noexcept; + SHRenderGraphNode(Handle renderGraphStorage, std::vector attDescInitParams, std::vector> predecessors, std::unordered_map> const* resources) noexcept; SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept; SHRenderGraphNode& operator= (SHRenderGraphNode&& rhs) noexcept; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp index adf3b6cd..3d05f466 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp @@ -5,6 +5,7 @@ #include "Graphics/Images/SHVkImageView.h" #include "Graphics/Buffers/SHVkBuffer.h" #include "Graphics/SHVkUtil.h" +#include "SHRenderGraphStorage.h" namespace SHADE { @@ -45,7 +46,7 @@ namespace SHADE */ /***************************************************************************/ - SHRenderGraphResource::SHRenderGraphResource(Handle const& logicalDevice, Handle const& swapchain, std::string const& name, std::initializer_list typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept + SHRenderGraphResource::SHRenderGraphResource(Handle graphStorage, std::string const& name, std::initializer_list typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept : logicalDevice {logicalDevice} , swapchain{ swapchain } , resourceTypeFlags{ } @@ -75,13 +76,13 @@ namespace SHADE }; // We want an image handle for every swapchain image - images.resize(swapchain->GetNumImages()); - imageViews.resize(swapchain->GetNumImages()); + images.resize(graphStorage->swapchain->GetNumImages()); + imageViews.resize(graphStorage->swapchain->GetNumImages()); - for (uint32_t i = 0; i < swapchain->GetNumImages(); ++i) + for (uint32_t i = 0; i < graphStorage->swapchain->GetNumImages(); ++i) { - images[i] = swapchain->GetSwapchainImage(i); - imageViews[i] = images[i]->CreateImageView(logicalDevice, images[i], viewDetails); + images[i] = graphStorage->swapchain->GetSwapchainImage(i); + imageViews[i] = images[i]->CreateImageView(graphStorage->logicalDevice, images[i], viewDetails); } } else // if swapchain image resource @@ -126,7 +127,7 @@ namespace SHADE } // The resource is not a swapchain image, just use the first slot of the vector - images.push_back(logicalDevice->CreateImage(width, height, mipLevels, resourceFormat, usage, createFlags)); + images.push_back(graphStorage->logicalDevice->CreateImage(width, height, mipLevels, resourceFormat, usage, createFlags)); // prepare image view details SHImageViewDetails viewDetails @@ -141,7 +142,7 @@ namespace SHADE }; // just 1 image view created - imageViews.push_back(images[0]->CreateImageView(logicalDevice, images[0], viewDetails)); + imageViews.push_back(images[0]->CreateImageView(graphStorage->logicalDevice, images[0], viewDetails)); } } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h index efaf9bf5..e11f6ed8 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h @@ -15,6 +15,7 @@ namespace SHADE class SHVkSwapchain; class SHVkCommandBuffer; class SHVkBuffer; + class SHRenderGraphStorage; static constexpr uint32_t NON_SWAPCHAIN_RESOURCE_INDEX = 0; @@ -69,7 +70,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* CTORS AND DTORS */ /*-----------------------------------------------------------------------*/ - SHRenderGraphResource(Handle const& logicalDevice, Handle const& swapchain, std::string const& name, std::initializer_list typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept; + SHRenderGraphResource(Handle graphStorage, std::string const& name, std::initializer_list typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept; SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept; SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept; ~SHRenderGraphResource(void) noexcept; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h new file mode 100644 index 00000000..9fcc4528 --- /dev/null +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h @@ -0,0 +1,33 @@ +#pragma once + +#include "Resource/Handle.h" +#include + +namespace SHADE +{ + class SHVkLogicalDevice; + class SHVkSwapchain; + class SHGraphicsGlobalData; + class SHVkDescriptorPool; + + class SHRenderGraphStorage + { + //! Logical device for creation of vulkan objects + Handle logicalDevice; + + //! swapchain hdl + Handle swapchain; + + //! Resource manager for creation of objects + std::shared_ptr resourceManager; + + //! Descriptor pool for the descriptor sets to be created in the subpasses + Handle descriptorPool; + + friend class SHRenderGraph; + friend class SHRenderGraphNode; + friend class SHSubpass; + friend class SHRenderGraphResource; + friend class SHSubpassCompute; + }; +} diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp index ffbe4ff0..9926fc2f 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp @@ -4,6 +4,10 @@ #include "Graphics/Devices/SHVkLogicalDevice.h" #include "SHRenderGraphNode.h" #include "SHRenderGraphResource.h" +#include "Graphics/Shaders/SHVkShaderModule.h" +#include "SHRenderGraphNode.h" +#include "SHRenderGraphStorage.h" +#include "Graphics/RenderGraph/SHSubpassCompute.h" namespace SHADE { @@ -23,7 +27,7 @@ namespace SHADE */ /***************************************************************************/ - SHSubpass::SHSubpass(Handle const& parent, uint32_t index, std::unordered_map const* mapping, std::unordered_map> const* resources) noexcept + SHSubpass::SHSubpass(Handle renderGraphStorage, Handle const& parent, uint32_t index, std::unordered_map const* mapping, std::unordered_map> const* resources) noexcept : resourceAttachmentMapping{ mapping } , ptrToResources{ resources } , parentNode{ parent } @@ -32,6 +36,7 @@ namespace SHADE , colorReferences{} , depthReferences{} , inputReferences{} + , graphStorage{ renderGraphStorage } { } @@ -56,7 +61,8 @@ namespace SHADE , resourceAttachmentMapping{ rhs.resourceAttachmentMapping } , ptrToResources{ rhs.ptrToResources } , descriptorSetLayout{ rhs.descriptorSetLayout } - , exteriorDrawCalls{ std::move (rhs.exteriorDrawCalls) } + , exteriorDrawCalls{ std::move(rhs.exteriorDrawCalls) } + , graphStorage{ std::move(rhs.graphStorage) } { } @@ -87,6 +93,7 @@ namespace SHADE ptrToResources = rhs.ptrToResources; descriptorSetLayout = rhs.descriptorSetLayout; exteriorDrawCalls = std::move(rhs.exteriorDrawCalls); + graphStorage = std::move(rhs.graphStorage); return *this; } @@ -182,6 +189,11 @@ namespace SHADE exteriorDrawCalls.push_back(newDrawCall); } + Handle SHSubpass::ActivateSubpassCompute(Handle computeShaderModule, std::initializer_list resources) noexcept + { + //subpassCompute = graphStorage->resourceManager->Create(, parentNode->GetGraphDescPool(), resources); + } + void SHSubpass::Init(ResourceManager& resourceManager) noexcept { superBatch = resourceManager.Create(GetHandle()); diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h index c567a897..71496b92 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h @@ -15,6 +15,9 @@ namespace SHADE class SHVkCommandBuffer; class SHVkDescriptorSetLayout; class SHVkDescriptorPool; + class SHRenderGraphStorage; + class SHSubpassCompute; + class SHVkShaderModule; class SH_API SHSubpass : public ISelfHandle { @@ -22,6 +25,8 @@ namespace SHADE /*---------------------------------------------------------------------*/ /* PRIVATE MEMBER VARIABLES */ /*---------------------------------------------------------------------*/ + Handle graphStorage; + //! The index of the subpass in the render graph uint32_t subpassIndex; @@ -49,6 +54,10 @@ namespace SHADE //! Pointer to resources in the render graph (for getting handle IDs) std::unordered_map> const* ptrToResources; + //! Sometimes we want the subpass to do something to the images instead + //! of drawing objects on the image (i.e. compute). + Handle subpassCompute; + //! Sometimes there exists entities that we want to render onto a render target //! but don't want it to come from the batching system. An example would be ImGUI. //! For these entities we want to link a function from the outside and draw them @@ -62,7 +71,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* CTORS AND DTORS */ /*-----------------------------------------------------------------------*/ - SHSubpass(Handle const& parent, uint32_t index, std::unordered_map const* mapping, std::unordered_map> const* ptrToResources) noexcept; + SHSubpass(Handle renderGraphStorage, Handle const& parent, uint32_t index, std::unordered_map const* mapping, std::unordered_map> const* ptrToResources) noexcept; SHSubpass(SHSubpass&& rhs) noexcept; SHSubpass& operator=(SHSubpass&& rhs) noexcept; @@ -78,6 +87,8 @@ namespace SHADE void Execute(Handle& commandBuffer, Handle descPool, uint32_t frameIndex) noexcept; void AddExteriorDrawCalls(std::function&)> const& newDrawCall) noexcept; + Handle ActivateSubpassCompute(Handle computeShaderModule, std::initializer_list resources) noexcept; + void Init(ResourceManager& resourceManager) noexcept; /*-----------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp index ccd0e6c3..722e7e4f 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp @@ -3,21 +3,32 @@ #include "Graphics/Pipeline/SHVkPipeline.h" #include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" #include "Graphics/Descriptors/SHVkDescriptorPool.h" +#include "Graphics/Devices/SHVkLogicalDevice.h" +#include "Graphics/Pipeline/SHVkPipelineLayout.h" +#include "SHRenderGraphStorage.h" +//#include "" namespace SHADE { - SHSubpassCompute::SHSubpassCompute(Handle inPipeline, Handle descPool) noexcept - : pipeline {inPipeline} + SHSubpassCompute::SHSubpassCompute(Handle graphStorage, Handle computeShaderModule, std::initializer_list resources) noexcept + : pipeline{} { + SHPipelineLayoutParams pipelineLayoutParams + { + //.globalDescSetLayouts + }; + + //pipeline = logicalDevice->CreateComputePipeline() + // Get the descriptor set layouts required to allocate. we will bind a different pipeline layout, one that includes the layout for global. auto const& layouts = pipeline->GetPipelineLayout()->GetDescriptorSetLayoutsAllocate(); // Variable counts for the descriptor sets (all should be 1). - std::vector variableCounts{static_cast(layouts.size())}; - std::fill (variableCounts.begin(), variableCounts.end(), 0); + std::vector variableCounts{ static_cast(layouts.size()) }; + std::fill(variableCounts.begin(), variableCounts.end(), 0); // Allocate descriptor sets to hold the images for reading (STORAGE_IMAGE) - descPool->Allocate(layouts, variableCounts); + descSetGroup = graphStorage->descriptorPool->Allocate(layouts, variableCounts); } } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.h b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.h index 3ebc5676..8dfc361e 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.h @@ -1,24 +1,36 @@ #pragma once -#include +#include "Resource/Handle.h" +#include +#include namespace SHADE { class SHVkPipeline; class SHVkDescriptorSetGroup; class SHVkDescriptorPool; + class SHVkLogicalDevice; + class SHVkPipelineLayout; + class SHRenderGraphStorage; + class SHVkShaderModule; class SHSubpassCompute { private: //! To run the dispatch command - Handle pipeline; + Handle pipeline; - //! Descriptor set group + //! Pipeline layout for the pipline creation + Handle pipelineLayout; + + //! Descriptor set group to hold the images for reading (STORAGE_IMAGE) Handle descSetGroup; - + + //! Required resources to be used in the descriptors + std::vector resourcesRequired; + public: - SHSubpassCompute (Handle inPipeline, Handle descPool) noexcept; + SHSubpassCompute(Handle graphStorage, Handle computeShaderModule, std::initializer_list resources) noexcept; }; } From fda33f7461087c84299a6afcac050a22e1ee81ac Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 20 Oct 2022 22:55:59 +0800 Subject: [PATCH 06/50] Fixed multi-level transform updates --- SHADE_Application/src/Scenes/SBTestScene.cpp | 2 +- .../src/Math/Transform/SHTransformSystem.cpp | 87 +++++++++++++++---- .../src/Math/Transform/SHTransformSystem.h | 7 +- SHADE_Engine/src/Scene/SHSceneGraph.cpp | 12 +-- SHADE_Engine/src/Scene/SHSceneGraph.h | 6 +- 5 files changed, 84 insertions(+), 30 deletions(-) diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index d81550e1..be09768b 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -78,7 +78,7 @@ namespace Sandbox // Create Stress Test Objects static const SHVec3 TEST_OBJ_SCALE = SHVec3::One; - constexpr int NUM_ROWS = 2; + constexpr int NUM_ROWS = 3; constexpr int NUM_COLS = 1; static const SHVec3 TEST_OBJ_SPACING = { 0.1f, 0.1f, 0.1f }; static const SHVec3 TEST_OBJ_START_POS = { -(NUM_COLS / 2 * TEST_OBJ_SPACING.x) + 1.0f, -2.0f, -1.0f }; diff --git a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp index 448fa60d..a3ca3e75 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp +++ b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp @@ -64,17 +64,18 @@ namespace SHADE { const auto& eventData = reinterpret_cast*>(changeParentEvent.get()); - // Get Current Respective Components - auto* tf = SHComponentManager::GetComponent(eventData->data->entityID); - const auto* PARENT = SHComponentManager::GetComponent_s(eventData->data->newParentID); + auto* node = eventData->data->node; + auto* tf = SHComponentManager::GetComponent_s(node->GetEntityID()); // Recompute local transform and store localToWorld Matrix SHMatrix localToWorld = SHMatrix::Identity; SHMatrix worldToLocal = SHMatrix::Identity; - if (PARENT != nullptr) // Not the root + auto* newParent = eventData->data->newParent; + const auto* PARENT_TF = SHComponentManager::GetComponent_s(newParent->GetEntityID()); + if (PARENT_TF != nullptr) // Not the root { - localToWorld = PARENT->GetTRS(); + localToWorld = PARENT_TF->GetTRS(); worldToLocal = SHMatrix::Inverse(localToWorld); } @@ -83,21 +84,74 @@ namespace SHADE // Compute Local Position tf->local.position = SHVec3::Transform(tf->world.position, worldToLocal); - // Compute Local Rotation - tf->local.rotation = tf->world.rotation; - if (PARENT) - tf->local.rotation -= PARENT->GetLocalRotation(); + + tf->local.rotation = tf->world.rotation; + tf->local.scale = tf->world.scale; - // Compute Local Scale - tf->local.scale = tf->world.scale; - if (PARENT) - tf->local.scale /= PARENT->GetLocalScale(); + if (PARENT_TF != nullptr) + { + // Compute Local Rotation + tf->local.rotation -= PARENT_TF->GetLocalRotation(); + + // Compute Local Scale + tf->local.scale /= PARENT_TF->GetLocalScale(); + } tf->local.trs = localToWorld; + // Propagate maintaining world transform down the branch + UpdateChildrenLocalTransforms(node); return eventData->handle; } + void SHTransformSystem::UpdateChildrenLocalTransforms(SHSceneNode* node) + { + // Structure is similar to update entity, albeit without a queue to do being a forced update + for (const auto* child : node->GetChildren()) + { + if (auto* childTransform = SHComponentManager::GetComponent_s(child->GetEntityID()); childTransform) + { + const bool IS_NODE_ACTIVE = child->IsActive(); + if (IS_NODE_ACTIVE && childTransform->isActive) + { + // Recompute local transform and store localToWorld Matrix + SHMatrix localToWorld = SHMatrix::Identity; + SHMatrix worldToLocal = SHMatrix::Identity; + + const auto* parent = SHComponentManager::GetComponent_s(node->GetEntityID()); + + if (parent != nullptr) // Not the root + { + localToWorld = parent->GetTRS(); + worldToLocal = SHMatrix::Inverse(localToWorld); + } + + // Maintain World Transform and recompute Local Transform + + // Compute Local Position + childTransform->local.position = SHVec3::Transform(childTransform->world.position, worldToLocal); + + + childTransform->local.rotation = childTransform->world.rotation; + childTransform->local.scale = childTransform->world.scale; + + if (parent) + { + // Compute Local Rotation + childTransform->local.rotation -= parent->GetLocalRotation(); + + // Compute Local Scale + childTransform->local.scale /= parent->GetLocalScale(); + } + + childTransform->local.trs = localToWorld; + } + } + + + } + } + void SHTransformSystem::UpdateEntity(const SHSceneNode* node) { const auto* NODE_TRANSFORM = SHComponentManager::GetComponent_s(node->GetEntityID()); @@ -113,7 +167,10 @@ namespace SHADE if (IS_NODE_ACTIVE && childTransform->isActive) { if (childTransform->dirty || HAS_PARENT_CHANGED) + { UpdateTransform(*childTransform, NODE_TRANSFORM); + childTransform->dirty = true; + } } } @@ -177,10 +234,6 @@ namespace SHADE tf.world.scale = tf.local.scale * (parent ? parent->GetLocalScale() : SHVec3::One); tf.world.ComputeTRS(); - - // Transpose TRS to column major - //tf.local.trs.Transpose(); - //tf.world.trs.Transpose(); } } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Math/Transform/SHTransformSystem.h b/SHADE_Engine/src/Math/Transform/SHTransformSystem.h index 8a50b368..95957830 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformSystem.h +++ b/SHADE_Engine/src/Math/Transform/SHTransformSystem.h @@ -84,10 +84,11 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ - SHEventHandle ChangeParent (SHEventPtr changeParentEvent); + SHEventHandle ChangeParent (SHEventPtr changeParentEvent); + static void UpdateChildrenLocalTransforms (SHSceneNode* node); - static void UpdateEntity (const SHSceneNode* node); - static void UpdateTransform (SHTransformComponent& tf, const SHTransformComponent* parent = nullptr); + static void UpdateEntity (const SHSceneNode* node); + static void UpdateTransform (SHTransformComponent& tf, const SHTransformComponent* parent = nullptr); }; diff --git a/SHADE_Engine/src/Scene/SHSceneGraph.cpp b/SHADE_Engine/src/Scene/SHSceneGraph.cpp index ac6975fb..950fd6a0 100644 --- a/SHADE_Engine/src/Scene/SHSceneGraph.cpp +++ b/SHADE_Engine/src/Scene/SHSceneGraph.cpp @@ -367,9 +367,9 @@ namespace SHADE const SHSceneGraphChangeParentEvent EVENT_DATA { - .entityID = entityID - , .oldParentID = NODE_ITER->second->GetParent()->GetEntityID() - , .newParentID = parent ? parent->GetEntityID() : root->GetEntityID() + .node = NODE_ITER->second + , .oldParent = NODE_ITER->second->GetParent() + , .newParent = parent ? parent : root }; if (parent == nullptr) @@ -413,9 +413,9 @@ namespace SHADE const SHSceneGraphChangeParentEvent EVENT_DATA { - .entityID = entityID - , .oldParentID = NODE_ITER->second->GetParent()->GetEntityID() - , .newParentID = parent + .node = NODE_ITER->second + , .oldParent = NODE_ITER->second->GetParent() + , .newParent = PARENT_ITER->second }; SHSceneNode* currentNode = NODE_ITER->second; diff --git a/SHADE_Engine/src/Scene/SHSceneGraph.h b/SHADE_Engine/src/Scene/SHSceneGraph.h index 1dfc1542..a4cf45eb 100644 --- a/SHADE_Engine/src/Scene/SHSceneGraph.h +++ b/SHADE_Engine/src/Scene/SHSceneGraph.h @@ -163,9 +163,9 @@ namespace SHADE struct SHSceneGraphChangeParentEvent { - EntityID entityID; - EntityID oldParentID; - EntityID newParentID; + SHSceneNode* node; + SHSceneNode* oldParent; + SHSceneNode* newParent; }; } // namespace SHADE \ No newline at end of file From a52f0ddeed7f7090a21567daeb85c366437bd2d5 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Fri, 21 Oct 2022 00:08:24 +0800 Subject: [PATCH 07/50] Added a degree getter and setter for rotation --- Assets/Editor/Layouts/UserLayout.ini | 2 +- .../Math/Transform/SHTransformComponent.cpp | 64 ++++++++++++++++++- .../src/Math/Transform/SHTransformComponent.h | 42 ++++++------ 3 files changed, 86 insertions(+), 22 deletions(-) diff --git a/Assets/Editor/Layouts/UserLayout.ini b/Assets/Editor/Layouts/UserLayout.ini index 7b0a70f8..396b853b 100644 --- a/Assets/Editor/Layouts/UserLayout.ini +++ b/Assets/Editor/Layouts/UserLayout.ini @@ -38,7 +38,7 @@ Collapsed=0 DockId=0x00000002,0 [Docking][Data] -DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,79 Size=1920,1012 Split=X +DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=-227,-1256 Size=1920,1012 Split=X DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1481,1036 Split=X DockNode ID=0x00000001 Parent=0x00000005 SizeRef=349,1036 Split=Y Selected=0x1E6EB881 DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,94 Selected=0x1E6EB881 diff --git a/SHADE_Engine/src/Math/Transform/SHTransformComponent.cpp b/SHADE_Engine/src/Math/Transform/SHTransformComponent.cpp index 949cfa67..a8b75497 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformComponent.cpp +++ b/SHADE_Engine/src/Math/Transform/SHTransformComponent.cpp @@ -12,6 +12,8 @@ // Primary Header #include "SHTransformComponent.h" +// Project Headers +#include "Math/SHMathHelpers.h" namespace SHADE { @@ -43,6 +45,15 @@ namespace SHADE return local.rotation; } + SHVec3 SHTransformComponent::GetLocalRotationDeg() const noexcept + { + SHVec3 rot = local.rotation; + rot.x = SHMath::RadiansToDegrees(rot.x); + rot.y = SHMath::RadiansToDegrees(rot.y); + rot.z = SHMath::RadiansToDegrees(rot.z); + return rot; + } + const SHVec3& SHTransformComponent::GetLocalScale() const noexcept { return local.scale; @@ -58,6 +69,15 @@ namespace SHADE return world.rotation; } + SHVec3 SHTransformComponent::GetWorldRotationDeg() const noexcept + { + SHVec3 rot = world.rotation; + rot.x = SHMath::RadiansToDegrees(rot.x); + rot.y = SHMath::RadiansToDegrees(rot.y); + rot.z = SHMath::RadiansToDegrees(rot.z); + return rot; + } + const SHVec3& SHTransformComponent::GetWorldScale() const noexcept { return world.scale; @@ -94,6 +114,15 @@ namespace SHADE local.rotation = newLocalRotation; } + void SHTransformComponent::SetLocalRotationDeg(SHVec3 newLocalRotationDeg) noexcept + { + dirty = true; + + local.rotation.x = SHMath::DegreesToRadians(newLocalRotationDeg.x); + local.rotation.y = SHMath::DegreesToRadians(newLocalRotationDeg.y); + local.rotation.z = SHMath::DegreesToRadians(newLocalRotationDeg.z); + } + void SHTransformComponent::SetLocalRotation(float pitch, float yaw, float roll) noexcept { dirty = true; @@ -103,6 +132,13 @@ namespace SHADE local.rotation.z = roll; } + void SHTransformComponent::SetLocalRotationDeg(float pitch, float yaw, float roll) noexcept + { + local.rotation.x = SHMath::DegreesToRadians(pitch); + local.rotation.y = SHMath::DegreesToRadians(yaw); + local.rotation.z = SHMath::DegreesToRadians(roll); + } + void SHTransformComponent::SetLocalScale(const SHVec3& newLocalScale) noexcept { dirty = true; @@ -125,6 +161,17 @@ namespace SHADE updateQueue.push({ UpdateCommandType::WORLD_ROTATION, newWorldRotation }); } + void SHTransformComponent::SetWorldRotationDeg(const SHVec3& newWorldRotation) noexcept + { + dirty = true; + + world.rotation.x = SHMath::DegreesToRadians(newWorldRotation.x); + world.rotation.y = SHMath::DegreesToRadians(newWorldRotation.y); + world.rotation.z = SHMath::DegreesToRadians(newWorldRotation.z); + + updateQueue.push({ UpdateCommandType::WORLD_ROTATION, world.rotation }); + } + void SHTransformComponent::SetWorldRotation(float pitch, float yaw, float roll) noexcept { dirty = true; @@ -136,6 +183,17 @@ namespace SHADE updateQueue.push({ UpdateCommandType::WORLD_ROTATION, SHVec3{ pitch, yaw, roll} }); } + void SHTransformComponent::SetWorldRotationDeg(float pitch, float yaw, float roll) noexcept + { + dirty = true; + + world.rotation.x = SHMath::DegreesToRadians(pitch); + world.rotation.y = SHMath::DegreesToRadians(yaw); + world.rotation.z = SHMath::DegreesToRadians(roll); + + updateQueue.push({ UpdateCommandType::WORLD_ROTATION, world.rotation }); + } + void SHTransformComponent::SetWorldScale(const SHVec3& newWorldScale) noexcept { dirty = true; @@ -152,7 +210,7 @@ RTTR_REGISTRATION using namespace rttr; registration::class_("Transform Component") - .property("Translate" , &SHTransformComponent::GetLocalPosition , &SHTransformComponent::SetLocalPosition ) - .property("Rotate" , &SHTransformComponent::GetLocalRotation , select_overload(&SHTransformComponent::SetLocalRotation) ) - .property("Scale" , &SHTransformComponent::GetLocalScale , &SHTransformComponent::SetLocalScale ); + .property("Translate" , &SHTransformComponent::GetLocalPosition , &SHTransformComponent::SetLocalPosition ) + .property("Rotate" , &SHTransformComponent::GetLocalRotationDeg, select_overload(&SHTransformComponent::SetLocalRotationDeg)) + .property("Scale" , &SHTransformComponent::GetLocalScale , &SHTransformComponent::SetLocalScale ); } \ No newline at end of file diff --git a/SHADE_Engine/src/Math/Transform/SHTransformComponent.h b/SHADE_Engine/src/Math/Transform/SHTransformComponent.h index ad355694..2a3fa7a0 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformComponent.h +++ b/SHADE_Engine/src/Math/Transform/SHTransformComponent.h @@ -56,32 +56,38 @@ namespace SHADE /* Getter Functions */ /*---------------------------------------------------------------------------------*/ - [[nodiscard]] bool HasChanged () const noexcept; + [[nodiscard]] bool HasChanged () const noexcept; - [[nodiscard]] const SHVec3& GetLocalPosition () const noexcept; - [[nodiscard]] const SHVec3& GetLocalRotation () const noexcept; - [[nodiscard]] const SHVec3& GetLocalScale () const noexcept; - [[nodiscard]] const SHVec3& GetWorldPosition () const noexcept; - [[nodiscard]] const SHVec3& GetWorldRotation () const noexcept; - [[nodiscard]] const SHVec3& GetWorldScale () const noexcept; + [[nodiscard]] const SHVec3& GetLocalPosition () const noexcept; + [[nodiscard]] const SHVec3& GetLocalRotation () const noexcept; + [[nodiscard]] SHVec3 GetLocalRotationDeg () const noexcept; + [[nodiscard]] const SHVec3& GetLocalScale () const noexcept; + [[nodiscard]] const SHVec3& GetWorldPosition () const noexcept; + [[nodiscard]] const SHVec3& GetWorldRotation () const noexcept; + [[nodiscard]] SHVec3 GetWorldRotationDeg () const noexcept; + [[nodiscard]] const SHVec3& GetWorldScale () const noexcept; - [[nodiscard]] const SHMatrix& GetLocalToWorld () const noexcept; - [[nodiscard]] SHMatrix GetWorldToLocal () const noexcept; + [[nodiscard]] const SHMatrix& GetLocalToWorld () const noexcept; + [[nodiscard]] SHMatrix GetWorldToLocal () const noexcept; - [[nodiscard]] const SHMatrix& GetTRS () const noexcept; + [[nodiscard]] const SHMatrix& GetTRS () const noexcept; /*---------------------------------------------------------------------------------*/ /* Setter Functions */ /*---------------------------------------------------------------------------------*/ - void SetLocalPosition (const SHVec3& newLocalPosition) noexcept; - void SetLocalRotation (const SHVec3& newLocalRotation) noexcept; - void SetLocalRotation (float pitch, float yaw, float roll) noexcept; - void SetLocalScale (const SHVec3& newLocalScale) noexcept; - void SetWorldPosition (const SHVec3& newWorldPosition) noexcept; - void SetWorldRotation (const SHVec3& newWorldRotation) noexcept; - void SetWorldRotation (float pitch, float yaw, float roll) noexcept; - void SetWorldScale (const SHVec3& newWorldScale) noexcept; + void SetLocalPosition (const SHVec3& newLocalPosition) noexcept; + void SetLocalRotation (const SHVec3& newLocalRotation) noexcept; + void SetLocalRotationDeg (SHVec3 newLocalRotationDeg) noexcept; + void SetLocalRotation (float pitch, float yaw, float roll) noexcept; + void SetLocalRotationDeg (float pitch, float yaw, float roll) noexcept; + void SetLocalScale (const SHVec3& newLocalScale) noexcept; + void SetWorldPosition (const SHVec3& newWorldPosition) noexcept; + void SetWorldRotation (const SHVec3& newWorldRotation) noexcept; + void SetWorldRotationDeg (const SHVec3& newWorldRotation) noexcept; + void SetWorldRotation (float pitch, float yaw, float roll) noexcept; + void SetWorldRotationDeg (float pitch, float yaw, float roll) noexcept; + void SetWorldScale (const SHVec3& newWorldScale) noexcept; private: /*---------------------------------------------------------------------------------*/ From c252e4ce4b7591da5eafa04a02329d32f20e06b1 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Fri, 21 Oct 2022 07:01:51 +0800 Subject: [PATCH 08/50] Some restructuring with render graph storage. Lesser parameters passed around. --- Assets/Editor/Layouts/UserLayout.ini | 20 +++++++++---------- .../Descriptors/SHVkDescriptorPool.cpp | 3 ++- .../RenderGraph/SHRenderGraphNode.cpp | 2 +- .../RenderGraph/SHRenderGraphResource.cpp | 17 ++++++++-------- .../RenderGraph/SHRenderGraphResource.h | 9 +++------ .../src/Graphics/RenderGraph/SHSubpass.cpp | 3 ++- 6 files changed, 26 insertions(+), 28 deletions(-) diff --git a/Assets/Editor/Layouts/UserLayout.ini b/Assets/Editor/Layouts/UserLayout.ini index 33b4ccfd..530ee770 100644 --- a/Assets/Editor/Layouts/UserLayout.ini +++ b/Assets/Editor/Layouts/UserLayout.ini @@ -1,16 +1,16 @@ [Window][MainStatusBar] -Pos=0,1389 -Size=2547,20 +Pos=0,1060 +Size=1920,20 Collapsed=0 [Window][SHEditorMenuBar] Pos=0,48 -Size=2547,1341 +Size=1920,1012 Collapsed=0 [Window][Hierarchy Panel] -Pos=0,172 -Size=571,1217 +Pos=0,142 +Size=571,918 Collapsed=0 DockId=0x00000004,0 @@ -20,25 +20,25 @@ Size=400,400 Collapsed=0 [Window][Inspector] -Pos=2276,48 -Size=271,1341 +Pos=1649,48 +Size=271,1012 Collapsed=0 DockId=0x00000006,0 [Window][Profiler] Pos=0,48 -Size=571,122 +Size=571,92 Collapsed=0 DockId=0x00000003,0 [Window][Viewport] Pos=573,48 -Size=1701,1341 +Size=1074,1012 Collapsed=0 DockId=0x00000002,0 [Docking][Data] -DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,79 Size=2547,1341 Split=X +DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,79 Size=1920,1012 Split=X DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1992,1036 Split=X DockNode ID=0x00000001 Parent=0x00000005 SizeRef=571,1036 Split=Y Selected=0x1E6EB881 DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,94 Selected=0x1E6EB881 diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.cpp b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.cpp index 6b770c3d..e5618c9c 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.cpp +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.cpp @@ -25,7 +25,8 @@ namespace SHADE } SHVkDescriptorPool::SHVkDescriptorPool(SHVkDescriptorPool&& rhs) noexcept - : device{ rhs.device } + : ISelfHandle (rhs) + , device{ rhs.device } , pool{ rhs.pool } { rhs.pool = VK_NULL_HANDLE; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp index f9b3c42d..48855806 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp @@ -233,7 +233,7 @@ namespace SHADE } // Add subpass to container and create mapping for it - subpasses.emplace_back(graphStorage->resourceManager->Create(GetHandle(), subpasses.size(), &resourceAttachmentMapping, ptrToResources)); + subpasses.emplace_back(graphStorage->resourceManager->Create(graphStorage, GetHandle(), subpasses.size(), &resourceAttachmentMapping, ptrToResources)); subpassIndexing.try_emplace(subpassName, static_cast(subpasses.size()) - 1u); Handle subpass = subpasses.back(); subpass->Init(*graphStorage->resourceManager); diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp index 3d05f466..d3f20665 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp @@ -46,9 +46,8 @@ namespace SHADE */ /***************************************************************************/ - SHRenderGraphResource::SHRenderGraphResource(Handle graphStorage, std::string const& name, std::initializer_list typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept - : logicalDevice {logicalDevice} - , swapchain{ swapchain } + SHRenderGraphResource::SHRenderGraphResource(Handle renderGraphStorage, std::string const& name, std::initializer_list typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept + : graphStorage{renderGraphStorage} , resourceTypeFlags{ } , resourceFormat{ format } , images{} @@ -67,7 +66,7 @@ namespace SHADE SHImageViewDetails viewDetails { .viewType = vk::ImageViewType::e2D, - .format = swapchain->GetSurfaceFormatKHR().format, + .format = graphStorage->swapchain->GetSurfaceFormatKHR().format, .imageAspectFlags = vk::ImageAspectFlagBits::eColor, .baseMipLevel = 0, .mipLevelCount = 1, @@ -167,7 +166,7 @@ namespace SHADE , height{ rhs.height } , mipLevels{ rhs.mipLevels } , imageAspectFlags{ rhs.imageAspectFlags } - , swapchain {rhs.swapchain} + , graphStorage{rhs.graphStorage} { } @@ -199,7 +198,7 @@ namespace SHADE height = rhs.height; mipLevels = rhs.mipLevels; imageAspectFlags = rhs.imageAspectFlags; - swapchain = rhs.swapchain; + graphStorage = rhs.graphStorage; return *this; } @@ -248,7 +247,7 @@ namespace SHADE SHImageViewDetails viewDetails { .viewType = vk::ImageViewType::e2D, - .format = swapchain->GetSurfaceFormatKHR().format, + .format = graphStorage->swapchain->GetSurfaceFormatKHR().format, .imageAspectFlags = vk::ImageAspectFlagBits::eColor, .baseMipLevel = 0, .mipLevelCount = 1, @@ -256,9 +255,9 @@ namespace SHADE .layerCount = 1, }; - for (uint32_t i = 0; i < swapchain->GetNumImages(); ++i) + for (uint32_t i = 0; i < graphStorage->swapchain->GetNumImages(); ++i) { - images[i] = swapchain->GetSwapchainImage(i); + images[i] = graphStorage->swapchain->GetSwapchainImage(i); imageViews[i]->ViewNewImage(images[i], viewDetails); } } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h index e11f6ed8..4bdecc49 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h @@ -25,11 +25,8 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER VARIABLES */ /*-----------------------------------------------------------------------*/ - // for creation/recreation - Handle logicalDevice; - - // for creation/recreation - Handle swapchain; + //! Storage from the render graph + Handle graphStorage; //! Name of the resource std::string resourceName; @@ -70,7 +67,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* CTORS AND DTORS */ /*-----------------------------------------------------------------------*/ - SHRenderGraphResource(Handle graphStorage, std::string const& name, std::initializer_list typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept; + SHRenderGraphResource(Handle renderGraphStorage, std::string const& name, std::initializer_list typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept; SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept; SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept; ~SHRenderGraphResource(void) noexcept; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp index 9926fc2f..3daafb8f 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp @@ -191,7 +191,8 @@ namespace SHADE Handle SHSubpass::ActivateSubpassCompute(Handle computeShaderModule, std::initializer_list resources) noexcept { - //subpassCompute = graphStorage->resourceManager->Create(, parentNode->GetGraphDescPool(), resources); + subpassCompute = graphStorage->resourceManager->Create(graphStorage, computeShaderModule, resources); + return subpassCompute; } void SHSubpass::Init(ResourceManager& resourceManager) noexcept From e8073bb67fc368fdd4d5e79ff9d8c2d18ddc6238 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Fri, 21 Oct 2022 08:42:58 +0800 Subject: [PATCH 09/50] WIP --- SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp index 722e7e4f..f30fa85f 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp @@ -5,6 +5,7 @@ #include "Graphics/Descriptors/SHVkDescriptorPool.h" #include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/Pipeline/SHVkPipelineLayout.h" +#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" #include "SHRenderGraphStorage.h" //#include "" @@ -15,7 +16,7 @@ namespace SHADE { SHPipelineLayoutParams pipelineLayoutParams { - //.globalDescSetLayouts + .globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts() }; //pipeline = logicalDevice->CreateComputePipeline() From 9df517f3b30885d78c5ce63a5add0d002680d9b6 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Fri, 21 Oct 2022 20:28:54 +0800 Subject: [PATCH 10/50] SP3-170 SP3-238 Restructured asset and asset loading library types to be derived from common base class. Storage of assets and loaders based on pointers. Created general templated calls to get data from asset manager based on asset type passed in as template argument. More concise internal interface when loading and storing assets with libraries --- Assets/Cube.003.shmesh.shmeta | 2 +- Assets/Cube.012.shmesh.shmeta | 2 +- .../RaccoonPreTexturedVer1_Base9.shtex.shmeta | 2 +- SHADE_Application/src/Scenes/SBTestScene.cpp | 47 +- .../src/Assets/Asset Types/SHAnimationAsset.h | 4 +- .../src/Assets/Asset Types/SHAssetData.h | 19 + .../src/Assets/Asset Types/SHInternalAsset.h | 21 + .../src/Assets/Asset Types/SHMeshAsset.h | 6 +- .../src/Assets/Asset Types/SHTextureAsset.h | 3 +- .../src/Assets/Libraries/SHAssetLoader.h | 21 + .../src/Assets/Libraries/SHAssimpLibrary.cpp | 26 +- .../src/Assets/Libraries/SHAssimpLibrary.h | 6 +- .../src/Assets/Libraries/SHMeshCompiler.cpp | 2 +- .../src/Assets/Libraries/SHMeshLoader.cpp | 13 +- .../src/Assets/Libraries/SHMeshLoader.h | 6 +- .../src/Assets/Libraries/SHTextureLoader.cpp | 9 + .../src/Assets/Libraries/SHTextureLoader.h | 17 +- SHADE_Engine/src/Assets/SHAsset.h | 5 +- SHADE_Engine/src/Assets/SHAssetMacros.h | 51 ++- SHADE_Engine/src/Assets/SHAssetManager.cpp | 422 ++++-------------- SHADE_Engine/src/Assets/SHAssetManager.h | 80 ++-- .../src/Assets/SHAssetMetaHandler.cpp | 14 +- 22 files changed, 300 insertions(+), 478 deletions(-) create mode 100644 SHADE_Engine/src/Assets/Asset Types/SHAssetData.h create mode 100644 SHADE_Engine/src/Assets/Asset Types/SHInternalAsset.h create mode 100644 SHADE_Engine/src/Assets/Libraries/SHAssetLoader.h diff --git a/Assets/Cube.003.shmesh.shmeta b/Assets/Cube.003.shmesh.shmeta index d41be546..207f3999 100644 --- a/Assets/Cube.003.shmesh.shmeta +++ b/Assets/Cube.003.shmesh.shmeta @@ -1,3 +1,3 @@ Name: Cube.003 ID: 110152941 -Type:  +Type: 6 diff --git a/Assets/Cube.012.shmesh.shmeta b/Assets/Cube.012.shmesh.shmeta index d5cd1090..3af04f93 100644 --- a/Assets/Cube.012.shmesh.shmeta +++ b/Assets/Cube.012.shmesh.shmeta @@ -1,3 +1,3 @@ Name: Cube.012 ID: 107348815 -Type:  +Type: 6 diff --git a/Assets/RaccoonPreTexturedVer1_Base9.shtex.shmeta b/Assets/RaccoonPreTexturedVer1_Base9.shtex.shmeta index f8c267d9..3905aa4f 100644 --- a/Assets/RaccoonPreTexturedVer1_Base9.shtex.shmeta +++ b/Assets/RaccoonPreTexturedVer1_Base9.shtex.shmeta @@ -1,3 +1,3 @@ Name: RaccoonPreTexturedVer1_Base9 ID: 91918845 -Type:  +Type: 4 diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index f1d656ee..50a87fd3 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -13,6 +13,9 @@ #include "Physics/Components/SHRigidBodyComponent.h" #include "Physics/Components/SHColliderComponent.h" +#include "Assets/Asset Types/SHMeshAsset.h" +#include "Assets/Asset Types/SHTextureAsset.h" + #include "Assets/SHAssetManager.h" using namespace SHADE; @@ -39,34 +42,26 @@ namespace Sandbox // Create temp meshes const auto CUBE_MESH = SHADE::SHPrimitiveGenerator::Cube(*graphicsSystem); + auto assets = SHAssetManager::GetAllAssets(); + //Test Racoon mesh - auto meshes = SHADE::SHAssetManager::GetAllMeshes(); - std::vector> handles; - for (auto const& mesh : meshes) - { - if (mesh.header.meshName == "Cube.012") - { - handles.push_back(graphicsSystem->AddMesh( - mesh.header.vertexCount, - mesh.vertexPosition.data(), - mesh.texCoords.data(), - mesh.vertexTangent.data(), - mesh.vertexNormal.data(), - mesh.header.indexCount, - mesh.indices.data() - )); - } - } + auto mesh = SHAssetManager::GetData(107348815); + Handle handle; + handle = (graphicsSystem->AddMesh( + mesh->header.vertexCount, + mesh->vertexPosition.data(), + mesh->texCoords.data(), + mesh->vertexTangent.data(), + mesh->vertexNormal.data(), + mesh->header.indexCount, + mesh->indices.data() + )); graphicsSystem->BuildMeshBuffers(); // Load Textures - auto textures = SHADE::SHAssetManager::GetAllTextures(); - std::vector> texHandles; - for (const auto& tex : textures) - { - auto texture = graphicsSystem->Add(tex); - texHandles.push_back(texture); - } + auto texture = SHAssetManager::GetData(91918845); + Handle texHandle; + texHandle = graphicsSystem->Add(*texture); graphicsSystem->BuildTextures(); // Create Materials @@ -116,7 +111,7 @@ namespace Sandbox auto& renderable = *SHComponentManager::GetComponent_s(raccoonSpin); auto& transform = *SHComponentManager::GetComponent_s(raccoonSpin); - renderable.Mesh = handles.front(); + renderable.Mesh = handle; renderable.SetMaterial(customMat); renderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f)); renderable.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f); @@ -157,7 +152,7 @@ namespace Sandbox auto& renderableShowcase = *SHComponentManager::GetComponent_s(raccoonShowcase); auto& transformShowcase = *SHComponentManager::GetComponent_s(raccoonShowcase); - renderableShowcase.Mesh = handles.front(); + renderableShowcase.Mesh = handle; renderableShowcase.SetMaterial(customMat); renderableShowcase.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f)); renderableShowcase.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f); diff --git a/SHADE_Engine/src/Assets/Asset Types/SHAnimationAsset.h b/SHADE_Engine/src/Assets/Asset Types/SHAnimationAsset.h index 76f4c0ac..b411a11e 100644 --- a/SHADE_Engine/src/Assets/Asset Types/SHAnimationAsset.h +++ b/SHADE_Engine/src/Assets/Asset Types/SHAnimationAsset.h @@ -12,11 +12,11 @@ #include #include -#include "SH_API.h" +#include "SHAssetData.h" namespace SHADE { - struct SH_API SHAnimationAsset + struct SH_API SHAnimationAsset : SHAssetData { std::string name; diff --git a/SHADE_Engine/src/Assets/Asset Types/SHAssetData.h b/SHADE_Engine/src/Assets/Asset Types/SHAssetData.h new file mode 100644 index 00000000..8db9824c --- /dev/null +++ b/SHADE_Engine/src/Assets/Asset Types/SHAssetData.h @@ -0,0 +1,19 @@ +/*************************************************************************//** + * \file SHAssetDataBase.h + * \author Loh Xiao Qi + * \date October 2022 + * \brief + * + * 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 + +namespace SHADE +{ + struct SHAssetData + { + virtual ~SHAssetData(){} + }; +} diff --git a/SHADE_Engine/src/Assets/Asset Types/SHInternalAsset.h b/SHADE_Engine/src/Assets/Asset Types/SHInternalAsset.h new file mode 100644 index 00000000..8bef34e9 --- /dev/null +++ b/SHADE_Engine/src/Assets/Asset Types/SHInternalAsset.h @@ -0,0 +1,21 @@ +/*************************************************************************//** + * \file SHInternalAsset.h + * \author Loh Xiao Qi + * \date October 2022 + * \brief + * + * 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 "SHAsset.h" + +namespace SHADE +{ + struct SHInternalAsset : SHAsset + { + + }; +} \ No newline at end of file diff --git a/SHADE_Engine/src/Assets/Asset Types/SHMeshAsset.h b/SHADE_Engine/src/Assets/Asset Types/SHMeshAsset.h index 68c0d150..20b442ba 100644 --- a/SHADE_Engine/src/Assets/Asset Types/SHMeshAsset.h +++ b/SHADE_Engine/src/Assets/Asset Types/SHMeshAsset.h @@ -14,7 +14,7 @@ #include #include "Math/SHMath.h" -#include "SH_API.h" +#include "SHAssetData.h" namespace SHADE { @@ -22,10 +22,10 @@ namespace SHADE { uint32_t vertexCount; uint32_t indexCount; - std::string meshName; + std::string name; }; - struct SH_API SHMeshAsset + struct SH_API SHMeshAsset : SHAssetData { bool compiled; bool changed; diff --git a/SHADE_Engine/src/Assets/Asset Types/SHTextureAsset.h b/SHADE_Engine/src/Assets/Asset Types/SHTextureAsset.h index d24b6c02..d26a2c30 100644 --- a/SHADE_Engine/src/Assets/Asset Types/SHTextureAsset.h +++ b/SHADE_Engine/src/Assets/Asset Types/SHTextureAsset.h @@ -2,10 +2,11 @@ #include "tinyddsloader.h" #include "Graphics/MiddleEnd/Textures/SHTextureLibrary.h" +#include "SHAssetData.h" namespace SHADE { - struct SHTextureAsset + struct SHTextureAsset : SHAssetData { bool compiled; diff --git a/SHADE_Engine/src/Assets/Libraries/SHAssetLoader.h b/SHADE_Engine/src/Assets/Libraries/SHAssetLoader.h new file mode 100644 index 00000000..41595519 --- /dev/null +++ b/SHADE_Engine/src/Assets/Libraries/SHAssetLoader.h @@ -0,0 +1,21 @@ +/*************************************************************************//** + * \file SHAssetLoader.h + * \author Loh Xiao Qi + * \date October 2022 + * \brief + * + * 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 "Assets/Asset Types/SHAssetData.h" + +namespace SHADE +{ + struct SHAssetLoader + { + virtual SHAssetData* Load(AssetPath path) = 0; + }; +} diff --git a/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.cpp b/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.cpp index feea9f35..f4be0b68 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.cpp +++ b/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.cpp @@ -51,13 +51,11 @@ namespace SHADE } } - SHMeshAsset SHAssimpLibrary::ProcessMesh(aiMesh const& mesh) noexcept + SHMeshAsset* SHAssimpLibrary::ProcessMesh(aiMesh const& mesh) noexcept { - SHMeshAsset result - { - .compiled { false}, - .changed { false } - }; + SHMeshAsset* result = new SHMeshAsset(); + result->compiled = false; + result->changed = false; for (size_t i{0}; i < mesh.mNumVertices; ++i) { @@ -66,7 +64,7 @@ namespace SHADE vertex.x = mesh.mVertices[i].x; vertex.y = mesh.mVertices[i].y; vertex.z = mesh.mVertices[i].z; - result.vertexPosition.push_back(vertex); + result->vertexPosition.push_back(vertex); // Tex coords SHVec2 texCoord{0.f, 0.f}; @@ -75,7 +73,7 @@ namespace SHADE texCoord.x = mesh.mTextureCoords[0][i].x; texCoord.y = mesh.mTextureCoords[0][i].y; } - result.texCoords.push_back(texCoord); + result->texCoords.push_back(texCoord); // Normals SHVec3 normal{0.f, 0.f, 0.f}; @@ -85,7 +83,7 @@ namespace SHADE normal.y = mesh.mNormals[i].y; normal.z = mesh.mNormals[i].z; } - result.vertexNormal.push_back(normal); + result->vertexNormal.push_back(normal); // Tangent SHVec3 tangent{0.f, 0.f, 0.f}; @@ -95,7 +93,7 @@ namespace SHADE tangent.y = mesh.mTangents[i].y; tangent.z = mesh.mTangents[i].z; } - result.vertexTangent.push_back(tangent); + result->vertexTangent.push_back(tangent); } for (size_t i {0}; i < mesh.mNumFaces; ++i) @@ -103,13 +101,13 @@ namespace SHADE aiFace face = mesh.mFaces[i]; for (size_t j{0}; j < face.mNumIndices; ++j) { - result.indices.push_back(face.mIndices[j]); + result->indices.push_back(face.mIndices[j]); } } - result.header.vertexCount = static_cast(result.vertexPosition.size()); - result.header.indexCount = static_cast(result.indices.size()); - result.header.meshName = mesh.mName.C_Str(); + result->header.vertexCount = static_cast(result->vertexPosition.size()); + result->header.indexCount = static_cast(result->indices.size()); + result->header.name = mesh.mName.C_Str(); return result; } diff --git a/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.h b/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.h index a4a0447a..83755b4c 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.h +++ b/SHADE_Engine/src/Assets/Libraries/SHAssimpLibrary.h @@ -22,13 +22,13 @@ namespace SHADE class SHAssimpLibrary { private: - using MeshVectorRef = std::vector&; - using AnimVectorRef = std::vector&; + using MeshVectorRef = std::vector&; + using AnimVectorRef = std::vector&; static Assimp::Importer aiImporter; static void ProcessNode(aiNode const& node, aiScene const& scene,MeshVectorRef meshes) noexcept; static void ExtractAnimations(aiScene const& scene, AnimVectorRef anims) noexcept; - static SHMeshAsset ProcessMesh(aiMesh const& mesh) noexcept; + static SHMeshAsset* ProcessMesh(aiMesh const& mesh) noexcept; public: static void LoadFromFile(AssetPath path, MeshVectorRef meshes, AnimVectorRef anims) noexcept; diff --git a/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.cpp b/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.cpp index 8026f0e1..2346714e 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.cpp +++ b/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.cpp @@ -20,7 +20,7 @@ std::string SHADE::SHMeshCompiler::CompileMeshBinary(SHMeshAsset const& asset, A { std::string newPath{ path.string() }; newPath = newPath.substr(0, newPath.find_last_of('/') + 1); - newPath += asset.header.meshName + MESH_EXTENSION; + newPath += asset.header.name + MESH_EXTENSION.data(); std::ofstream file{ newPath, std::ios::out | std::ios::binary | std::ios::trunc }; if (!file.is_open()) diff --git a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp index 73fed1fb..90dd58d4 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp +++ b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp @@ -16,7 +16,7 @@ namespace SHADE { - void SHMeshLoader::LoadSHMesh(SHMeshAsset& mesh, AssetPath path) noexcept + void SHMeshLoader::LoadSHMesh(AssetPath path, SHMeshAsset& mesh) noexcept { std::ifstream file{ path.string(), std::ios::in | std::ios::binary }; if (!file.is_open()) @@ -56,7 +56,7 @@ namespace SHADE mesh.header.indexCount = indexCount; mesh.header.vertexCount = vertCount; - mesh.header.meshName = name; + mesh.header.name = name; mesh.vertexPosition = std::move(vertPos); mesh.vertexTangent = std::move(vertTan); @@ -66,4 +66,13 @@ namespace SHADE file.close(); } + + SHAssetData* SHMeshLoader::Load(AssetPath path) + { + auto result = new SHMeshAsset(); + + LoadSHMesh(path, *result); + + return result; + } } diff --git a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.h b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.h index f01b942a..34c4e5d2 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.h +++ b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.h @@ -12,11 +12,13 @@ #pragma once #include "../SHAssetMacros.h" #include "../Asset Types/SHMeshAsset.h" +#include "SHAssetLoader.h" namespace SHADE { - struct SHMeshLoader + struct SHMeshLoader : public SHAssetLoader { - static void LoadSHMesh(SHMeshAsset& meshes, AssetPath path) noexcept; + void LoadSHMesh(AssetPath path, SHMeshAsset& meshes) noexcept; + SHAssetData* Load(AssetPath path) override; }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.cpp b/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.cpp index 5147562a..8b986524 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.cpp +++ b/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.cpp @@ -133,6 +133,15 @@ namespace SHADE file.close(); } + SHAssetData* SHTextureLoader::Load(AssetPath path) + { + auto result = new SHTextureAsset(); + + LoadImageAsset(path, *result); + + return result; + } + void SHTextureLoader::LoadImageAsset(AssetPath path, SHTextureAsset& asset) { if (path.extension().string() == DDS_EXTENSION) diff --git a/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.h b/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.h index eb61ea91..8bdf91b1 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.h +++ b/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.h @@ -15,19 +15,20 @@ #include "../SHAssetMacros.h" #include "../Asset Types/SHTextureAsset.h" #include "tinyddsloader.h" +#include "SHAssetLoader.h" namespace SHADE { - class SHTextureLoader + class SHTextureLoader : public SHAssetLoader { private: - static std::string TinyDDSResultToString(tinyddsloader::Result value); - static vk::Format ddsLoaderToVkFormat(tinyddsloader::DDSFile::DXGIFormat format, bool isLinear); - - - static void LoadTinyDDS(AssetPath path, SHTextureAsset& asset) noexcept; + std::string TinyDDSResultToString(tinyddsloader::Result value); + vk::Format ddsLoaderToVkFormat(tinyddsloader::DDSFile::DXGIFormat format, bool isLinear); + + void LoadTinyDDS(AssetPath path, SHTextureAsset& asset) noexcept; public: - static void LoadImageAsset(AssetPath paths, SHTextureAsset& image); - static void LoadSHTexture(AssetPath path, SHTextureAsset& asset) noexcept; + void LoadImageAsset(AssetPath paths, SHTextureAsset& image); + void LoadSHTexture(AssetPath path, SHTextureAsset& asset) noexcept; + SHAssetData* Load(AssetPath path) override; }; } diff --git a/SHADE_Engine/src/Assets/SHAsset.h b/SHADE_Engine/src/Assets/SHAsset.h index 8d7b55d1..86e8a722 100644 --- a/SHADE_Engine/src/Assets/SHAsset.h +++ b/SHADE_Engine/src/Assets/SHAsset.h @@ -12,11 +12,12 @@ #pragma once #include "Filesystem/SHFileSystem.h" -#include "SHAssetMacros.h" +#include "Assets/SHAssetMacros.h" +#include "SH_API.h" namespace SHADE { - struct SHAsset + struct SH_API SHAsset { AssetName name; AssetID id; diff --git a/SHADE_Engine/src/Assets/SHAssetMacros.h b/SHADE_Engine/src/Assets/SHAssetMacros.h index 61c5879d..0fdfa04e 100644 --- a/SHADE_Engine/src/Assets/SHAssetMacros.h +++ b/SHADE_Engine/src/Assets/SHAssetMacros.h @@ -32,12 +32,12 @@ typedef std::filesystem::path AssetPath; typedef unsigned char* AssetData; typedef std::string AssetMetaVersion; typedef std::string AssetExtension; -typedef unsigned char AssetTypeMeta; +typedef size_t AssetTypeMeta; typedef FMOD::Sound* SHSound; // Asset Meta Version -#define ASSET_META_VER "1.0" +constexpr std::string_view ASSET_META_VER { "1.0" }; // Asset type enum enum class AssetType : AssetTypeMeta @@ -53,34 +53,35 @@ enum class AssetType : AssetTypeMeta SCENE, PREFAB, AUDIO_WAV, - DDS + DDS, + MAX_COUNT }; //Directory #ifdef _PUBLISH -#define ASSET_ROOT "Assets" +constexpr std::string_view ASSET_ROOT {"Assets"}; #else -#define ASSET_ROOT "../../Assets" +constexpr std::string_view ASSET_ROOT {"../../Assets"}; #endif // ASSET EXTENSIONS -#define META_EXTENSION ".shmeta" -#define IMAGE_EXTENSION ".png" -#define AUDIO_EXTENSION ".ogg" -#define AUDIO_WAV_EXTENSION ".wav" -#define SHADER_EXTENSION ".glsl" -#define SCRIPT_EXTENSION ".cs" -#define SCENE_EXTENSION ".SHADE" -#define PREFAB_EXTENSION ".SHPrefab" -#define MATERIAL_EXTENSION ".SHMat" -#define TEXTURE_EXTENSION ".shtex" -#define DDS_EXTENSION ".dds" -#define FBX_EXTENSION ".fbx" -#define GLTF_EXTENSION ".gltf" -#define MESH_EXTENSION ".shmesh" +constexpr std::string_view META_EXTENSION {".shmeta"}; +constexpr std::string_view IMAGE_EXTENSION {".png"}; +constexpr std::string_view AUDIO_EXTENSION {".ogg"}; +constexpr std::string_view AUDIO_WAV_EXTENSION {".wav"}; +constexpr std::string_view SHADER_EXTENSION {".glsl"}; +constexpr std::string_view SCRIPT_EXTENSION {".cs"}; +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 DDS_EXTENSION {".dds"}; +constexpr std::string_view FBX_EXTENSION {".fbx"}; +constexpr std::string_view GLTF_EXTENSION {".gltf"}; +constexpr std::string_view MESH_EXTENSION {".shmesh"}; -std::string const EXTENSIONS[] = { +constexpr std::string_view EXTENSIONS[] = { AUDIO_EXTENSION, SHADER_EXTENSION, MATERIAL_EXTENSION, @@ -96,10 +97,12 @@ std::string const EXTENSIONS[] = { GLTF_EXTENSION }; +constexpr size_t TYPE_COUNT {static_cast(AssetType::MAX_COUNT) }; + // Error flags -#define FILE_NOT_FOUND_ERR "FILE NOT FOUND" -#define META_NOT_FOUND_ERR "META NOT FOUND" -#define ASSET_NOT_FOUND_ERR "ASSET NOT FOUND" -#define EXT_DOES_NOT_EXIST "TYPE DOES NOT HAVE EXTENSION DEFINED" +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 diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index faca24b2..2658e83b 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -26,11 +26,10 @@ namespace SHADE FMOD::System* SHAssetManager::audioSystem; std::unordered_map* SHAssetManager::audioSoundList; - std::vector SHAssetManager::assetCollection; - std::unordered_map SHAssetManager::assetRegistry; + std::vector SHAssetManager::loaders(TYPE_COUNT); - std::unordered_map SHAssetManager::meshCollection; - std::unordered_map SHAssetManager::textureCollection; + std::vector SHAssetManager::assetCollection; + std::unordered_map SHAssetManager::assetData; /**************************************************************************** * \brief Static function to generate asset ID. @@ -81,7 +80,37 @@ namespace SHADE // return std::filesystem::path(); //} - return std::filesystem::path(ASSET_ROOT + folder + path.filename().string()); + return std::filesystem::path(std::string(ASSET_ROOT) + folder + path.filename().string()); + } + + AssetPath SHAssetManager::GenerateNewPath(AssetName name, AssetType type) + { + std::string folder; + + switch(type) + { + case AssetType::SCENE: + folder = "scenes/"; + break; + + case AssetType::PREFAB: + folder = "prefabs/"; + break; + + case AssetType::MATERIAL: + folder = "materials/"; + break; + + default: + folder = "/"; + } + + return std::filesystem::path{ + std::string(ASSET_ROOT) + + folder + + name + + std::string(EXTENSIONS[static_cast(type)]) + }; } /**************************************************************************** @@ -117,7 +146,7 @@ namespace SHADE // folder = ""; // break; //} - AssetPath path{ ASSET_ROOT + folder + name + SHAssetMetaHandler::GetExtensionFromType(type) }; + AssetPath path{ std::string{ASSET_ROOT} + folder + name + SHAssetMetaHandler::GetExtensionFromType(type) }; SHAssetMetaHandler::WriteMetaData(meta); @@ -126,6 +155,19 @@ namespace SHADE return id; } + AssetID SHAssetManager::CreateAsset(AssetName name, AssetType type) noexcept + { + AssetID id = GenerateAssetID(type); + + assetCollection.emplace_back( + name, + id, + type, + GenerateNewPath(name, type), + 0 + ); + return id; + } /**************************************************************************** * \brief Import new asset from outside editor window. * @@ -134,7 +176,10 @@ namespace SHADE ****************************************************************************/ AssetID SHAssetManager::ImportNewAsset(char const* p) noexcept { - std::filesystem::path const path{ p }; + std::filesystem::path const path{ p }; + + auto const type = SHAssetMetaHandler::GetTypeFromExtension(path.extension().string()); + auto const id = GenerateAssetID(type); std::filesystem::path const newPath{ GenerateLocalPath(path) }; if (newPath.empty()) @@ -145,11 +190,7 @@ namespace SHADE std::filesystem::copy(path, newPath); - AssetID id{ RetrieveAsset(newPath.string().c_str()) }; - if (id != 0) - { - LoadData(id); - } + assetCollection.push_back(CreateAssetFromPath(newPath)); return id; } @@ -160,158 +201,14 @@ namespace SHADE ****************************************************************************/ void SHAssetManager::RefreshAllAssets() noexcept { - std::vector metaFiles; - std::vector AssetFiles; - //SHFileSystem::LoadAllFiles(metaFiles, AssetFiles); - //std::vector AssetFilesVerified; - std::vector AssetFilesNew; - - for (auto const& asset : AssetFiles) - { - bool found = false; - for (auto it {metaFiles.begin()}; it != metaFiles.end(); ++it) - { - std::string fileExtCheck{ asset.filename().string() }; - fileExtCheck += META_EXTENSION; - if (it->filename().string() == fileExtCheck) - { - metaFiles.erase(it); - found = true; - break; - } - } - - if (!found && IsRecognised(asset.extension().string().c_str())) - { - AssetFilesNew.push_back(asset); - } - } - - std::vector newLoad; - newLoad.reserve(AssetFilesNew.size()); - - //TODO: Handle if meta does not match all assets (if meta exist and asset doesnt, vice versa) - for (auto const& file : AssetFilesNew) - { - newLoad.push_back(RegisterAssetNew(file)); - } - - //UpdateAllSpriteSets(); - - } - - //void SHAssetManager::LoadDataTemp(std::string p) noexcept - //{ - // AssetPath path{ p }; - - // if (path.extension().string() == FBX_EXTENSION - // || path.extension().string() == GLTF_EXTENSION - // || path.extension().string() == MESH_EXTENSION) - // { - // LoadGLTF( - // { - // .name {path.filename().string()}, - // .id {0}, - // .type {AssetType::MESH}, - // .path {path}, - // .location {0} - // } - // ); - // } - // else if (path.extension().string() == DDS_EXTENSION - // || path.extension().string() == TEXTURE_EXTENSION) - // { - // LoadDDS( - // { - // .name {path.filename().string()}, - // .id {0}, - // .type {AssetType::DDS}, - // .path {path}, - // .location {0} - // } - // ); - // } - //} - - std::vector SHAssetManager::GetAllMeshes() noexcept - { - std::vector result; - for (auto const& mesh : meshCollection) - { - result.push_back(mesh.second); - } - - return result; - } - - std::vector SHAssetManager::GetAllTextures() noexcept - { - std::vector result; - for (auto const& dds : textureCollection) - { - result.push_back(dds.second); - } - - return result; - } - - SHMeshAsset const* SHAssetManager::GetMesh(AssetID id) noexcept - { - if (meshCollection.find(id) == meshCollection.end()) - { - return nullptr; - } - - return &meshCollection[id]; - } - - SHTextureAsset const* SHAssetManager::GetTexture(AssetID id) noexcept - { - if (textureCollection.find(id) == textureCollection.end()) - { - return nullptr; - } - - return &textureCollection[id]; - } - - /**************************************************************************** - * \param Path for meta data file - * \param Path for asset file - - * \brief Links meta data to asset in registries. Meta data should - * already exist - ****************************************************************************/ - void SHAssetManager::RegisterAsset(AssetPath const& metaPath, AssetPath const& path) noexcept - { - SHAsset const meta = SHAssetMetaHandler::RetrieveMetaData(metaPath); - - assetCollection.push_back(meta); - } - - /**************************************************************************** - * \param Path for asset file - - * \brief Creates new meta data for new asset. - ****************************************************************************/ - SHAsset SHAssetManager::RegisterAssetNew(AssetPath const& asset) noexcept - { - SHAsset meta; - meta.type = SHAssetMetaHandler::GetTypeFromExtension(asset.extension().string()); - meta.id = GenerateAssetID(meta.type); - - assetCollection.push_back(meta); - - SHAssetMetaHandler::WriteMetaData(meta); - return assetCollection.back(); } bool SHAssetManager::IsRecognised(char const* ext) noexcept { for (auto const& e : EXTENSIONS) { - if (strcmp(ext, e.c_str()) == 0) + if (strcmp(ext, e.data()) == 0) { return true; } @@ -320,60 +217,31 @@ namespace SHADE return false; } - void SHAssetManager::LoadGLTF(AssetPath path) noexcept + SHAsset SHAssetManager::CreateAssetFromPath(AssetPath path) noexcept { - std::vector meshes; - std::vector anims; - - SHAssimpLibrary::LoadFromFile(path, meshes, anims); + SHAsset result; - for (auto const& mesh : meshes) - { - auto id{ GenerateAssetID(AssetType::MESH) }; - meshCollection.emplace(id, mesh); + result.name = path.stem().string(); + result.type = SHAssetMetaHandler::GetTypeFromExtension(path.extension().string()); + result.id = GenerateAssetID(result.type); + result.path = path; - AssetPath path; - if (!mesh.compiled) - { - path = SHMeshCompiler::CompileMeshBinary(mesh, path); - } - - assetCollection.emplace_back( - mesh.header.meshName, - id, - AssetType::MESH, - path, - 0 - ); - } - - for (auto const& anim : anims) - { - //TODO Register anim resource and compile into binary - } + return result; } - void SHAssetManager::LoadDDS(SHAsset asset) noexcept + void SHAssetManager::InitLoaders() noexcept { - SHTextureAsset image; - - SHTextureLoader::LoadImageAsset(asset.path, image); - - if (!image.compiled) - { - auto id{ GenerateAssetID(AssetType::TEXTURE) }; - textureCollection.emplace(id, image); - - auto path{ SHTextureCompiler::CompileTextureBinary(image, asset.path) }; - - assetCollection.emplace_back( - image.name, - id, - AssetType::TEXTURE, - path, - 0 - ); - } + loaders[static_cast(AssetType::AUDIO)] = nullptr; + loaders[static_cast(AssetType::SHADER)] = nullptr; + loaders[static_cast(AssetType::MATERIAL)] = nullptr; + loaders[static_cast(AssetType::IMAGE)] = dynamic_cast(new SHTextureLoader()); + loaders[static_cast(AssetType::TEXTURE)] = nullptr; + loaders[static_cast(AssetType::MESH)] = dynamic_cast(new SHMeshLoader()); + loaders[static_cast(AssetType::SCRIPT)] = nullptr; + loaders[static_cast(AssetType::SCENE)] = nullptr; + loaders[static_cast(AssetType::PREFAB)] = nullptr; + loaders[static_cast(AssetType::AUDIO_WAV)] = nullptr; + loaders[static_cast(AssetType::DDS)] = nullptr; } /**************************************************************************** @@ -381,7 +249,8 @@ namespace SHADE ****************************************************************************/ void SHAssetManager::Load() noexcept { - RetrieveAssets(); + InitLoaders(); + BuildAssetCollection(); LoadAllData(); } @@ -390,143 +259,40 @@ namespace SHADE ****************************************************************************/ void SHAssetManager::LoadAllData() noexcept { - //TODO Remove when on demand loading is done for (auto const& asset : assetCollection) { - switch (asset.type) - { - case AssetType::MESH: - meshCollection.emplace(asset.id, SHMeshAsset()); - SHMeshLoader::LoadSHMesh(meshCollection[asset.id], asset.path); - break; - - case AssetType::TEXTURE: - textureCollection.emplace(asset.id, SHTextureAsset()); - SHTextureLoader::LoadSHTexture(asset.path, textureCollection[asset.id]); - break; - - default: - void; - } + SHAssetData* data = loaders[static_cast(asset.type)]->Load(asset.path); + assetData.emplace(asset.id, data); } } - void SHAssetManager::LoadData(AssetID id) noexcept + SHAssetData* SHAssetManager::LoadData(SHAsset const& asset) noexcept { - (void)id; - } + SHAssetData* data = loaders[static_cast(asset.type)]->Load(asset.path); - /**************************************************************************** - * \brief Retrieve all asset files and meta files from filesystem - ****************************************************************************/ - void SHAssetManager::RetrieveAssets() noexcept - { - std::vector metaFiles; - std::vector AssetFiles; - - for (auto const dir : std::filesystem::recursive_directory_iterator(ASSET_ROOT)) + if (data == nullptr) { - if (dir.path().extension().string() == META_EXTENSION) - { - auto meta{ SHAssetMetaHandler::RetrieveMetaData(dir.path()) }; - - assetCollection.push_back(meta); - assetRegistry.emplace(meta.id, meta); - } - } - - //TODO: Write new function for file manager to loop through all files - //SHFileSystem::StartupFillDirectories(ASSET_ROOT); - //FolderPointer rootFolder = SHFileSystem::GetRoot(); - - //for (auto const& meta : metaFiles) - //{ - // for (std::vector::const_iterator it{ AssetFiles.cbegin() }; - // it != AssetFiles.cend(); - // ++it) - // { - // // Asset exists for meta file - // std::string fileExtCheck{ it->filename().string() }; - // fileExtCheck += META_EXTENSION; - // if (meta.filename().string() == fileExtCheck) - // { - // RegisterAsset(meta, *it); - // AssetFiles.erase(it); - // break; - // } - // } - //} - - //TODO: Handle if meta does not match all assets (if meta exist and asset doesnt, vice versa) - //for (auto const& file : AssetFiles) - //{ - // if (IsRecognised(file.extension().string().c_str())) - // { - // SHAssetMetaHandler::WriteMetaData(RegisterAssetNew(file)); - // } - // else - // { - // std::cout << "Unsupported File Format: " << file.filename() << "\n"; - // } - //} - } - - AssetID SHAssetManager::RetrieveAsset(char const* path) noexcept - { - std::filesystem::path p{ path }; - if (IsRecognised(p.extension().string().c_str())) - { - SHAsset const& meta{ RegisterAssetNew(p) }; - SHAssetMetaHandler::WriteMetaData(meta); - return meta.id; + SHLOG_ERROR("Unable to load asset into memory: {}\n", asset.path.string()); } else { - std::cout << "Unsupported File Format: " << p.filename() << "\n"; + assetData.emplace(asset.id, data); } - // Assert that file imported is not recognised - return 0; + return data; } - /**************************************************************************** - * \param Full path of file - - * \brief Extracts file name from path. Formats file name into readable - * with spaces and capitalises first letter of every word - ****************************************************************************/ - AssetName SHAssetManager::GetNameFromPath(AssetPath filepath) noexcept + void SHAssetManager::BuildAssetCollection() noexcept { - std::string name{ filepath.filename().string() }; - name = name.substr(0, name.find_last_of('.')); - - //if (name[0] <= 122 && name[0] >= 97) - //{ - // name[0] -= 32; - //} - - //for (size_t i{ 1 }; i < name.length(); ++i) - //{ - // // Replace all underscores with spaces - // if (name[i] == '_') - // { - // name[i] = ' '; - // continue; - // } - - // if (name[i + 1] <= 'Z' && name[i + 1] >= 'A' - // && name[i] <= 'z' && name[i] >= 'a') - // { - // name.insert(i + 1, 1, ' '); - // continue; - // } - - // if (name[i - 1] == ' ' && name[i] <= 'z' && name[i] >= 'a') - // { - // name[i] -= 32; - // } - //} - - return name; + for (auto const& dir : std::filesystem::recursive_directory_iterator{ASSET_ROOT}) + { + if (dir.is_regular_file()) + { + if (dir.path().extension().string() == META_EXTENSION.data()) + { + assetCollection.push_back(SHAssetMetaHandler::RetrieveMetaData(dir.path())); + } + } + } } } diff --git a/SHADE_Engine/src/Assets/SHAssetManager.h b/SHADE_Engine/src/Assets/SHAssetManager.h index b2c4216b..74029bdd 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.h +++ b/SHADE_Engine/src/Assets/SHAssetManager.h @@ -11,9 +11,10 @@ #pragma once #include "tinyddsloader.h" #include "SHAsset.h" +#include "Asset Types/SHAssetData.h" +#include "Libraries/SHAssetLoader.h" +#include -#include "Asset Types/SHMeshAsset.h" -#include "Asset Types/SHTextureAsset.h" #include "SH_API.h" namespace SHADE @@ -28,6 +29,8 @@ namespace SHADE static AssetPath GenerateLocalPath(AssetPath path) noexcept; + static AssetPath GenerateNewPath(AssetName name, AssetType type); + /**************************************************************************** * \brief Deallocate all memory used by resource data ****************************************************************************/ @@ -54,6 +57,7 @@ namespace SHADE * \return resource id generated for new asset ****************************************************************************/ static AssetID CreateNewAsset(AssetType, AssetName) noexcept; + static AssetID CreateAsset(AssetName name, AssetType type) noexcept; /**************************************************************************** * \brief Import new resource from outside editor window. @@ -70,67 +74,49 @@ namespace SHADE static void RefreshAllAssets() noexcept; // -------------------------------------------------------------------------/ - //TODO: TEMPORARY FOR TESTING GLTF & DDS - //static void LoadDataTemp(std::string path) noexcept; - static std::vector GetAllMeshes() noexcept; - static std::vector GetAllTextures() noexcept; + template + static std::enable_if_t, T const * const> GetData(AssetID id) noexcept + { + if (assetData.contains(id)) + { + for (auto const& asset : assetCollection) + { + if (asset.id == id) + { + assetData.emplace(id, LoadData(asset)); + return dynamic_cast(assetData[id]); + } + } - static SHMeshAsset const* GetMesh(AssetID id) noexcept; - static SHTextureAsset const* GetTexture(AssetID id) noexcept; - - // Specialised load calls - static void LoadGLTF(AssetPath path) noexcept; - static void LoadDDS(SHAsset asset) noexcept; + SHLOG_ERROR("Asset ID provided does not exist: {}", id); + return nullptr; + } + + return dynamic_cast(assetData[id]); + } private: /**************************************************************************** * \brief Load resource data into memory ****************************************************************************/ static void LoadAllData() noexcept; - static void LoadData(AssetID id) noexcept; + static SHAssetData* LoadData(SHAsset const& asset) noexcept; - /**************************************************************************** - * \brief Retrieve all resource files and meta files from filesystem - ****************************************************************************/ - static void RetrieveAssets() noexcept; - - static AssetID RetrieveAsset(char const* path) noexcept; - - /**************************************************************************** - * \param Full path of file - - * \brief Extracts file name from path. Formats file name into readable - * with spaces and capitalises first letter of every word - ****************************************************************************/ - static AssetName GetNameFromPath(AssetPath) noexcept; - - /**************************************************************************** - * \param Path for meta data file - * \param Path for resource file - - * \brief Links meta data to resource in registries. Meta data should - * already exist - ****************************************************************************/ - static void RegisterAsset(AssetPath const&, AssetPath const&) noexcept; - - /**************************************************************************** - * \param Path for resource file - - * \brief Creates new meta data for new resource. - ****************************************************************************/ - static SHAsset RegisterAssetNew(AssetPath const&) noexcept; + inline static void BuildAssetCollection() noexcept; static bool IsRecognised(char const*) noexcept; + + static SHAsset CreateAssetFromPath(AssetPath path) noexcept; + static void InitLoaders() noexcept; static FMOD::System* audioSystem; static std::unordered_map* audioSoundList; + static std::vector loaders; + // For all resources static std::vector assetCollection; - static std::unordered_map assetRegistry; - - static std::unordered_map meshCollection; - static std::unordered_map textureCollection; + static std::unordered_map assetData; }; } diff --git a/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp b/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp index 442c3d96..1bfec00d 100644 --- a/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp +++ b/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp @@ -37,7 +37,7 @@ namespace SHADE { for (int i{0}; i < EXTENSIONS->size(); ++i) { - if (ext == EXTENSIONS[i]) + if (strcmp(ext.c_str(), EXTENSIONS[i].data()) == 0) { return static_cast(i); } @@ -53,7 +53,7 @@ namespace SHADE ****************************************************************************/ AssetExtension SHAssetMetaHandler::GetExtensionFromType(AssetType type) noexcept { - return EXTENSIONS[static_cast(type)]; + return AssetExtension(EXTENSIONS[static_cast(type)]); } /**************************************************************************** @@ -124,16 +124,6 @@ namespace SHADE metaFile << "ID: " << meta.id << "\n"; metaFile << "Type: " << static_cast(meta.type) << std::endl; - ////TODO Add in information that is specific to types like mesh - //switch(meta.type) - //{ - //case AssetType::MESH: - // break; - - //default: - // break; - //} - metaFile.close(); } From 449cd28bb353b5b3a41f103dc1b6cc3540b22b17 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Fri, 21 Oct 2022 20:55:21 +0800 Subject: [PATCH 11/50] Took test scene from main --- SHADE_Application/src/Scenes/SBTestScene.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index bd33e63c..41326174 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -13,9 +13,6 @@ #include "Physics/Components/SHRigidBodyComponent.h" #include "Physics/Components/SHColliderComponent.h" -#include "Assets/Asset Types/SHMeshAsset.h" -#include "Assets/Asset Types/SHTextureAsset.h" - #include "Assets/SHAssetManager.h" #include "Resource/SHResourceManager.h" @@ -43,8 +40,6 @@ namespace Sandbox // Create temp meshes const auto CUBE_MESH = SHADE::SHPrimitiveGenerator::Cube(*graphicsSystem); - auto assets = SHAssetManager::GetAllAssets(); - //Test Racoon mesh std::vector> handles; std::vector> texHandles; From cc6e2189fa7df84faec49733f7cf417da947a970 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Fri, 21 Oct 2022 20:56:14 +0800 Subject: [PATCH 12/50] WIP --- SHADE_Engine/src/Camera/SHCameraSystem.cpp | 1 + .../MiddleEnd/Interface/SHGraphicsConstants.h | 8 + .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 35 ++- .../src/Graphics/Pipeline/SHVkPipeline.cpp | 23 ++ .../RenderGraph/SHAttachmentDescriptionType.h | 1 + .../Graphics/RenderGraph/SHRenderGraph.cpp | 45 +++- .../src/Graphics/RenderGraph/SHRenderGraph.h | 4 - .../RenderGraph/SHRenderGraphNode.cpp | 12 +- .../Graphics/RenderGraph/SHRenderGraphNode.h | 5 +- .../RenderGraph/SHRenderGraphResource.cpp | 11 + .../RenderGraph/SHRenderGraphResource.h | 11 +- .../RenderGraph/SHRenderGraphStorage.h | 3 + .../src/Graphics/RenderGraph/SHSubpass.cpp | 199 +++++++++++++++++- .../src/Graphics/RenderGraph/SHSubpass.h | 51 +++-- .../Graphics/RenderGraph/SHSubpassCompute.cpp | 34 ++- .../Graphics/RenderGraph/SHSubpassCompute.h | 28 ++- .../Graphics/Shaders/SHShaderReflected.cpp | 3 + TempShaderFolder/GreyscaleCs.glsl | 38 ++++ TempShaderFolder/GreyscaleCs.spv | Bin 0 -> 1400 bytes 19 files changed, 437 insertions(+), 75 deletions(-) create mode 100644 TempShaderFolder/GreyscaleCs.glsl create mode 100644 TempShaderFolder/GreyscaleCs.spv diff --git a/SHADE_Engine/src/Camera/SHCameraSystem.cpp b/SHADE_Engine/src/Camera/SHCameraSystem.cpp index 9c97131a..c9822b82 100644 --- a/SHADE_Engine/src/Camera/SHCameraSystem.cpp +++ b/SHADE_Engine/src/Camera/SHCameraSystem.cpp @@ -62,6 +62,7 @@ namespace SHADE system->editorCamera.position -= UP * dt * camera.movementSpeed; system->editorCamera.dirtyView = true; } + system->UpdateCameraComponent(system->editorCamera); } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h index 67cbc001..a0457b65 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h @@ -63,6 +63,14 @@ namespace SHADE */ /***************************************************************************/ static constexpr uint32_t PER_INSTANCE = 3; + /***************************************************************************/ + /*! + \brief + DescriptorSet Index for render graph resources. + */ + /***************************************************************************/ + static constexpr uint32_t RENDERGRAPH_RESOURCE = 4; + }; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 06762db8..386cef54 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -115,6 +115,23 @@ namespace SHADE graphicsCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true); transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); + + + // TODO: This is VERY temporarily here until a more solid resource management system is implemented + shaderSourceLibrary.Init("../../TempShaderFolder/"); + + shaderSourceLibrary.LoadShader(0, "TestCubeVs.glsl", SH_SHADER_TYPE::VERTEX, true); + shaderSourceLibrary.LoadShader(1, "TestCubeFs.glsl", SH_SHADER_TYPE::FRAGMENT, true); + + shaderSourceLibrary.LoadShader(2, "GreyscaleCs.glsl", SH_SHADER_TYPE::COMPUTE, true); + + shaderModuleLibrary.ImportFromSourceLibrary(device, shaderSourceLibrary); + auto cubeVS = shaderModuleLibrary.GetShaderModule("TestCubeVs.glsl"); + auto cubeFS = shaderModuleLibrary.GetShaderModule("TestCubeFs.glsl"); + auto greyscale = shaderModuleLibrary.GetShaderModule("GreyscaleCs.glsl"); + cubeVS->Reflect(); + cubeFS->Reflect(); + greyscale->Reflect(); } void SHGraphicsSystem::InitSceneRenderGraph(void) noexcept @@ -166,6 +183,13 @@ namespace SHADE gBufferWriteSubpass->AddColorOutput("Entity ID"); gBufferWriteSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL); + auto greyscale = shaderModuleLibrary.GetShaderModule("GreyscaleCs.glsl"); + + auto greyscaleSubpass = node->AddSubpass("Greyscale Subpass"); + greyscaleSubpass->AddGeneralInput("Scene"); + greyscaleSubpass->AddSubpassCompute(greyscale); + + // We do this to just transition our scene layout to shader read auto sceneLayoutTransitionSubpass = node->AddSubpass("Scene Layout Transition"); sceneLayoutTransitionSubpass->AddInput("Scene"); @@ -177,20 +201,11 @@ namespace SHADE worldRenderer = worldViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph); worldRenderer->SetCamera(worldCamera); - - // TODO: This is VERY temporarily here until a more solid resource management system is implemented - shaderSourceLibrary.Init("../../TempShaderFolder/"); - - shaderSourceLibrary.LoadShader(0, "TestCubeVs.glsl", SH_SHADER_TYPE::VERTEX, true); - shaderSourceLibrary.LoadShader(1, "TestCubeFs.glsl", SH_SHADER_TYPE::FRAGMENT, true); - - shaderModuleLibrary.ImportFromSourceLibrary(device, shaderSourceLibrary); auto cubeVS = shaderModuleLibrary.GetShaderModule("TestCubeVs.glsl"); auto cubeFS = shaderModuleLibrary.GetShaderModule("TestCubeFs.glsl"); - cubeVS->Reflect(); - cubeFS->Reflect(); defaultMaterial = AddMaterial(cubeVS, cubeFS, gBufferWriteSubpass); + } void SHGraphicsSystem::InitMiddleEnd(void) noexcept diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.cpp b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.cpp index c03fd2a7..973218d1 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.cpp +++ b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.cpp @@ -171,6 +171,29 @@ namespace SHADE void SHVkPipeline::CreateComputePipeline(void) noexcept { + auto shaderModule = pipelineLayout->GetShaderModules()[0]; + + vk::PipelineShaderStageCreateInfo shaderStageCreateInfo + { + .stage = vk::ShaderStageFlagBits::eCompute, + .module = shaderModule->GetVkShaderModule(), + .pName = shaderModule->GetEntryPoint().c_str(), + }; + + vk::ComputePipelineCreateInfo cpCreateInfo + { + .flags = {}, + .stage = shaderStageCreateInfo, + .layout = pipelineLayout->GetVkPipelineLayout(), + }; + + if (auto result = logicalDeviceHdl->GetVkLogicalDevice().createComputePipelines({}, 1, &cpCreateInfo, nullptr, &vkPipeline); result != vk::Result::eSuccess) + SHVulkanDebugUtil::ReportVkError(result, "Failed to create Compute Pipeline. "); + else + { + SHVulkanDebugUtil::ReportVkSuccess("Successfully created a Compute Pipeline. "); + created = true; + } } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescriptionType.h b/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescriptionType.h index 241292d4..efd3fb0f 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescriptionType.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescriptionType.h @@ -12,4 +12,5 @@ namespace SHADE DEPTH_STENCIL = 0x10, INPUT = 0x20 }; + } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index 1db410c0..df588c05 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -10,6 +10,7 @@ #include "Tools/SHLogger.h" #include "SHAttachmentDescInitParams.h" #include "SHRenderGraphStorage.h" +#include "Graphics/RenderGraph/SHSubpassCompute.h" namespace SHADE { @@ -78,36 +79,48 @@ namespace SHADE for (uint32_t i = 0; auto& node : nodes) { - // key is handle ID, value is pair (first is initial layout, second is final layout). - std::unordered_map resourceAttLayouts; + // key is handle ID, value is final layout. + std::unordered_map resourceAttFinalLayouts; if (node->subpasses.empty()) { SHLOG_ERROR("Node does not contain a subpass. Cannot configure attachment descriptions as a result. "); return; } + // attempt to get all final layouts for all resources for (auto& subpass : node->subpasses) { for (auto& color : subpass->colorReferences) { + // If final renderpass and attachment is a COLOR_PRESENT resource, make resource transition to present after last subpass if (i == nodes.size() - 1 && (node->attResources[color.attachment]->resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT))) - resourceAttLayouts[color.attachment] = vk::ImageLayout::ePresentSrcKHR; + resourceAttFinalLayouts[color.attachment] = vk::ImageLayout::ePresentSrcKHR; else - resourceAttLayouts[color.attachment] = color.layout; + resourceAttFinalLayouts[color.attachment] = color.layout; } for (auto& depth : subpass->depthReferences) - resourceAttLayouts[depth.attachment] = depth.layout; + resourceAttFinalLayouts[depth.attachment] = depth.layout; for (auto& input : subpass->inputReferences) - resourceAttLayouts[input.attachment] = input.layout; + resourceAttFinalLayouts[input.attachment] = input.layout; + + // Go through all subpass computes and initialize final layouts to GENERAL when a resource is detected to be used in it + //for (auto sbCompute : subpass->subpassComputes) + //{ + // auto const& indices = sbCompute->attachmentDescriptionIndices; + // for (auto& index : indices) + // { + // resourceAttFinalLayouts[index] = vk::ImageLayout::eGeneral; + // } + //} } for (uint32_t j = 0; j < node->attachmentDescriptions.size(); ++j) { auto& att = node->attachmentDescriptions[j]; att.initialLayout = vk::ImageLayout::eUndefined; - att.finalLayout = resourceAttLayouts[j]; + att.finalLayout = resourceAttFinalLayouts[j]; } ++i; } @@ -175,7 +188,7 @@ namespace SHADE // Now we want to loop through all attachments in all subpasses in the node and query // the resources being used. For each resource we want to query the type and record it // in bit fields (1 bit for each subpass). - uint32_t colorRead = 0, colorWrite = 0, depthRead = 0, depthWrite = 0, inputDependencies = 0; + uint32_t colorRead = 0, colorWrite = 0, depthRead = 0, depthWrite = 0, inputDependencies = 0, descriptorDependencies = 0; uint32_t i = 0; @@ -214,6 +227,9 @@ namespace SHADE if (subpass->inputReferences.size()) inputDependencies |= (1 << i); + if (!subpass->subpassComputes.empty()) + descriptorDependencies |= (1 << i); + // Input attachments can be any type, so we need to check what type it is for (auto& inputAtt : subpass->inputReferences) { @@ -279,6 +295,12 @@ namespace SHADE dstAccess |= vk::AccessFlagBits::eInputAttachmentRead; } + if (descriptorDependencies & (1 << i)) + { + dstStage |= vk::PipelineStageFlagBits::eComputeShader; + dstAccess |= vk::AccessFlagBits::eShaderWrite | vk::AccessFlagBits::eShaderRead; + } + //// If subpass of first renderpass, stage flag should be bottom of pipe //if (&node == &nodes.front() && i == 0) // srcStage = vk::PipelineStageFlagBits::eBottomOfPipe; @@ -293,6 +315,9 @@ namespace SHADE dep.dstAccessMask = dstAccess; dep.srcStageMask = srcStage; + + // initialize the barriers + //node->subpasses[i]->InitComputeBarriers(); } } } @@ -353,6 +378,8 @@ namespace SHADE renderGraphStorage->resourceManager = resourceManager; renderGraphStorage->descriptorPool = logicalDevice->CreateDescriptorPools(); + + renderGraphStorage->ptrToResources = &graphResources; } /***************************************************************************/ @@ -459,7 +486,7 @@ namespace SHADE } } - nodes.emplace_back(resourceManager->Create(renderGraphStorage, std::move(descInitParams), std::move(predecessors), &graphResources)); + 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]); } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h index 9dbfa6d3..529476cf 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h @@ -57,10 +57,6 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER VARIABLES */ /*-----------------------------------------------------------------------*/ - //Handle logicalDeviceHdl; - - //! swapchain used for querying image count - //Handle swapchainHdl; Handle renderGraphStorage; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp index 48855806..0d88a93a 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp @@ -83,6 +83,11 @@ namespace SHADE framebuffers[i]->HandleResize(renderpass, imageViews, fbWidth, fbHeight); } + + for (auto& subpass : subpasses) + { + subpass->HandleResize(); + } } /***************************************************************************/ @@ -105,7 +110,7 @@ namespace SHADE */ /***************************************************************************/ - SHRenderGraphNode::SHRenderGraphNode(Handle renderGraphStorage, std::vector attDescInitParams, std::vector> predecessors, std::unordered_map> const* resources) noexcept + SHRenderGraphNode::SHRenderGraphNode(Handle renderGraphStorage, std::vector attDescInitParams, std::vector> predecessors) noexcept : graphStorage{ renderGraphStorage} , renderpass{} , framebuffers{} @@ -116,7 +121,6 @@ namespace SHADE , subpasses{} , executed{ false } , configured{ false } - , ptrToResources{ resources } { // pipeline library initialization pipelineLibrary.Init(graphStorage->logicalDevice); @@ -173,7 +177,6 @@ namespace SHADE , subpassIndexing{ std::move(rhs.subpassIndexing) } , configured{ rhs.configured } , executed{ rhs.executed } - , ptrToResources{ rhs.ptrToResources } , pipelineLibrary{ std::move(rhs.pipelineLibrary) } , batcher{ std::move(rhs.batcher) } , spDescs{ std::move(rhs.spDescs) } @@ -197,7 +200,6 @@ namespace SHADE subpasses = std::move(rhs.subpasses); resourceAttachmentMapping = std::move(rhs.resourceAttachmentMapping); subpassIndexing = std::move(rhs.subpassIndexing); - ptrToResources = std::move(rhs.ptrToResources); pipelineLibrary = std::move(rhs.pipelineLibrary); batcher = std::move(rhs.batcher); spDescs = std::move(rhs.spDescs); @@ -233,7 +235,7 @@ namespace SHADE } // Add subpass to container and create mapping for it - subpasses.emplace_back(graphStorage->resourceManager->Create(graphStorage, GetHandle(), subpasses.size(), &resourceAttachmentMapping, ptrToResources)); + subpasses.emplace_back(graphStorage->resourceManager->Create(graphStorage, GetHandle(), subpasses.size(), &resourceAttachmentMapping)); subpassIndexing.try_emplace(subpassName, static_cast(subpasses.size()) - 1u); Handle subpass = subpasses.back(); subpass->Init(*graphStorage->resourceManager); diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h index 04638c37..7c3622ad 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h @@ -64,9 +64,6 @@ namespace SHADE //! For indexing subpasses std::map subpassIndexing; - //! Pointer to resources in the render graph (for getting handle IDs) - std::unordered_map> const* ptrToResources; - //! Every renderpass will require a pipeline library that will contain pipelines compatible with this renderpass SHPipelineLibrary pipelineLibrary; @@ -89,7 +86,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* CTORS AND DTORS */ /*-----------------------------------------------------------------------*/ - SHRenderGraphNode(Handle renderGraphStorage, std::vector attDescInitParams, std::vector> predecessors, std::unordered_map> const* resources) noexcept; + SHRenderGraphNode(Handle renderGraphStorage, std::vector attDescInitParams, std::vector> predecessors) noexcept; SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept; SHRenderGraphNode& operator= (SHRenderGraphNode&& rhs) noexcept; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp index d3f20665..651ba88b 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp @@ -308,6 +308,7 @@ namespace SHADE return resourceFormat; } + uint32_t SHRenderGraphResource::GetWidth(void) const noexcept { return width; @@ -323,4 +324,14 @@ namespace SHADE return imageViews [index]; } + Handle SHRenderGraphResource::GetImage(uint32_t index /*= NON_SWAPCHAIN_RESOURCE_INDEX*/) const noexcept + { + return images[index]; + } + + uint8_t SHRenderGraphResource::GetMipLevels(void) const noexcept + { + return mipLevels; + } + } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h index 4bdecc49..55f25864 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h @@ -82,12 +82,15 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ /*-----------------------------------------------------------------------*/ - vk::Format GetResourceFormat (void) const noexcept; - uint32_t GetWidth (void) const noexcept; - uint32_t GetHeight (void) const noexcept; - Handle GetImageView (uint32_t index = NON_SWAPCHAIN_RESOURCE_INDEX) const noexcept; + vk::Format GetResourceFormat (void) const noexcept; + uint32_t GetWidth (void) const noexcept; + uint32_t GetHeight (void) const noexcept; + Handle GetImageView (uint32_t index = NON_SWAPCHAIN_RESOURCE_INDEX) const noexcept; + Handle GetImage (uint32_t index = NON_SWAPCHAIN_RESOURCE_INDEX) const noexcept; + uint8_t GetMipLevels (void) const noexcept; friend class SHRenderGraphNode; friend class SHRenderGraph; + friend class SHSubpass; }; } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h index 9fcc4528..cb274697 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h @@ -24,6 +24,9 @@ namespace SHADE //! Descriptor pool for the descriptor sets to be created in the subpasses Handle descriptorPool; + //! For accessing resources anyone in the graph + std::unordered_map> const* ptrToResources; + friend class SHRenderGraph; friend class SHRenderGraphNode; friend class SHSubpass; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp index 3daafb8f..e6472c52 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp @@ -8,6 +8,10 @@ #include "SHRenderGraphNode.h" #include "SHRenderGraphStorage.h" #include "Graphics/RenderGraph/SHSubpassCompute.h" +#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" +#include "Graphics/Swapchain/SHVkSwapchain.h" +#include "Graphics/Images/SHVkSampler.h" +#include "SHRenderGraphResource.h" namespace SHADE { @@ -27,9 +31,8 @@ namespace SHADE */ /***************************************************************************/ - SHSubpass::SHSubpass(Handle renderGraphStorage, Handle const& parent, uint32_t index, std::unordered_map const* mapping, std::unordered_map> const* resources) noexcept + SHSubpass::SHSubpass(Handle renderGraphStorage, Handle const& parent, uint32_t index, std::unordered_map const* mapping) noexcept : resourceAttachmentMapping{ mapping } - , ptrToResources{ resources } , parentNode{ parent } , subpassIndex{ index } , superBatch{} @@ -37,6 +40,8 @@ namespace SHADE , depthReferences{} , inputReferences{} , graphStorage{ renderGraphStorage } + , subpassComputes{} + , inputImageDescriptors {SHGraphicsConstants::NUM_FRAME_BUFFERS} { } @@ -59,10 +64,10 @@ namespace SHADE , depthReferences{ std::move(rhs.depthReferences) } , inputReferences{ std::move(rhs.inputReferences) } , resourceAttachmentMapping{ rhs.resourceAttachmentMapping } - , ptrToResources{ rhs.ptrToResources } , descriptorSetLayout{ rhs.descriptorSetLayout } , exteriorDrawCalls{ std::move(rhs.exteriorDrawCalls) } , graphStorage{ std::move(rhs.graphStorage) } + , subpassComputes{std::move (rhs.subpassComputes)} { } @@ -90,10 +95,10 @@ namespace SHADE depthReferences = std::move(rhs.depthReferences); inputReferences = std::move(rhs.inputReferences); resourceAttachmentMapping = rhs.resourceAttachmentMapping; - ptrToResources = rhs.ptrToResources; descriptorSetLayout = rhs.descriptorSetLayout; exteriorDrawCalls = std::move(rhs.exteriorDrawCalls); graphStorage = std::move(rhs.graphStorage); + subpassComputes = std::move(rhs.subpassComputes); return *this; } @@ -112,7 +117,7 @@ namespace SHADE /***************************************************************************/ void SHSubpass::AddColorOutput(std::string resourceToReference) noexcept { - colorReferences.push_back({ resourceAttachmentMapping->at(ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eColorAttachmentOptimal }); + colorReferences.push_back({ resourceAttachmentMapping->at(graphStorage->ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eColorAttachmentOptimal }); } /***************************************************************************/ @@ -149,7 +154,7 @@ namespace SHADE //Invalid return; } - depthReferences.push_back({ resourceAttachmentMapping->at(ptrToResources->at(resourceToReference).GetId().Raw), imageLayout }); + depthReferences.push_back({ resourceAttachmentMapping->at(graphStorage->ptrToResources->at(resourceToReference).GetId().Raw), imageLayout }); } /***************************************************************************/ @@ -166,7 +171,15 @@ namespace SHADE /***************************************************************************/ void SHSubpass::AddInput(std::string resourceToReference) noexcept { - inputReferences.push_back({ resourceAttachmentMapping->at(ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eShaderReadOnlyOptimal }); + inputReferences.push_back({ resourceAttachmentMapping->at(graphStorage->ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eShaderReadOnlyOptimal }); + + inputNames.push_back(resourceToReference); + } + + void SHSubpass::AddGeneralInput(std::string resourceToReference) noexcept + { + inputReferences.push_back({ resourceAttachmentMapping->at(graphStorage->ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eGeneral }); + } void SHSubpass::Execute(Handle& commandBuffer, Handle descPool, uint32_t frameIndex) noexcept @@ -182,6 +195,17 @@ namespace SHADE { drawCall(commandBuffer); } + + // if there are subpass computes, transition all to GENERAL layout first + for (auto& sbCompute : subpassComputes) + { + + } + } + + void SHSubpass::HandleResize(void) noexcept + { + UpdateWriteDescriptors(); } void SHSubpass::AddExteriorDrawCalls(std::function&)> const& newDrawCall) noexcept @@ -189,9 +213,27 @@ namespace SHADE exteriorDrawCalls.push_back(newDrawCall); } - Handle SHSubpass::ActivateSubpassCompute(Handle computeShaderModule, std::initializer_list resources) noexcept + Handle SHSubpass::AddSubpassCompute(Handle computeShaderModule/*, std::initializer_list resources*/) noexcept { - subpassCompute = graphStorage->resourceManager->Create(graphStorage, computeShaderModule, resources); + //// for the subpass compute to store indices to the resources, see member comments + //std::unordered_set attDescIndices{}; + //attDescIndices.reserve (resources.size()); + + //// Look for the required resources in the graph + //std::vector> subpassComputeResources{}; + //subpassComputeResources.reserve(resources.size()); + + //for (auto& resourceName : resources) + //{ + // auto resource = graphStorage->ptrToResources->at(resourceName); + // subpassComputeResources.push_back(resource); + // attDescIndices.emplace(resourceAttachmentMapping->at (resource.GetId().Raw)); + //} + + // Create the subpass compute with the resources + auto subpassCompute = graphStorage->resourceManager->Create(graphStorage, computeShaderModule/*, std::move(subpassComputeResources), std::move (attDescIndices)*/); + subpassComputes.push_back(subpassCompute); + return subpassCompute; } @@ -201,6 +243,145 @@ namespace SHADE } + void SHSubpass::CreateInputDescriptors(void) noexcept + { + //std::vector bindings{}; + + //for (auto& input : inputReferences) + //{ + // SHVkDescriptorSetLayout::Binding newBinding + // { + // .Type = (input.layout == vk::ImageLayout::eShaderReadOnlyOptimal) ? vk::DescriptorType::eInputAttachment : vk::DescriptorType::eStorageImage, + // .Stage = vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eCompute, + // .BindPoint = static_cast(bindings.size()), + // .DescriptorCount = 1, + // .flags = {}, + // }; + + // bindings.push_back(newBinding); + //} + + //// We build a new descriptor set layout to store our images + //inputDescriptorLayout = graphStorage->logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, bindings); + + //// we store a sampler if its an input attachment. if it is storage image, no need sampler, store an empty handle. + //for (uint32_t i = 0; i < bindings.size(); ++i) + //{ + // if (bindings[i].Type == vk::DescriptorType::eInputAttachment) + // { + // auto newSampler = graphStorage->logicalDevice->CreateSampler(SHVkSamplerParams + // { + // .minFilter = vk::Filter::eLinear, + // .magFilter = vk::Filter::eLinear, + // .addressMode = vk::SamplerAddressMode::eRepeat, + // .mipmapMode = vk::SamplerMipmapMode::eLinear, + // .minLod = -1000, + // .maxLod = 1000 + // } + // ); + + // inputSamplers.push_back(newSampler); + // } + // else + // { + // inputSamplers.push_back({}); + // } + //} + + //// maybe do this in handle resize? + //UpdateWriteDescriptors(); + } + + void SHSubpass::UpdateWriteDescriptors(void) noexcept + { + //auto const& bindings = inputDescriptorLayout->GetBindings(); + + //std::vector variableCounts{ static_cast(bindings.size()), 0 }; + + //uint32_t i = 0; + + //// For every frame's descriptor set + //for (auto& group : inputImageDescriptors) + //{ + // if (group) + // group.Free(); + + // group = graphStorage->descriptorPool->Allocate({ inputDescriptorLayout }, variableCounts); + + // for (auto& binding : bindings) + // { + // // get the resource + // auto resource = graphStorage->ptrToResources->at(inputNames[binding.BindPoint]); + + // // If resource is swapchain image, get the correct image, if not just get 0. + // uint32_t viewIndex = (resource->resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) ? i : 0; + + // // layout is GENERAL if image is meant to be used as storage image, if not use SHADER_READ_ONLY_OPTINAL + // vk::ImageLayout descriptorLayout = (binding.Type == vk::DescriptorType::eStorageImage) ? vk::ImageLayout::eGeneral : vk::ImageLayout::eShaderReadOnlyOptimal; + + // // Update descriptor sets + // auto args = std::make_tuple(resource->GetImageView(viewIndex), inputSamplers[i], descriptorLayout); + // group->ModifyWriteDescImage(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint, std::span{&args, 1}); + // group->UpdateDescriptorSetImages(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint); + // } + + // ++i; + //} + } + + //void SHSubpass::InitComputeBarriers(void) noexcept + //{ + // std::unordered_set handleBarriers{}; + + // // we will have swapchainNumImages vectors of vector of barriers + // subpassComputeBarriers.resize(graphStorage->swapchain->GetNumImages()); + + // for (auto sbCompute : subpassComputes) + // { + // // for every resource the subpass compute is using + // for (auto resource : sbCompute->resources) + // { + // // Get the resource handle + // uint64_t resourceRaw = resource.GetId().Raw; + + // // if the barrier is not registered + // if (!handleBarriers.contains(resourceRaw)) + // { + // // If the resource is a swapchain image + // bool isSwapchainImage = (resource->resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)); + // for (uint32_t i = 0; i < graphStorage->swapchain->GetNumImages(); ++i) + // { + // // if swapchain image, we want the index of the swapchain image, if not take base image + // uint32_t imageIndex = isSwapchainImage ? i : 0; + + // // Prepare image barrier + // vk::ImageMemoryBarrier imageBarrier + // { + // .oldLayout = colorReferences[resourceAttachmentMapping->at(resource.GetId().Raw)].layout, + // .newLayout = vk::ImageLayout::eGeneral, + // .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + // .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + // .image = resource->GetImage(imageIndex)->GetVkImage(), + // .subresourceRange = + // { + // .aspectMask = resource->imageAspectFlags, + // .levelCount = resource->GetMipLevels(), + // .baseArrayLayer = 0, + // .layerCount = 1 + // } + // }; + + // // push the barrier + // subpassComputeBarriers[i].push_back(imageBarrier); + // } + + // // Image transition registered + // handleBarriers.emplace(resourceRaw); + // } + // } + // } + //} + /***************************************************************************/ /*! diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h index 71496b92..48874a06 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h @@ -14,10 +14,12 @@ namespace SHADE class SHRenderGraphResource; class SHVkCommandBuffer; class SHVkDescriptorSetLayout; + class SHVkDescriptorSetGroup; class SHVkDescriptorPool; class SHRenderGraphStorage; class SHSubpassCompute; class SHVkShaderModule; + class SHVkSampler; class SH_API SHSubpass : public ISelfHandle { @@ -25,38 +27,52 @@ namespace SHADE /*---------------------------------------------------------------------*/ /* PRIVATE MEMBER VARIABLES */ /*---------------------------------------------------------------------*/ - Handle graphStorage; + Handle graphStorage; //! The index of the subpass in the render graph - uint32_t subpassIndex; + uint32_t subpassIndex; //! The parent renderpass that this subpass belongs to - Handle parentNode; + Handle parentNode; //! - Handle superBatch; + Handle superBatch; //! Descriptor set layout to hold attachments - Handle descriptorSetLayout; + Handle descriptorSetLayout; //! Color attachments - std::vector colorReferences; + std::vector colorReferences; //! Depth attachments - std::vector depthReferences; + std::vector depthReferences; //! Input attachments - std::vector inputReferences; + std::vector inputReferences; + + //! This is mainly for when we want to retrieve resources using names. + std::vector inputNames; //! For getting attachment reference indices using handles std::unordered_map const* resourceAttachmentMapping; - //! Pointer to resources in the render graph (for getting handle IDs) - std::unordered_map> const* ptrToResources; + //! Descriptor set group to hold the images for input + std::vector> inputImageDescriptors; + + //! Descriptor set layout for allocating descriptor set for inputs + Handle inputDescriptorLayout; + + std::vector> inputSamplers; //! Sometimes we want the subpass to do something to the images instead //! of drawing objects on the image (i.e. compute). - Handle subpassCompute; + std::vector> subpassComputes; + + ////! subpass compute image barriers. We do this because every frame has a different + ////! swapchain image. If the resource we want to transition is not a swapchain image, + ////! we duplicate the barrier anyway, not much memory wasted. ;) + //std::vector> subpassComputeBarriers{}; + //! Sometimes there exists entities that we want to render onto a render target //! but don't want it to come from the batching system. An example would be ImGUI. @@ -71,7 +87,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* CTORS AND DTORS */ /*-----------------------------------------------------------------------*/ - SHSubpass(Handle renderGraphStorage, Handle const& parent, uint32_t index, std::unordered_map const* mapping, std::unordered_map> const* ptrToResources) noexcept; + SHSubpass(Handle renderGraphStorage, Handle const& parent, uint32_t index, std::unordered_map const* mapping) noexcept; SHSubpass(SHSubpass&& rhs) noexcept; SHSubpass& operator=(SHSubpass&& rhs) noexcept; @@ -82,14 +98,20 @@ namespace SHADE void AddColorOutput(std::string resourceToReference) noexcept; void AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE_FLAGS attachmentDescriptionType = SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL) noexcept; void AddInput(std::string resourceToReference) noexcept; + void AddGeneralInput (std::string resourceToReference) noexcept; + void AddExteriorDrawCalls(std::function&)> const& newDrawCall) noexcept; // Runtime functions void Execute(Handle& commandBuffer, Handle descPool, uint32_t frameIndex) noexcept; - void AddExteriorDrawCalls(std::function&)> const& newDrawCall) noexcept; + void HandleResize (void) noexcept; - Handle ActivateSubpassCompute(Handle computeShaderModule, std::initializer_list resources) noexcept; + Handle AddSubpassCompute(Handle computeShaderModule/*, std::initializer_list resources*/) noexcept; void Init(ResourceManager& resourceManager) noexcept; + + //void InitComputeBarriers (void) noexcept; + void CreateInputDescriptors (void) noexcept; + void UpdateWriteDescriptors (void) noexcept; /*-----------------------------------------------------------------------*/ /* GETTERS AND SETTERS */ @@ -102,5 +124,6 @@ namespace SHADE friend class SHRenderGraphNode; friend class SHRenderGraph; + friend class SHSubpass; }; } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp index f30fa85f..79242c7d 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp @@ -11,25 +11,43 @@ namespace SHADE { - SHSubpassCompute::SHSubpassCompute(Handle graphStorage, Handle computeShaderModule, std::initializer_list resources) noexcept + SHSubpassCompute::SHSubpassCompute(Handle graphStorage, Handle computeShaderModule/*, std::vector>&& subpassComputeResources, std::unordered_set&& attDescIndices*/) noexcept : pipeline{} { SHPipelineLayoutParams pipelineLayoutParams { + .shaderModules = {computeShaderModule}, .globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts() }; - //pipeline = logicalDevice->CreateComputePipeline() + // Create descriptor set from + pipelineLayout = graphStorage->logicalDevice->CreatePipelineLayout (pipelineLayoutParams); - // Get the descriptor set layouts required to allocate. we will bind a different pipeline layout, one that includes the layout for global. - auto const& layouts = pipeline->GetPipelineLayout()->GetDescriptorSetLayoutsAllocate(); + // Create the compute pipeline + pipeline = graphStorage->logicalDevice->CreateComputePipeline(pipelineLayout); + + pipeline->ConstructPipeline(); + + // Get the descriptor set layouts required to allocate. We only want the ones for allocate because + // global descriptors are already bound in the main system. + //auto const& layouts = pipeline->GetPipelineLayout()->GetDescriptorSetLayoutsAllocate(); // Variable counts for the descriptor sets (all should be 1). - std::vector variableCounts{ static_cast(layouts.size()) }; - std::fill(variableCounts.begin(), variableCounts.end(), 0); + //std::vector variableCounts{ static_cast(layouts.size()) }; + //std::fill(variableCounts.begin(), variableCounts.end(), 0); - // Allocate descriptor sets to hold the images for reading (STORAGE_IMAGE) - descSetGroup = graphStorage->descriptorPool->Allocate(layouts, variableCounts); + //// Allocate descriptor sets to hold the images for reading (STORAGE_IMAGE) + //descSetGroup = graphStorage->descriptorPool->Allocate(layouts, variableCounts); + + //// save the resources + //resources = std::move (subpassComputeResources); + + //// we save this because when we configure the graph, we want to make sure final layouts + //// of attachment descriptions are set to GENERAL. See ConfigureAttachmentDescriptions in SHRenderGraph.cpp. + //attachmentDescriptionIndices = std::move (attDescIndices); + + //descSetGroup->ModifyWriteDescImage (SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, ) } + //SHSubpass } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.h b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.h index 8dfc361e..aae2a9b9 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.h @@ -3,6 +3,7 @@ #include "Resource/Handle.h" #include #include +#include namespace SHADE { @@ -12,26 +13,37 @@ namespace SHADE class SHVkLogicalDevice; class SHVkPipelineLayout; class SHRenderGraphStorage; + class SHRenderGraphResource; class SHVkShaderModule; class SHSubpassCompute { private: //! To run the dispatch command - Handle pipeline; + Handle pipeline; - //! Pipeline layout for the pipline creation - Handle pipelineLayout; + //! Pipeline layout for the pipeline creation + Handle pipelineLayout; - //! Descriptor set group to hold the images for reading (STORAGE_IMAGE) - Handle descSetGroup; + ////! Descriptor set group to hold the images for reading (STORAGE_IMAGE) + //Handle descSetGroup; - //! Required resources to be used in the descriptors - std::vector resourcesRequired; + ////! Required resources to be used in the descriptors + //std::vector resourcesRequired; + + ////! vector of resources needed by the subpass compute + //std::vector> resources; + + ////! we save this because when we configure the graph, we want to make sure final layouts + ////! of attachment descriptions are set to GENERAL. See ConfigureAttachmentDescriptions in SHRenderGraph.cpp. + //std::unordered_set attachmentDescriptionIndices{}; public: - SHSubpassCompute(Handle graphStorage, Handle computeShaderModule, std::initializer_list resources) noexcept; + SHSubpassCompute(Handle graphStorage, Handle computeShaderModule/*, std::vector>&& subpassComputeResources, std::unordered_set&& attDescIndices*/) noexcept; + //void ExecuteSubpass (void) noexcept; + friend class SHRenderGraph; + friend class SHSubpass; }; } diff --git a/SHADE_Engine/src/Graphics/Shaders/SHShaderReflected.cpp b/SHADE_Engine/src/Graphics/Shaders/SHShaderReflected.cpp index 41327988..e635f763 100644 --- a/SHADE_Engine/src/Graphics/Shaders/SHShaderReflected.cpp +++ b/SHADE_Engine/src/Graphics/Shaders/SHShaderReflected.cpp @@ -177,6 +177,9 @@ namespace SHADE return vk::DescriptorType::eStorageBufferDynamic; case SpvReflectDescriptorType::SPV_REFLECT_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: return vk::DescriptorType::eInputAttachment; + case SpvReflectDescriptorType::SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE: + return vk::DescriptorType::eStorageImage; + break; default: return vk::DescriptorType::eCombinedImageSampler; break; diff --git a/TempShaderFolder/GreyscaleCs.glsl b/TempShaderFolder/GreyscaleCs.glsl new file mode 100644 index 00000000..3167a57c --- /dev/null +++ b/TempShaderFolder/GreyscaleCs.glsl @@ -0,0 +1,38 @@ +/* Start Header *****************************************************************/ + +/*! \file (e.g. kirsch.comp) + + \author William Zheng, william.zheng, 60001906. Brandon Mak, brandon.hao 390003920. + + \par william.zheng\@digipen.edu. brandon.hao\@digipen.edu. + + \date Sept 20, 2022 + + \brief Copyright (C) 20xx 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. */ + + /* End Header *******************************************************************/ + +#version 450 + +layout(local_size_x = 16, local_size_y = 16) in; +layout(set = 4, binding = 0, rgba8) uniform image2D targetImage; + + +void main() +{ + // load the image + vec4 color = imageLoad (targetImage, ivec2 (gl_GlobalInvocationID)); + + // get the average + float average = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b; + + // store result into result image + imageStore(targetImage, ivec2(gl_GlobalInvocationID), vec4(average, average, average, 1.0f)); + +} + + + + diff --git a/TempShaderFolder/GreyscaleCs.spv b/TempShaderFolder/GreyscaleCs.spv new file mode 100644 index 0000000000000000000000000000000000000000..5b36e00317061a12d75127def8a67c940e8969c6 GIT binary patch literal 1400 zcmZ9K+fEZv6o$97g$e>9Ld9b%o)E04oRoku(M*~&0pb-`lVLh(CK*~%#wI3S=!H+< zjql+b_yoRy@8OM!|2NDsqkFQl*8i{5UTaTjWO2;7b8g&Cx@~uMX55Gv=O)}}roHyt zcJnmtG}qQwiI{SwERdLK#Z;urlH(xm;h2$J6c2Z1gX!XwSyFZ9z6+Gq)oc6S-k#Tf zfbRiXw{r!ROT@>?i$!bVc6<=`~7t}_mcimkhFTkei)>2zt?)5<&@oZ>0lTQi1$>J8n-3%GTe~O0W<4_ zggo$z94|=EYHH?gWE*gqJuiDyTwPLAydEOM)UOLyrQwhTO*Ae|yjJ(mp|0i7pF`}n zSTOhI%n46P*8w{8oR)^;Md@kp1W!Jgx#&s$taLrc;VzioHzgeNv*W|s=1cQ03e(^G4`hG+`DMraOTzRs|E6r`KK{*rF2o!w>dsue z3mii24gC$aL&0p8Ut;*L*#Yms|HK?%X5x*(JHqUGQo^3W^tdEpZy$u&(Ok|Qs4Dxa z<(!l=?n=%v>%QXHCI1ew_>RQU^Qwe?_;z($?gsZte(rWl0>@stkNsotpA`dcNO*_3 z#PaUQCXbz1-d)-7mUmA!?*soSuXSHG_3&A(hq9@)B(Yk{vf-`PifrBz-fBIPO+9?f z#-8D*!JeCv;+`K17x%m>3}-uiA{&ll+*8?b#XUb0CKjLFcTG0^4X^))H*&nMSK(c@ WB;*i>kN+^#y}2{>@&8uWEy*9dZd@?{ literal 0 HcmV?d00001 From 304071cb0abc4d629bcf25aab651b73f87061028 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Sat, 22 Oct 2022 00:42:50 +0800 Subject: [PATCH 13/50] Apparently static keyword gives error but it compiles --- SHADE_Engine/src/Resource/SHResourceManager.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SHADE_Engine/src/Resource/SHResourceManager.hpp b/SHADE_Engine/src/Resource/SHResourceManager.hpp index cff4e84b..fb0dcc6a 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.hpp +++ b/SHADE_Engine/src/Resource/SHResourceManager.hpp @@ -134,7 +134,7 @@ namespace SHADE /* Query Functions */ /*-----------------------------------------------------------------------------------*/ template - std::optional SHResourceManager::GetAssetID(Handle handle) + static std::optional SHResourceManager::GetAssetID(Handle handle) { const Handle GENERIC_HANDLE = Handle(handle); auto [typedHandleMap, typedAssetIdMap] = getAssetHandleMap(); From db751bd1418955f3b35be6e384aeedff65cdf438 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Sat, 22 Oct 2022 18:22:26 +0800 Subject: [PATCH 14/50] Editor & Scripts can now override Physics-Based objects' Transforms --- Assets/Editor/Layouts/UserLayout.ini | 2 +- .../src/Application/SBApplication.cpp | 4 +- .../src/Math/Transform/SHTransformSystem.cpp | 44 +++++++++++++++++-- .../src/Math/Transform/SHTransformSystem.h | 42 +++++++++++++++--- 4 files changed, 80 insertions(+), 12 deletions(-) diff --git a/Assets/Editor/Layouts/UserLayout.ini b/Assets/Editor/Layouts/UserLayout.ini index 396b853b..7b0a70f8 100644 --- a/Assets/Editor/Layouts/UserLayout.ini +++ b/Assets/Editor/Layouts/UserLayout.ini @@ -38,7 +38,7 @@ Collapsed=0 DockId=0x00000002,0 [Docking][Data] -DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=-227,-1256 Size=1920,1012 Split=X +DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,79 Size=1920,1012 Split=X DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1481,1036 Split=X DockNode ID=0x00000001 Parent=0x00000005 SizeRef=349,1036 Split=Y Selected=0x1E6EB881 DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,94 Selected=0x1E6EB881 diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index 8733e7b9..3675e275 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -83,11 +83,13 @@ namespace Sandbox SHSystemManager::RegisterRoutine(); SHSystemManager::RegisterRoutine(); + SHSystemManager::RegisterRoutine(); + SHSystemManager::RegisterRoutine(); SHSystemManager::RegisterRoutine(); SHSystemManager::RegisterRoutine(); - SHSystemManager::RegisterRoutine(); + SHSystemManager::RegisterRoutine(); SHSystemManager::RegisterRoutine(); SHSystemManager::RegisterRoutine(); diff --git a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp index a3ca3e75..4b4f1cce 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp +++ b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp @@ -28,8 +28,12 @@ namespace SHADE /* Constructors & Destructor Definitions */ /*-----------------------------------------------------------------------------------*/ - SHTransformSystem::TransformUpdateRoutine::TransformUpdateRoutine() - : SHSystemRoutine { "Transform Update", true } + SHTransformSystem::TransformPostLogicUpdate::TransformPostLogicUpdate() + : SHSystemRoutine { "Transform Post-Logic Update", true } + {} + + SHTransformSystem::TransformPostPhysicsUpdate::TransformPostPhysicsUpdate() + : SHSystemRoutine { "Transform Post-Physics Update", false } {} @@ -37,13 +41,20 @@ namespace SHADE /* Public Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ - void SHTransformSystem::TransformUpdateRoutine::Execute(double) noexcept + void SHTransformSystem::TransformPostLogicUpdate::Execute(double) noexcept { // Get the current scene graph to traverse and update const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph(); UpdateEntity(SCENE_GRAPH.GetRoot()); } + void SHTransformSystem::TransformPostPhysicsUpdate::Execute(double dt) noexcept + { + // Get the current scene graph to traverse and update + const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph(); + UpdateEntityAndClear(SCENE_GRAPH.GetRoot()); + } + void SHTransformSystem::Init() { std::shared_ptr thisReceiver { std::make_shared>(this, &SHTransformSystem::ChangeParent) }; @@ -175,6 +186,33 @@ namespace SHADE } UpdateEntity(child); + } + } + + + void SHTransformSystem::UpdateEntityAndClear(const SHSceneNode* node) + { + const auto* NODE_TRANSFORM = SHComponentManager::GetComponent_s(node->GetEntityID()); + const bool HAS_PARENT_CHANGED = NODE_TRANSFORM && NODE_TRANSFORM->dirty; + + for (const auto* child : node->GetChildren()) + { + auto* childTransform = SHComponentManager::GetComponent_s(child->GetEntityID()); + if (childTransform) + { + // Only update if node in hierarchy and component are both active + const bool IS_NODE_ACTIVE = child->IsActive(); + if (IS_NODE_ACTIVE && childTransform->isActive) + { + if (childTransform->dirty || HAS_PARENT_CHANGED) + { + UpdateTransform(*childTransform, NODE_TRANSFORM); + childTransform->dirty = true; + } + } + } + + UpdateEntityAndClear(child); // Clear dirty flag after all children are updated if (childTransform) diff --git a/SHADE_Engine/src/Math/Transform/SHTransformSystem.h b/SHADE_Engine/src/Math/Transform/SHTransformSystem.h index 95957830..256c1561 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformSystem.h +++ b/SHADE_Engine/src/Math/Transform/SHTransformSystem.h @@ -45,25 +45,52 @@ namespace SHADE /* System Routines */ /*---------------------------------------------------------------------------------*/ - class SH_API TransformUpdateRoutine final: public SHSystemRoutine + class SH_API TransformPostLogicUpdate final: public SHSystemRoutine { public: /*-------------------------------------------------------------------------------*/ /* Constructors & Destructor */ /*-------------------------------------------------------------------------------*/ - TransformUpdateRoutine (); - ~TransformUpdateRoutine () = default; + TransformPostLogicUpdate (); + ~TransformPostLogicUpdate () = default; - TransformUpdateRoutine (const TransformUpdateRoutine&) = delete; - TransformUpdateRoutine (TransformUpdateRoutine&&) = delete; + TransformPostLogicUpdate (const TransformPostLogicUpdate&) = delete; + TransformPostLogicUpdate (TransformPostLogicUpdate&&) = delete; /*-------------------------------------------------------------------------------*/ /* Operator Overloads */ /*-------------------------------------------------------------------------------*/ - TransformUpdateRoutine& operator= (const TransformUpdateRoutine&) = delete; - TransformUpdateRoutine& operator= (TransformUpdateRoutine&&) = delete; + TransformPostLogicUpdate& operator= (const TransformPostLogicUpdate&) = delete; + TransformPostLogicUpdate& operator= (TransformPostLogicUpdate&&) = delete; + + /*-------------------------------------------------------------------------------*/ + /* Function Members */ + /*-------------------------------------------------------------------------------*/ + + void Execute(double dt) noexcept override; + }; + + class SH_API TransformPostPhysicsUpdate final: public SHSystemRoutine + { + public: + /*-------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*-------------------------------------------------------------------------------*/ + + TransformPostPhysicsUpdate (); + ~TransformPostPhysicsUpdate () = default; + + TransformPostPhysicsUpdate (const TransformPostPhysicsUpdate&) = delete; + TransformPostPhysicsUpdate (TransformPostPhysicsUpdate&&) = delete; + + /*-------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*-------------------------------------------------------------------------------*/ + + TransformPostPhysicsUpdate& operator= (const TransformPostPhysicsUpdate&) = delete; + TransformPostPhysicsUpdate& operator= (TransformPostPhysicsUpdate&&) = delete; /*-------------------------------------------------------------------------------*/ /* Function Members */ @@ -88,6 +115,7 @@ namespace SHADE static void UpdateChildrenLocalTransforms (SHSceneNode* node); static void UpdateEntity (const SHSceneNode* node); + static void UpdateEntityAndClear (const SHSceneNode* node); static void UpdateTransform (SHTransformComponent& tf, const SHTransformComponent* parent = nullptr); }; From ebfcf1c6bbbeae4c8a16c7d96ed3be9b4205fb6c Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Sat, 22 Oct 2022 20:16:38 +0800 Subject: [PATCH 15/50] Transform now stores orientation as Quaternions. Interface unchanged --- SHADE_Application/src/Scenes/SBTestScene.cpp | 6 +- SHADE_Engine/src/Math/SHMatrix.cpp | 81 +++----- SHADE_Engine/src/Math/SHMatrix.h | 2 + SHADE_Engine/src/Math/SHQuaternion.cpp | 174 +++++++----------- SHADE_Engine/src/Math/SHQuaternion.h | 9 +- .../src/Math/Transform/SHTransform.cpp | 18 +- SHADE_Engine/src/Math/Transform/SHTransform.h | 22 +-- .../Math/Transform/SHTransformComponent.cpp | 78 +++----- .../src/Math/Transform/SHTransformComponent.h | 36 ++-- .../src/Math/Transform/SHTransformSystem.cpp | 75 ++++---- .../src/Math/Transform/SHTransformSystem.h | 3 +- SHADE_Engine/src/Physics/SHPhysicsObject.cpp | 6 +- 12 files changed, 209 insertions(+), 301 deletions(-) diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index be09768b..23259ee4 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -104,10 +104,10 @@ namespace Sandbox transform.SetWorldRotation(SHMath::GenerateRandomNumber(), SHMath::GenerateRandomNumber(), SHMath::GenerateRandomNumber()); transform.SetWorldScale(TEST_OBJ_SCALE); - if (const bool IS_EVEN = (y * NUM_ROWS + x) % 2; IS_EVEN) + //if (const bool IS_EVEN = (y * NUM_ROWS + x) % 2; IS_EVEN) collider.AddBoundingBox(SHVec3::One * 0.5f, SHVec3::Zero); - else - collider.AddBoundingSphere(0.5f, SHVec3::Zero); + //else + // collider.AddBoundingSphere(0.5f, SHVec3::Zero); stressTestObjects.emplace_back(entity); } diff --git a/SHADE_Engine/src/Math/SHMatrix.cpp b/SHADE_Engine/src/Math/SHMatrix.cpp index 571fa4e0..ec3951e2 100644 --- a/SHADE_Engine/src/Math/SHMatrix.cpp +++ b/SHADE_Engine/src/Math/SHMatrix.cpp @@ -295,32 +295,33 @@ namespace SHADE ) != 0; } + SHMatrix::operator XMMATRIX() const noexcept + { + return XMLoadFloat4x4(this); + } + SHMatrix operator*(float lhs, const SHMatrix& rhs) noexcept { return rhs * lhs; } - /*-----------------------------------------------------------------------------------*/ /* Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ void SHMatrix::Transpose() noexcept { - const XMMATRIX M = XMLoadFloat4x4(this); - XMStoreFloat4x4(this, XMMatrixTranspose(M)); + XMStoreFloat4x4(this, XMMatrixTranspose(*this)); } void SHMatrix::Invert() noexcept { - const XMMATRIX M = XMLoadFloat4x4(this); - XMStoreFloat4x4(this, XMMatrixInverse(nullptr, M)); + XMStoreFloat4x4(this, XMMatrixInverse(nullptr, *this)); } float SHMatrix::Determinant() const noexcept { - const XMMATRIX M = XMLoadFloat4x4(this); - return XMVectorGetX(XMMatrixDeterminant(M)); + return XMVectorGetX(XMMatrixDeterminant(*this)); } std::string SHMatrix::ToString() const noexcept @@ -337,9 +338,8 @@ namespace SHADE bool SHMatrix::Decompose(SHVec3& translation, SHVec3& rotation, SHVec3& scale) const noexcept { XMVECTOR s, r, t; - const XMMATRIX M = XMLoadFloat4x4(this); - if (!XMMatrixDecompose(&s, &r, &t, M)) + if (!XMMatrixDecompose(&s, &r, &t, *this)) return false; SHQuaternion orientation; @@ -356,9 +356,8 @@ namespace SHADE bool SHMatrix::Decompose(SHVec3& translation, SHQuaternion& orientation, SHVec3& scale) const noexcept { XMVECTOR s, r, t; - const XMMATRIX M = XMLoadFloat4x4(this); - if (!XMMatrixDecompose(&s, &r, &t, M)) + if (!XMMatrixDecompose(&s, &r, &t, *this)) return false; XMStoreFloat3(&scale, s); @@ -376,8 +375,7 @@ namespace SHADE { SHMatrix result; - const XMMATRIX M = XMLoadFloat4x4(&matrix); - XMStoreFloat4x4(&result, XMMatrixTranspose(M)); + XMStoreFloat4x4(&result, XMMatrixTranspose(matrix)); return result; } @@ -385,8 +383,7 @@ namespace SHADE { SHMatrix result; - const XMMATRIX M = XMLoadFloat4x4(&matrix); - XMStoreFloat4x4(&result, XMMatrixInverse(nullptr, M)); + XMStoreFloat4x4(&result, XMMatrixInverse(nullptr, matrix)); return result; } @@ -401,8 +398,8 @@ namespace SHADE SHMatrix SHMatrix::Translate(const SHVec3& pos) noexcept { SHMatrix result; - XMStoreFloat4x4(&result, XMMatrixTranslation(pos.x, pos.y, pos.z)); + XMStoreFloat4x4(&result, XMMatrixTranslation(pos.x, pos.y, pos.z)); return result; } @@ -410,25 +407,23 @@ namespace SHADE { SHMatrix result; - const XMVECTOR A = XMLoadFloat3(&axis); - XMStoreFloat4x4(&result, XMMatrixRotationAxis(A, angleInRad)); - + XMStoreFloat4x4(&result, XMMatrixRotationAxis(axis, angleInRad)); return result; } SHMatrix SHMatrix::Rotate(float yaw, float pitch, float roll) noexcept { SHMatrix result; - XMStoreFloat4x4(&result, XMMatrixRotationRollPitchYaw(pitch, yaw, roll)); + XMStoreFloat4x4(&result, XMMatrixRotationRollPitchYaw(pitch, yaw, roll)); return result; } SHMatrix SHMatrix::Rotate(const SHVec3& eulerAngles) noexcept { SHMatrix result; - XMStoreFloat4x4(&result, XMMatrixRotationRollPitchYaw(eulerAngles.x, eulerAngles.y, eulerAngles.z)); + XMStoreFloat4x4(&result, XMMatrixRotationRollPitchYawFromVector(eulerAngles)); return result; } @@ -436,57 +431,55 @@ namespace SHADE { SHMatrix result; - const XMVECTOR Q = XMLoadFloat4(&q); - XMStoreFloat4x4(&result, XMMatrixRotationQuaternion(Q)); - + XMStoreFloat4x4(&result, XMMatrixRotationQuaternion(q)); return result; } SHMatrix SHMatrix::RotateX(float angleInRad) noexcept { SHMatrix result; - XMStoreFloat4x4(&result, XMMatrixRotationX(angleInRad)); + XMStoreFloat4x4(&result, XMMatrixRotationX(angleInRad)); return result; } SHMatrix SHMatrix::RotateY(float angleInRad) noexcept { SHMatrix result; - XMStoreFloat4x4(&result, XMMatrixRotationY(angleInRad)); + XMStoreFloat4x4(&result, XMMatrixRotationY(angleInRad)); return result; } SHMatrix SHMatrix::RotateZ(float angleInRad) noexcept { SHMatrix result; - XMStoreFloat4x4(&result, XMMatrixRotationZ(angleInRad)); + XMStoreFloat4x4(&result, XMMatrixRotationZ(angleInRad)); return result; } SHMatrix SHMatrix::Scale(float uniformScaleFactor) noexcept { SHMatrix result; - XMStoreFloat4x4(&result, XMMatrixScaling(uniformScaleFactor, uniformScaleFactor, uniformScaleFactor)); + XMStoreFloat4x4(&result, XMMatrixScaling(uniformScaleFactor, uniformScaleFactor, uniformScaleFactor)); return result; } SHMatrix SHMatrix::Scale(float x, float y, float z) noexcept { SHMatrix result; - XMStoreFloat4x4(&result, XMMatrixScaling(x, y, z)); + XMStoreFloat4x4(&result, XMMatrixScaling(x, y, z)); return result; } SHMatrix SHMatrix::Scale(const SHVec3& scale) noexcept { SHMatrix result; - XMStoreFloat4x4(&result, XMMatrixScaling(scale.x, scale.y, scale.z)); + XMStoreFloat4x4(&result, XMMatrixScalingFromVector(scale)); return result; } @@ -494,12 +487,7 @@ namespace SHADE { SHMatrix result; - const XMVECTOR EYE = XMLoadFloat3(&eye); - const XMVECTOR TGT = XMLoadFloat3(&target); - const XMVECTOR UP = XMLoadFloat3(&up); - - XMStoreFloat4x4(&result, XMMatrixLookAtRH(EYE, TGT, UP)); - + XMStoreFloat4x4(&result, XMMatrixLookAtRH(eye, target, up)); return result; } @@ -507,12 +495,7 @@ namespace SHADE { SHMatrix result; - const XMVECTOR EYE = XMLoadFloat3(&eye); - const XMVECTOR TGT = XMLoadFloat3(&target); - const XMVECTOR UP = XMLoadFloat3(&up); - - XMStoreFloat4x4(&result, XMMatrixLookAtLH(EYE, TGT, UP)); - + XMStoreFloat4x4(&result, XMMatrixLookAtLH(eye, target, up)); return result; } @@ -522,8 +505,8 @@ namespace SHADE const SHVec3 FWD_HAT = SHVec3::Normalise(-forward); - const XMVECTOR Z_HAT = XMVector3Normalize(XMLoadFloat3(&FWD_HAT)); - const XMVECTOR X_HAT = XMVector3Normalize(XMVector3Cross(XMLoadFloat3(&up), Z_HAT)); + const XMVECTOR Z_HAT = XMVector3Normalize(FWD_HAT); + const XMVECTOR X_HAT = XMVector3Normalize(XMVector3Cross(up, Z_HAT)); const XMVECTOR Y_HAT = XMVector3Cross(Z_HAT, X_HAT); XMStoreFloat3(reinterpret_cast(&result._11), X_HAT); @@ -543,8 +526,8 @@ namespace SHADE const SHVec3 FWD_HAT = SHVec3::Normalise(forward); - const XMVECTOR Z_HAT = XMVector3Normalize(XMLoadFloat3(&FWD_HAT)); - const XMVECTOR X_HAT = XMVector3Normalize(XMVector3Cross(XMLoadFloat3(&up), Z_HAT)); + const XMVECTOR Z_HAT = XMVector3Normalize(FWD_HAT); + const XMVECTOR X_HAT = XMVector3Normalize(XMVector3Cross(up, Z_HAT)); const XMVECTOR Y_HAT = XMVector3Cross(Z_HAT, X_HAT); XMStoreFloat3(reinterpret_cast(&result._11), X_HAT); @@ -563,7 +546,6 @@ namespace SHADE SHMatrix result; XMStoreFloat4x4(&result, XMMatrixPerspectiveFovRH(fov, aspectRatio, nearPlane, farPlane)); - return result; } @@ -572,7 +554,6 @@ namespace SHADE SHMatrix result; XMStoreFloat4x4(&result, XMMatrixPerspectiveFovLH(fov, aspectRatio, nearPlane, farPlane)); - return result; } @@ -581,7 +562,6 @@ namespace SHADE SHMatrix result; XMStoreFloat4x4(&result, XMMatrixPerspectiveRH(width, height, nearPlane, farPlane)); - return result; } @@ -590,7 +570,6 @@ namespace SHADE SHMatrix result; XMStoreFloat4x4(&result, XMMatrixPerspectiveLH(width, height, nearPlane, farPlane)); - return result; } @@ -599,7 +578,6 @@ namespace SHADE SHMatrix result; XMStoreFloat4x4(&result, XMMatrixOrthographicRH(width, height, nearPlane, farPlane)); - return result; } @@ -608,7 +586,6 @@ namespace SHADE SHMatrix result; XMStoreFloat4x4(&result, XMMatrixOrthographicLH(width, height, nearPlane, farPlane)); - return result; } diff --git a/SHADE_Engine/src/Math/SHMatrix.h b/SHADE_Engine/src/Math/SHMatrix.h index 7a662478..4d8f1bfe 100644 --- a/SHADE_Engine/src/Math/SHMatrix.h +++ b/SHADE_Engine/src/Math/SHMatrix.h @@ -77,6 +77,8 @@ namespace SHADE SHMatrix& operator= (const SHMatrix& rhs) = default; SHMatrix& operator= (SHMatrix&& rhs) = default; + operator DirectX::XMMATRIX () const noexcept; + SHMatrix& operator+= (const SHMatrix& rhs) noexcept; SHMatrix& operator-= (const SHMatrix& rhs) noexcept; SHMatrix& operator*= (const SHMatrix& rhs) noexcept; diff --git a/SHADE_Engine/src/Math/SHQuaternion.cpp b/SHADE_Engine/src/Math/SHQuaternion.cpp index 33c568a5..924ac67a 100644 --- a/SHADE_Engine/src/Math/SHQuaternion.cpp +++ b/SHADE_Engine/src/Math/SHQuaternion.cpp @@ -40,40 +40,10 @@ namespace SHADE : XMFLOAT4( _x, _y, _z, _w ) {} - SHQuaternion::SHQuaternion(float yaw, float pitch, float roll) noexcept - : XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f ) - { - XMStoreFloat4(this, XMQuaternionRotationRollPitchYaw(pitch, yaw, roll)); - } - - SHQuaternion::SHQuaternion(const SHVec3& eulerAngles) noexcept - : XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f ) - { - const XMVECTOR V = XMLoadFloat3(&eulerAngles); - XMStoreFloat4(this, XMQuaternionRotationRollPitchYawFromVector(V)); - } - - SHQuaternion::SHQuaternion(const SHVec3& axis, float angleInRad) noexcept - : XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f ) - { - const XMVECTOR AXIS = XMLoadFloat3(&axis); - XMStoreFloat4(this, XMQuaternionRotationAxis(AXIS, angleInRad)); - } - - SHQuaternion::SHQuaternion(const SHMatrix& rotationMatrix) noexcept - : XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f ) - { - const XMMATRIX M = XMLoadFloat4x4(&rotationMatrix); - XMStoreFloat4(this, XMQuaternionRotationMatrix(M)); - } - SHQuaternion::SHQuaternion(const reactphysics3d::Vector3& rp3dEuler) noexcept : XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f ) { - const SHVec3& SHADE_VEC{ rp3dEuler }; - - const XMVECTOR V = XMLoadFloat3(&SHADE_VEC); - XMStoreFloat4(this, XMQuaternionRotationRollPitchYawFromVector(V)); + XMStoreFloat4(this, XMQuaternionRotationRollPitchYawFromVector(SHVec3 { rp3dEuler })); } SHQuaternion::SHQuaternion(const reactphysics3d::Quaternion& rp3dQuat) noexcept @@ -113,10 +83,7 @@ namespace SHADE { SHQuaternion result; - const XMVECTOR Q1 = XMLoadFloat4(this); - const XMVECTOR Q2 = XMLoadFloat4(&rhs); - - XMStoreFloat4(&result, XMVectorAdd(Q1, Q2)); + XMStoreFloat4(&result, XMVectorAdd(*this, rhs)); return result; } @@ -124,10 +91,7 @@ namespace SHADE { SHQuaternion result; - const XMVECTOR Q1 = XMLoadFloat4(this); - const XMVECTOR Q2 = XMLoadFloat4(&rhs); - - XMStoreFloat4(&result, XMVectorSubtract(Q1, Q2)); + XMStoreFloat4(&result, XMVectorSubtract(*this, rhs)); return result; } @@ -135,9 +99,7 @@ namespace SHADE { SHQuaternion result; - const XMVECTOR Q = XMLoadFloat4(this); - - XMStoreFloat4(&result, XMVectorNegate(Q)); + XMStoreFloat4(&result, XMVectorNegate(*this)); return result; } @@ -145,10 +107,7 @@ namespace SHADE { SHQuaternion result; - const XMVECTOR Q1 = XMLoadFloat4(this); - const XMVECTOR Q2 = XMLoadFloat4(&rhs); - - XMStoreFloat4(&result, XMQuaternionMultiply(Q1, Q2)); + XMStoreFloat4(&result, XMQuaternionMultiply(*this, rhs)); return result; } @@ -156,9 +115,7 @@ namespace SHADE { SHQuaternion result; - const XMVECTOR Q = XMLoadFloat4(this); - - XMStoreFloat4(&result, XMVectorScale(Q, rhs)); + XMStoreFloat4(&result, XMVectorScale(*this, rhs)); return result; } @@ -166,27 +123,18 @@ namespace SHADE { SHQuaternion result; - const XMVECTOR Q1 = XMLoadFloat4(this); - const XMVECTOR Q2 = XMQuaternionInverse(XMLoadFloat4(&rhs)); - - XMStoreFloat4(&result, XMQuaternionMultiply(Q1, Q2)); + XMStoreFloat4(&result, XMQuaternionMultiply(*this, XMQuaternionInverse(rhs))); return result; } bool SHQuaternion::operator==(const SHQuaternion& rhs) const noexcept { - const XMVECTOR Q1 = XMLoadFloat4(this); - const XMVECTOR Q2 = XMLoadFloat4(&rhs); - - return XMQuaternionEqual(Q1, Q2); + return XMQuaternionEqual(*this, rhs); } bool SHQuaternion::operator!=(const SHQuaternion& rhs) const noexcept { - const XMVECTOR Q1 = XMLoadFloat4(this); - const XMVECTOR Q2 = XMLoadFloat4(&rhs); - - return XMQuaternionNotEqual(Q1, Q2); + return XMQuaternionNotEqual(*this, rhs); } SHQuaternion::operator reactphysics3d::Quaternion() const noexcept @@ -199,6 +147,11 @@ namespace SHADE return reactphysics3d::Vector3{ ToEuler() }; } + SHQuaternion::operator XMVECTOR() const noexcept + { + return XMLoadFloat4(this); + } + SHQuaternion operator*(float lhs, const SHQuaternion& rhs) noexcept { return rhs * lhs; @@ -213,8 +166,7 @@ namespace SHADE XMVECTOR axis; float angle; - const XMVECTOR Q = XMLoadFloat4(this); - XMQuaternionToAxisAngle(&axis, &angle, Q); + XMQuaternionToAxisAngle(&axis, &angle, *this); return angle; } @@ -223,8 +175,7 @@ namespace SHADE XMVECTOR axis; float angle; - const XMVECTOR Q = XMLoadFloat4(this); - XMQuaternionToAxisAngle(&axis, &angle, Q); + XMQuaternionToAxisAngle(&axis, &angle, *this); return SHVec4{XMVectorGetX(axis), XMVectorGetY(axis), XMVectorGetZ(axis), angle}; @@ -238,28 +189,22 @@ namespace SHADE void SHQuaternion::Invert() noexcept { - const XMVECTOR Q = XMLoadFloat4(this); - XMStoreFloat4(this, XMQuaternionInverse(Q)); + XMStoreFloat4(this, XMQuaternionInverse(*this)); } float SHQuaternion::Length() const noexcept { - const XMVECTOR Q = XMLoadFloat4(this); - return XMVectorGetX(XMQuaternionLength(Q)); + return XMVectorGetX(XMQuaternionLength(*this)); } float SHQuaternion::LengthSquared() const noexcept { - const XMVECTOR Q = XMLoadFloat4(this); - return XMVectorGetX(XMQuaternionLengthSq(Q)); + return XMVectorGetX(XMQuaternionLengthSq(*this)); } float SHQuaternion::Dot(const SHQuaternion& rhs) const noexcept { - const XMVECTOR Q1 = XMLoadFloat4(this); - const XMVECTOR Q2 = XMLoadFloat4(&rhs); - - return XMVectorGetX(XMQuaternionDot(Q1, Q2)); + return XMVectorGetX(XMQuaternionDot(*this, rhs)); } SHQuaternion SHQuaternion::RotateTowards(const SHQuaternion&, float) const noexcept @@ -273,29 +218,29 @@ namespace SHADE SHVec3 SHQuaternion::ToEuler() const noexcept { - const float xx = x * x; - const float yy = y * y; - const float zz = z * z; + const float XX = x * x; + const float YY = y * y; + const float ZZ = z * z; - const float m31 = 2.f * x * z + 2.f * y * w; - const float m32 = 2.f * y * z - 2.f * x * w; - const float m33 = 1.f - 2.f * xx - 2.f * yy; + const float M_31 = 2.f * x * z + 2.f * y * w; + const float M_32 = 2.f * y * z - 2.f * x * w; + const float M_33 = 1.f - 2.f * XX - 2.f * YY; - const float cy = sqrtf(m33 * m33 + m31 * m31); - const float cx = atan2f(-m32, cy); - if (cy > 16.0f * SHMath::EPSILON) + const float CY = sqrtf(M_33 * M_33 + M_31 * M_31); + const float CX = atan2f(-M_32, CY); + if (CY > 16.0f * SHMath::EPSILON) { - const float m12 = 2.f * x * y + 2.f * z * w; - const float m22 = 1.f - 2.f * xx - 2.f * zz; + const float M_12 = 2.f * x * y + 2.f * z * w; + const float M_22 = 1.f - 2.f * XX - 2.f * ZZ; - return SHVec3(cx, atan2f(m31, m33), atan2f(m12, m22)); + return SHVec3(CX, atan2f(M_31, M_33), atan2f(M_12, M_22)); } else { - const float m11 = 1.f - 2.f * yy - 2.f * zz; - const float m21 = 2.f * x * y - 2.f * z * w; + const float m11 = 1.f - 2.f * YY - 2.f * ZZ; + const float m21 = 2.f * x * y - 2.f * z * w; - return SHVec3(cx, 0.f, atan2f(-m21, m11)); + return SHVec3(CX, 0.f, atan2f(-m21, m11)); } } @@ -311,13 +256,43 @@ namespace SHADE /* Static Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ + SHQuaternion SHQuaternion::FromEuler(const SHVec3& eulerAngles) noexcept + { + SHQuaternion result; + + XMStoreFloat4(&result, XMQuaternionRotationRollPitchYawFromVector(eulerAngles)); + return result; + } + + SHQuaternion SHQuaternion::FromPitchYawRoll(float pitch, float yaw, float roll) noexcept + { + SHQuaternion result; + + XMStoreFloat4(&result, XMQuaternionRotationRollPitchYaw(pitch, yaw, roll)); + return result; + } + + SHQuaternion SHQuaternion::FromAxisAngle(const SHVec3& axis, float angle) noexcept + { + SHQuaternion result; + + XMStoreFloat4(&result, XMQuaternionRotationAxis(axis, angle)); + return result; + } + + SHQuaternion SHQuaternion::FromRotationMatrix(const SHMatrix& rotationMatrix) noexcept + { + SHQuaternion result; + + XMStoreFloat4(&result, XMQuaternionRotationMatrix(rotationMatrix)); + return result; + } + SHQuaternion SHQuaternion::Normalise(const SHQuaternion& q) noexcept { SHQuaternion result; - const XMVECTOR Q = XMLoadFloat4(&q); - - XMStoreFloat4(&result, XMQuaternionNormalize(Q)); + XMStoreFloat4(&result, XMQuaternionNormalize(q)); return result; } @@ -325,9 +300,7 @@ namespace SHADE { SHQuaternion result; - const XMVECTOR Q = XMLoadFloat4(&q); - - XMStoreFloat4(&result, XMQuaternionConjugate(Q)); + XMStoreFloat4(&result, XMQuaternionConjugate(q)); return result; } @@ -335,9 +308,7 @@ namespace SHADE { SHQuaternion result; - const XMVECTOR Q = XMLoadFloat4(&q); - XMStoreFloat4(&result, XMQuaternionInverse(Q)); - + XMStoreFloat4(&result, XMQuaternionInverse(q)); return result; } @@ -362,10 +333,7 @@ namespace SHADE { SHQuaternion result; - const XMVECTOR Q1 = XMLoadFloat4(&q1); - const XMVECTOR Q2 = XMLoadFloat4(&q2); - - XMStoreFloat4(&result, XMQuaternionSlerp(Q1, Q2, t)); + XMStoreFloat4(&result, XMQuaternionSlerp(q1, q2, t)); return result; } diff --git a/SHADE_Engine/src/Math/SHQuaternion.h b/SHADE_Engine/src/Math/SHQuaternion.h index c94907b5..f3ce3d61 100644 --- a/SHADE_Engine/src/Math/SHQuaternion.h +++ b/SHADE_Engine/src/Math/SHQuaternion.h @@ -51,9 +51,6 @@ namespace SHADE SHQuaternion () noexcept; SHQuaternion (float x, float y, float z, float w) noexcept; SHQuaternion (float yaw, float pitch, float roll) noexcept; - SHQuaternion (const SHVec3& eulerAngles) noexcept; - SHQuaternion (const SHVec3& axis, float angleInRad) noexcept; - SHQuaternion (const SHMatrix& rotationMatrix) noexcept; // Conversion from other math types @@ -87,6 +84,7 @@ namespace SHADE operator reactphysics3d::Quaternion () const noexcept; operator reactphysics3d::Vector3 () const noexcept; + operator DirectX::XMVECTOR () const noexcept; /*---------------------------------------------------------------------------------*/ /* Getter Functions */ @@ -113,6 +111,11 @@ namespace SHADE /* Static Function Members */ /*---------------------------------------------------------------------------------*/ + [[nodiscard]] static SHQuaternion FromEuler (const SHVec3& eulerAngles) noexcept; + [[nodiscard]] static SHQuaternion FromPitchYawRoll (float pitch, float yaw, float roll) noexcept; + [[nodiscard]] static SHQuaternion FromAxisAngle (const SHVec3& axis, float angle) noexcept; + [[nodiscard]] static SHQuaternion FromRotationMatrix(const SHMatrix& rotationMatrix) noexcept; + [[nodiscard]] static SHQuaternion Normalise (const SHQuaternion& q) noexcept; [[nodiscard]] static SHQuaternion Conjugate (const SHQuaternion& q) noexcept; [[nodiscard]] static SHQuaternion Inverse (const SHQuaternion& q) noexcept; diff --git a/SHADE_Engine/src/Math/Transform/SHTransform.cpp b/SHADE_Engine/src/Math/Transform/SHTransform.cpp index f51d73ec..ef7c5fda 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransform.cpp +++ b/SHADE_Engine/src/Math/Transform/SHTransform.cpp @@ -26,15 +26,15 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ SHTransform::SHTransform() noexcept - : position { SHVec3::Zero } - , rotation { SHVec3::Zero } - , scale { SHVec3::One } + : position { SHVec3::Zero } + , orientation { SHQuaternion::Identity } + , scale { SHVec3::One } {} SHTransform::SHTransform(const SHVec3& pos, const SHVec3& rot, const SHVec3& scl) noexcept - : position { pos } - , rotation { rot } - , scale { scl } + : position { pos } + , orientation { SHQuaternion::FromEuler(rot) } + , scale { scl } {} /*-----------------------------------------------------------------------------------*/ @@ -43,12 +43,12 @@ namespace SHADE bool SHTransform::operator==(const SHTransform& rhs) const noexcept { - return !(position != rhs.position || rotation != rhs.rotation || scale != rhs.scale); + return !(position != rhs.position || orientation != rhs.orientation || scale != rhs.scale); } bool SHTransform::operator!=(const SHTransform& rhs) const noexcept { - return (position != rhs.position || rotation != rhs.rotation || scale != rhs.scale); + return (position != rhs.position || orientation != rhs.orientation || scale != rhs.scale); } /*-----------------------------------------------------------------------------------*/ @@ -59,7 +59,7 @@ namespace SHADE { const SHMatrix T = SHMatrix::Translate(position); - const SHMatrix R = SHMatrix::Rotate(rotation); + const SHMatrix R = SHMatrix::Rotate(orientation); const SHMatrix S = SHMatrix::Scale(scale); trs = S * R * T; diff --git a/SHADE_Engine/src/Math/Transform/SHTransform.h b/SHADE_Engine/src/Math/Transform/SHTransform.h index c1a0e565..2e7d236c 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransform.h +++ b/SHADE_Engine/src/Math/Transform/SHTransform.h @@ -12,8 +12,8 @@ // Project Headers #include "SH_API.h" -#include "Math/Vector/SHVec2.h" #include "Math/Vector/SHVec3.h" +#include "Math/SHQuaternion.h" #include "Math/SHMatrix.h" namespace SHADE @@ -31,22 +31,23 @@ namespace SHADE static const SHTransform Identity; - SHVec3 position; - SHVec3 rotation; - SHVec3 scale; + SHVec3 position; + SHQuaternion orientation; + SHVec3 scale; - SHMatrix trs; + SHMatrix trs; /*---------------------------------------------------------------------------------*/ /* Constructors & Destructor */ /*---------------------------------------------------------------------------------*/ - SHTransform (const SHTransform&) = default; - SHTransform (SHTransform&&) = default; - ~SHTransform () = default; + SHTransform (const SHTransform&) = default; + SHTransform (SHTransform&&) = default; + ~SHTransform () = default; - SHTransform () noexcept; - SHTransform (const SHVec3& pos, const SHVec3& rot, const SHVec3& scl) noexcept; + SHTransform () noexcept; + SHTransform (const SHVec3& pos, const SHVec3& rot, const SHVec3& scl) noexcept; + SHTransform (const SHVec3& pos, const SHQuaternion& quat, const SHVec3& scl) noexcept; /*---------------------------------------------------------------------------------*/ /* Operator Overloads */ @@ -63,7 +64,6 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ const SHMatrix& ComputeTRS(); - }; } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Math/Transform/SHTransformComponent.cpp b/SHADE_Engine/src/Math/Transform/SHTransformComponent.cpp index a8b75497..306cde67 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformComponent.cpp +++ b/SHADE_Engine/src/Math/Transform/SHTransformComponent.cpp @@ -42,16 +42,12 @@ namespace SHADE const SHVec3& SHTransformComponent::GetLocalRotation() const noexcept { - return local.rotation; + return localRotation; } - SHVec3 SHTransformComponent::GetLocalRotationDeg() const noexcept + const SHQuaternion& SHTransformComponent::GetLocalOrientation() const noexcept { - SHVec3 rot = local.rotation; - rot.x = SHMath::RadiansToDegrees(rot.x); - rot.y = SHMath::RadiansToDegrees(rot.y); - rot.z = SHMath::RadiansToDegrees(rot.z); - return rot; + return local.orientation; } const SHVec3& SHTransformComponent::GetLocalScale() const noexcept @@ -66,16 +62,12 @@ namespace SHADE const SHVec3& SHTransformComponent::GetWorldRotation() const noexcept { - return world.rotation; + return worldRotation; } - SHVec3 SHTransformComponent::GetWorldRotationDeg() const noexcept + const SHQuaternion& SHTransformComponent::GetWorldOrientation() const noexcept { - SHVec3 rot = world.rotation; - rot.x = SHMath::RadiansToDegrees(rot.x); - rot.y = SHMath::RadiansToDegrees(rot.y); - rot.z = SHMath::RadiansToDegrees(rot.z); - return rot; + return world.orientation; } const SHVec3& SHTransformComponent::GetWorldScale() const noexcept @@ -111,32 +103,21 @@ namespace SHADE void SHTransformComponent::SetLocalRotation(const SHVec3& newLocalRotation) noexcept { dirty = true; - local.rotation = newLocalRotation; - } - - void SHTransformComponent::SetLocalRotationDeg(SHVec3 newLocalRotationDeg) noexcept - { - dirty = true; - - local.rotation.x = SHMath::DegreesToRadians(newLocalRotationDeg.x); - local.rotation.y = SHMath::DegreesToRadians(newLocalRotationDeg.y); - local.rotation.z = SHMath::DegreesToRadians(newLocalRotationDeg.z); + localRotation = newLocalRotation; } void SHTransformComponent::SetLocalRotation(float pitch, float yaw, float roll) noexcept { dirty = true; - local.rotation.x = pitch; - local.rotation.y = yaw; - local.rotation.z = roll; + localRotation.x = pitch; + localRotation.y = yaw; + localRotation.z = roll; } - void SHTransformComponent::SetLocalRotationDeg(float pitch, float yaw, float roll) noexcept + void SHTransformComponent::SetLocalOrientation(const SHQuaternion& newLocalOrientation) noexcept { - local.rotation.x = SHMath::DegreesToRadians(pitch); - local.rotation.y = SHMath::DegreesToRadians(yaw); - local.rotation.z = SHMath::DegreesToRadians(roll); + } void SHTransformComponent::SetLocalScale(const SHVec3& newLocalScale) noexcept @@ -157,41 +138,24 @@ namespace SHADE { dirty = true; - world.rotation = newWorldRotation; + worldRotation = newWorldRotation; updateQueue.push({ UpdateCommandType::WORLD_ROTATION, newWorldRotation }); } - void SHTransformComponent::SetWorldRotationDeg(const SHVec3& newWorldRotation) noexcept - { - dirty = true; - - world.rotation.x = SHMath::DegreesToRadians(newWorldRotation.x); - world.rotation.y = SHMath::DegreesToRadians(newWorldRotation.y); - world.rotation.z = SHMath::DegreesToRadians(newWorldRotation.z); - - updateQueue.push({ UpdateCommandType::WORLD_ROTATION, world.rotation }); - } - void SHTransformComponent::SetWorldRotation(float pitch, float yaw, float roll) noexcept { dirty = true; - world.rotation.x = pitch; - world.rotation.y = yaw; - world.rotation.z = roll; + worldRotation.x = pitch; + worldRotation.y = yaw; + worldRotation.z = roll; updateQueue.push({ UpdateCommandType::WORLD_ROTATION, SHVec3{ pitch, yaw, roll} }); } - void SHTransformComponent::SetWorldRotationDeg(float pitch, float yaw, float roll) noexcept + void SHTransformComponent::SetWorldOrientation(const SHQuaternion& newWorldOrientation) noexcept { - dirty = true; - - world.rotation.x = SHMath::DegreesToRadians(pitch); - world.rotation.y = SHMath::DegreesToRadians(yaw); - world.rotation.z = SHMath::DegreesToRadians(roll); - - updateQueue.push({ UpdateCommandType::WORLD_ROTATION, world.rotation }); + } void SHTransformComponent::SetWorldScale(const SHVec3& newWorldScale) noexcept @@ -210,7 +174,7 @@ RTTR_REGISTRATION using namespace rttr; registration::class_("Transform Component") - .property("Translate" , &SHTransformComponent::GetLocalPosition , &SHTransformComponent::SetLocalPosition ) - .property("Rotate" , &SHTransformComponent::GetLocalRotationDeg, select_overload(&SHTransformComponent::SetLocalRotationDeg)) - .property("Scale" , &SHTransformComponent::GetLocalScale , &SHTransformComponent::SetLocalScale ); + .property("Translate" , &SHTransformComponent::GetLocalPosition , &SHTransformComponent::SetLocalPosition ) + .property("Rotate" , &SHTransformComponent::GetLocalRotation , select_overload(&SHTransformComponent::SetLocalRotation) ) + .property("Scale" , &SHTransformComponent::GetLocalScale , &SHTransformComponent::SetLocalScale ); } \ No newline at end of file diff --git a/SHADE_Engine/src/Math/Transform/SHTransformComponent.h b/SHADE_Engine/src/Math/Transform/SHTransformComponent.h index 2a3fa7a0..d1d21bec 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformComponent.h +++ b/SHADE_Engine/src/Math/Transform/SHTransformComponent.h @@ -60,11 +60,11 @@ namespace SHADE [[nodiscard]] const SHVec3& GetLocalPosition () const noexcept; [[nodiscard]] const SHVec3& GetLocalRotation () const noexcept; - [[nodiscard]] SHVec3 GetLocalRotationDeg () const noexcept; + [[nodiscard]] const SHQuaternion& GetLocalOrientation () const noexcept; [[nodiscard]] const SHVec3& GetLocalScale () const noexcept; [[nodiscard]] const SHVec3& GetWorldPosition () const noexcept; [[nodiscard]] const SHVec3& GetWorldRotation () const noexcept; - [[nodiscard]] SHVec3 GetWorldRotationDeg () const noexcept; + [[nodiscard]] const SHQuaternion& GetWorldOrientation () const noexcept; [[nodiscard]] const SHVec3& GetWorldScale () const noexcept; [[nodiscard]] const SHMatrix& GetLocalToWorld () const noexcept; @@ -76,28 +76,30 @@ namespace SHADE /* Setter Functions */ /*---------------------------------------------------------------------------------*/ - void SetLocalPosition (const SHVec3& newLocalPosition) noexcept; - void SetLocalRotation (const SHVec3& newLocalRotation) noexcept; - void SetLocalRotationDeg (SHVec3 newLocalRotationDeg) noexcept; - void SetLocalRotation (float pitch, float yaw, float roll) noexcept; - void SetLocalRotationDeg (float pitch, float yaw, float roll) noexcept; - void SetLocalScale (const SHVec3& newLocalScale) noexcept; - void SetWorldPosition (const SHVec3& newWorldPosition) noexcept; - void SetWorldRotation (const SHVec3& newWorldRotation) noexcept; - void SetWorldRotationDeg (const SHVec3& newWorldRotation) noexcept; - void SetWorldRotation (float pitch, float yaw, float roll) noexcept; - void SetWorldRotationDeg (float pitch, float yaw, float roll) noexcept; - void SetWorldScale (const SHVec3& newWorldScale) noexcept; + void SetLocalPosition (const SHVec3& newLocalPosition) noexcept; + void SetLocalRotation (const SHVec3& newLocalRotation) noexcept; + void SetLocalRotation (float pitch, float yaw, float roll) noexcept; + void SetLocalOrientation (const SHQuaternion& newLocalOrientation) noexcept; + void SetLocalScale (const SHVec3& newLocalScale) noexcept; + void SetWorldPosition (const SHVec3& newWorldPosition) noexcept; + void SetWorldRotation (const SHVec3& newWorldRotation) noexcept; + void SetWorldRotation (float pitch, float yaw, float roll) noexcept; + void SetWorldOrientation (const SHQuaternion& newWorldOrientation) noexcept; + void SetWorldScale (const SHVec3& newWorldScale) noexcept; private: /*---------------------------------------------------------------------------------*/ /* Type Definitions */ /*---------------------------------------------------------------------------------*/ + // Differentiate between rotation and orientation for setters + // Setting a quaternion directly is different from using euler angle rotations. + enum class UpdateCommandType { WORLD_POSITION , WORLD_ROTATION + , WORLD_ORIENTATION , WORLD_SCALE }; @@ -120,6 +122,12 @@ namespace SHADE bool dirty; + // We store euler angle rotations separately to interface with transform quaternions. + // Reading quaternions are unreliable. + + SHVec3 localRotation; // Stored in degrees + SHVec3 worldRotation; // Stored in degrees + SHTransform local; // Local TRS holds Local To World Transform SHTransform world; diff --git a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp index 4b4f1cce..3244db1b 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp +++ b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp @@ -17,6 +17,8 @@ #include "Scene/SHSceneManager.h" #include "ECS_Base/Managers/SHComponentManager.h" #include "ECS_Base/Managers/SHEntityManager.h" +#include "ECS_Base/Managers/SHSystemManager.h" +#include "Math/SHMathHelpers.h" namespace SHADE { @@ -45,14 +47,16 @@ namespace SHADE { // Get the current scene graph to traverse and update const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph(); - UpdateEntity(SCENE_GRAPH.GetRoot()); + + // TODO(Diren): Consider how to clear dirty in pause / stop mode and update physics, but do not clear in play mode. + UpdateEntity(SCENE_GRAPH.GetRoot(), false); } - void SHTransformSystem::TransformPostPhysicsUpdate::Execute(double dt) noexcept + void SHTransformSystem::TransformPostPhysicsUpdate::Execute(double) noexcept { // Get the current scene graph to traverse and update const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph(); - UpdateEntityAndClear(SCENE_GRAPH.GetRoot()); + UpdateEntity(SCENE_GRAPH.GetRoot(), true); } void SHTransformSystem::Init() @@ -96,13 +100,13 @@ namespace SHADE tf->local.position = SHVec3::Transform(tf->world.position, worldToLocal); - tf->local.rotation = tf->world.rotation; - tf->local.scale = tf->world.scale; + tf->localRotation = tf->worldRotation; + tf->local.scale = tf->world.scale; if (PARENT_TF != nullptr) { // Compute Local Rotation - tf->local.rotation -= PARENT_TF->GetLocalRotation(); + tf->localRotation -= PARENT_TF->GetLocalRotation(); // Compute Local Scale tf->local.scale /= PARENT_TF->GetLocalScale(); @@ -143,13 +147,13 @@ namespace SHADE childTransform->local.position = SHVec3::Transform(childTransform->world.position, worldToLocal); - childTransform->local.rotation = childTransform->world.rotation; - childTransform->local.scale = childTransform->world.scale; + childTransform->localRotation = childTransform->worldRotation; + childTransform->local.scale = childTransform->world.scale; if (parent) { // Compute Local Rotation - childTransform->local.rotation -= parent->GetLocalRotation(); + childTransform->localRotation -= parent->GetLocalRotation(); // Compute Local Scale childTransform->local.scale /= parent->GetLocalScale(); @@ -158,12 +162,10 @@ namespace SHADE childTransform->local.trs = localToWorld; } } - - } } - void SHTransformSystem::UpdateEntity(const SHSceneNode* node) + void SHTransformSystem::UpdateEntity(const SHSceneNode* node, bool clearDirtyFlag) { const auto* NODE_TRANSFORM = SHComponentManager::GetComponent_s(node->GetEntityID()); const bool HAS_PARENT_CHANGED = NODE_TRANSFORM && NODE_TRANSFORM->dirty; @@ -185,37 +187,10 @@ namespace SHADE } } - UpdateEntity(child); - } - } - - - void SHTransformSystem::UpdateEntityAndClear(const SHSceneNode* node) - { - const auto* NODE_TRANSFORM = SHComponentManager::GetComponent_s(node->GetEntityID()); - const bool HAS_PARENT_CHANGED = NODE_TRANSFORM && NODE_TRANSFORM->dirty; - - for (const auto* child : node->GetChildren()) - { - auto* childTransform = SHComponentManager::GetComponent_s(child->GetEntityID()); - if (childTransform) - { - // Only update if node in hierarchy and component are both active - const bool IS_NODE_ACTIVE = child->IsActive(); - if (IS_NODE_ACTIVE && childTransform->isActive) - { - if (childTransform->dirty || HAS_PARENT_CHANGED) - { - UpdateTransform(*childTransform, NODE_TRANSFORM); - childTransform->dirty = true; - } - } - } - - UpdateEntityAndClear(child); + UpdateEntity(child, clearDirtyFlag); // Clear dirty flag after all children are updated - if (childTransform) + if (childTransform && clearDirtyFlag) childTransform->dirty = false; } } @@ -244,12 +219,17 @@ namespace SHADE } case SHTransformComponent::UpdateCommandType::WORLD_ROTATION: { - tf.local.rotation = tf.world.rotation; + tf.localRotation = tf.worldRotation; if (parent) - tf.local.rotation -= parent->GetLocalRotation(); + tf.localRotation -= parent->GetLocalRotation(); break; } + case SHTransformComponent::UpdateCommandType::WORLD_ORIENTATION: + { + // TODO(Diren): Test using scripts by concat quaternions? + break; + } case SHTransformComponent::UpdateCommandType::WORLD_SCALE: { tf.local.scale = tf.world.scale; @@ -268,7 +248,14 @@ namespace SHADE tf.local.trs = localToWorld; tf.world.position = SHVec3::Transform(tf.local.position, localToWorld); - tf.world.rotation = tf.local.rotation + (parent ? parent->GetLocalRotation() : SHVec3::Zero); + + tf.worldRotation = tf.localRotation + (parent ? parent->GetLocalRotation() : SHVec3::Zero); + + // TODO(Diren): Wrap rotations between -360 and 360 + + tf.world.orientation = SHQuaternion::FromEuler(tf.worldRotation); + tf.local.orientation = SHQuaternion::FromEuler(tf.localRotation); + tf.world.scale = tf.local.scale * (parent ? parent->GetLocalScale() : SHVec3::One); tf.world.ComputeTRS(); diff --git a/SHADE_Engine/src/Math/Transform/SHTransformSystem.h b/SHADE_Engine/src/Math/Transform/SHTransformSystem.h index 256c1561..e63969ce 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformSystem.h +++ b/SHADE_Engine/src/Math/Transform/SHTransformSystem.h @@ -114,8 +114,7 @@ namespace SHADE SHEventHandle ChangeParent (SHEventPtr changeParentEvent); static void UpdateChildrenLocalTransforms (SHSceneNode* node); - static void UpdateEntity (const SHSceneNode* node); - static void UpdateEntityAndClear (const SHSceneNode* node); + static void UpdateEntity (const SHSceneNode* node, bool clearDirtyFlag); static void UpdateTransform (SHTransformComponent& tf, const SHTransformComponent* parent = nullptr); }; diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp index 36f7c57e..f9b476ef 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp @@ -140,12 +140,12 @@ namespace SHADE isRigidBody = true; rb->position = tf->GetWorldPosition(); - rb->orientation = tf->GetWorldRotation(); + rb->orientation = SHQuaternion::FromEuler(tf->GetWorldRotation()); if (hasColliders) { c->position = tf->GetWorldPosition(); - c->orientation = tf->GetWorldRotation(); + c->orientation = SHQuaternion::FromEuler(tf->GetWorldRotation()); // Get array of colliders and add them back into the rigidbody for (auto& collider : c->colliders | std::views::keys) AddCollider(&collider); @@ -160,7 +160,7 @@ namespace SHADE hasColliders = true; c->position = tf->GetWorldPosition(); - c->orientation = tf->GetWorldRotation(); + c->orientation = SHQuaternion::FromEuler(tf->GetWorldRotation()); for (auto& collider : c->colliders | std::views::keys) AddCollider(&collider); From d4fe63722a480eb18cbd24840a17eb007b695a0d Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Sun, 23 Oct 2022 15:05:31 +0800 Subject: [PATCH 16/50] WIP (TODO: remember to change commit message) --- Assets/Editor/Layouts/UserLayout.ini | 26 +-- .../Graphics/Commands/SHVkCommandBuffer.cpp | 30 ++- .../src/Graphics/Commands/SHVkCommandBuffer.h | 25 ++- .../Descriptors/SHVkDescriptorSetGroup.cpp | 9 +- .../Descriptors/SHVkDescriptorSetGroup.h | 2 + .../Graphics/MiddleEnd/Batching/SHBatch.cpp | 4 +- .../MiddleEnd/Batching/SHSuperBatch.cpp | 140 ++++++------- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 33 ++- .../Interface/SHPostOffscreenRenderSystem.cpp | 2 +- .../MiddleEnd/Interface/SHRenderer.cpp | 2 +- .../src/Graphics/Pipeline/SHPipelineType.h | 6 +- .../src/Graphics/Pipeline/SHVkPipeline.cpp | 26 +-- .../src/Graphics/Pipeline/SHVkPipeline.h | 1 + .../Graphics/Pipeline/SHVkPipelineLayout.cpp | 32 +-- .../Graphics/Pipeline/SHVkPipelineLayout.h | 12 +- .../RenderGraph/SHAttachmentDescriptionType.h | 3 +- .../Graphics/RenderGraph/SHRenderGraph.cpp | 71 +++---- .../src/Graphics/RenderGraph/SHRenderGraph.h | 12 +- .../RenderGraph/SHRenderGraphNode.cpp | 82 +++++++- .../Graphics/RenderGraph/SHRenderGraphNode.h | 9 + .../RenderGraph/SHRenderGraphNodeCompute.cpp | 109 ++++++++++ .../RenderGraph/SHRenderGraphNodeCompute.h | 57 +++++ .../RenderGraph/SHRenderGraphResource.cpp | 8 + .../RenderGraph/SHRenderGraphResource.h | 2 + .../RenderGraph/SHRenderGraphStorage.h | 15 +- .../src/Graphics/RenderGraph/SHSubpass.cpp | 194 +++++++++--------- .../src/Graphics/RenderGraph/SHSubpass.h | 7 +- .../Graphics/RenderGraph/SHSubpassCompute.cpp | 53 ----- .../Graphics/RenderGraph/SHSubpassCompute.h | 49 ----- SHADE_Engine/src/Graphics/SHVkUtil.cpp | 15 ++ SHADE_Engine/src/Graphics/SHVkUtil.h | 12 +- TempShaderFolder/GreyscaleCs.glsl | 38 ---- TempShaderFolder/GreyscaleCs.spv | Bin 1400 -> 0 bytes TempShaderFolder/KirschCs.glsl | 167 +++++++++++++++ TempShaderFolder/KirschCs.spv | Bin 0 -> 5900 bytes 35 files changed, 788 insertions(+), 465 deletions(-) create mode 100644 SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp create mode 100644 SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.h delete mode 100644 SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp delete mode 100644 SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.h delete mode 100644 TempShaderFolder/GreyscaleCs.glsl delete mode 100644 TempShaderFolder/GreyscaleCs.spv create mode 100644 TempShaderFolder/KirschCs.glsl create mode 100644 TempShaderFolder/KirschCs.spv diff --git a/Assets/Editor/Layouts/UserLayout.ini b/Assets/Editor/Layouts/UserLayout.ini index 530ee770..005c3556 100644 --- a/Assets/Editor/Layouts/UserLayout.ini +++ b/Assets/Editor/Layouts/UserLayout.ini @@ -1,16 +1,16 @@ [Window][MainStatusBar] -Pos=0,1060 -Size=1920,20 +Pos=0,1367 +Size=3440,20 Collapsed=0 [Window][SHEditorMenuBar] Pos=0,48 -Size=1920,1012 +Size=3440,1319 Collapsed=0 [Window][Hierarchy Panel] -Pos=0,142 -Size=571,918 +Pos=0,170 +Size=646,1197 Collapsed=0 DockId=0x00000004,0 @@ -20,29 +20,29 @@ Size=400,400 Collapsed=0 [Window][Inspector] -Pos=1649,48 -Size=271,1012 +Pos=3169,48 +Size=271,1319 Collapsed=0 DockId=0x00000006,0 [Window][Profiler] Pos=0,48 -Size=571,92 +Size=646,120 Collapsed=0 DockId=0x00000003,0 [Window][Viewport] -Pos=573,48 -Size=1074,1012 +Pos=648,48 +Size=2519,1319 Collapsed=0 DockId=0x00000002,0 [Docking][Data] -DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,79 Size=1920,1012 Split=X +DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=0,71 Size=3440,1319 Split=X DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1992,1036 Split=X - DockNode ID=0x00000001 Parent=0x00000005 SizeRef=571,1036 Split=Y Selected=0x1E6EB881 + DockNode ID=0x00000001 Parent=0x00000005 SizeRef=646,1036 Split=Y Selected=0x1E6EB881 DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,94 Selected=0x1E6EB881 DockNode ID=0x00000004 Parent=0x00000001 SizeRef=225,940 Selected=0xE096E5AE - DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1074,1036 CentralNode=1 Selected=0x13926F0B + DockNode ID=0x00000002 Parent=0x00000005 SizeRef=999,1036 CentralNode=1 Selected=0x13926F0B DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=271,1036 Selected=0xE7039252 diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp index 4501ba7b..a744c795 100644 --- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp +++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp @@ -10,6 +10,7 @@ #include "Graphics/Buffers/SHVkBuffer.h" #include "Graphics/Images/SHVkImage.h" #include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" +#include "Graphics/SHVkUtil.h" namespace SHADE @@ -299,7 +300,7 @@ namespace SHADE SHLOG_ERROR("Command buffer must have started recording before a pipeline can be bound. "); return; } - boundPipelineLayoutHdl = pipelineHdl->GetPipelineLayout(); + bindPointData[static_cast(pipelineHdl->GetPipelineType())].boundPipelineLayoutHdl = pipelineHdl->GetPipelineLayout(); vkCommandBuffer.bindPipeline(pipelineHdl->GetPipelineBindPoint(), pipelineHdl->GetVkPipeline()); } @@ -358,9 +359,10 @@ namespace SHADE } } - void SHVkCommandBuffer::BindDescriptorSet(Handle descSetGroup, vk::PipelineBindPoint bindPoint, uint32_t firstSet, std::span dynamicOffsets) + void SHVkCommandBuffer::BindDescriptorSet(Handle descSetGroup, SH_PIPELINE_TYPE bindPoint, uint32_t firstSet, std::span dynamicOffsets) { - vkCommandBuffer.bindDescriptorSets(bindPoint, boundPipelineLayoutHdl->GetVkPipelineLayout(), firstSet, descSetGroup->GetVkHandle(), dynamicOffsets); + uint32_t bindPointIndex = static_cast(bindPoint); + vkCommandBuffer.bindDescriptorSets(SHVkUtil::GetPipelineBindPointFromType(bindPoint), bindPointData[bindPointIndex].boundPipelineLayoutHdl->GetVkPipelineLayout(), firstSet, descSetGroup->GetVkHandle(), dynamicOffsets); } /***************************************************************************/ @@ -452,6 +454,11 @@ namespace SHADE vkCommandBuffer.drawIndexedIndirect(indirectDrawData->GetVkBuffer(), 0, drawCount, sizeof(vk::DrawIndexedIndirectCommand)); } + void SHVkCommandBuffer::ComputeDispatch(uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ) noexcept + { + vkCommandBuffer.dispatch (groupCountX, groupCountY, groupCountZ); + } + void SHVkCommandBuffer::CopyBufferToImage(const vk::Buffer& src, const vk::Image& dst, const std::vector& copyInfo) { vkCommandBuffer.copyBufferToImage @@ -500,9 +507,9 @@ namespace SHADE // //vkCommandBuffer.pipelineBarrier() //} - void SHVkCommandBuffer::ForceSetPipelineLayout(Handle pipelineLayout) noexcept + void SHVkCommandBuffer::ForceSetPipelineLayout(Handle pipelineLayout, SH_PIPELINE_TYPE pipelineType) noexcept { - boundPipelineLayoutHdl = pipelineLayout; + bindPointData[static_cast(pipelineType)].boundPipelineLayoutHdl = pipelineLayout; } /***************************************************************************/ @@ -513,12 +520,13 @@ namespace SHADE */ /***************************************************************************/ - void SHVkCommandBuffer::SubmitPushConstants(void) const noexcept + void SHVkCommandBuffer::SubmitPushConstants(SH_PIPELINE_TYPE bindPoint) const noexcept { - vkCommandBuffer.pushConstants(boundPipelineLayoutHdl->GetVkPipelineLayout(), - boundPipelineLayoutHdl->GetPushConstantInterface().GetShaderStageFlags(), + auto layoutHdl = bindPointData[static_cast(bindPoint)].boundPipelineLayoutHdl; + vkCommandBuffer.pushConstants(layoutHdl->GetVkPipelineLayout(), + layoutHdl->GetPushConstantInterface().GetShaderStageFlags(), 0, - boundPipelineLayoutHdl->GetPushConstantInterface().GetSize(), pushConstantData); + layoutHdl->GetPushConstantInterface().GetSize(), pushConstantData); } /***************************************************************************/ @@ -695,7 +703,7 @@ namespace SHADE , usageFlags{ rhs.usageFlags } , commandBufferCount{ rhs.commandBufferCount } , parentPool{ rhs.parentPool } - , boundPipelineLayoutHdl{ rhs.boundPipelineLayoutHdl } + , bindPointData{ std::move (rhs.bindPointData)} { memcpy(pushConstantData, rhs.pushConstantData, PUSH_CONSTANT_SIZE); @@ -728,7 +736,7 @@ namespace SHADE usageFlags = rhs.usageFlags; commandBufferCount = rhs.commandBufferCount; parentPool = rhs.parentPool; - boundPipelineLayoutHdl = rhs.boundPipelineLayoutHdl; + bindPointData = std::move(rhs.bindPointData); memcpy(pushConstantData, rhs.pushConstantData, PUSH_CONSTANT_SIZE); rhs.vkCommandBuffer = VK_NULL_HANDLE; diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h index 9416a1aa..70a209ee 100644 --- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h +++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h @@ -6,6 +6,7 @@ #include "SHCommandPoolResetMode.h" #include "Resource/ResourceLibrary.h" #include "Graphics/Pipeline/SHVkPipelineLayout.h" +#include "Graphics/Pipeline/SHPipelineType.h" namespace SHADE { @@ -39,7 +40,14 @@ namespace SHADE friend class ResourceLibrary; static constexpr uint16_t PUSH_CONSTANT_SIZE = 512; + private: + struct PipelineBindPointData + { + //! The currently bound pipeline + Handle boundPipelineLayoutHdl; + }; + /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER VARIABLES */ /*-----------------------------------------------------------------------*/ @@ -66,8 +74,8 @@ namespace SHADE //! The command pool that this command buffer belongs to Handle parentPool; - //! The currently bound pipeline - Handle boundPipelineLayoutHdl; + //! Every command buffer will have a set of pipeline bind point specific data + std::array(SH_PIPELINE_TYPE::NUM_TYPES)> bindPointData; //! The push constant data for the command buffer uint8_t pushConstantData[PUSH_CONSTANT_SIZE]; @@ -112,13 +120,16 @@ namespace SHADE void BindPipeline (Handle const& pipelineHdl) noexcept; void BindVertexBuffer (uint32_t bindingPoint, Handle const& buffer, vk::DeviceSize offset) noexcept; void BindIndexBuffer (Handle const& buffer, uint32_t startingIndex) const noexcept; - void BindDescriptorSet (Handle descSetGroup, vk::PipelineBindPoint bindPoint, uint32_t firstSet, std::span dynamicOffsets); + void BindDescriptorSet (Handle descSetGroup, SH_PIPELINE_TYPE bindPoint, uint32_t firstSet, std::span dynamicOffsets); // Draw Commands void DrawArrays (uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) const noexcept; void DrawIndexed (uint32_t indexCount, uint32_t firstIndex, uint32_t vertexOffset) const noexcept; void DrawMultiIndirect (Handle indirectDrawData, uint32_t drawCount); + // Compute Commands + void ComputeDispatch (uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ) noexcept; + // Buffer Copy void CopyBufferToImage (const vk::Buffer& src, const vk::Image& dst, const std::vector& copyInfo); void CopyImageToBuffer (const vk::Image& src, const vk::Buffer& dst, const std::vector& copyInfo); @@ -138,13 +149,13 @@ namespace SHADE // Push Constant variable setting template - void SetPushConstantVariable(std::string variableName, T const& data) noexcept + void SetPushConstantVariable(std::string variableName, T const& data, SH_PIPELINE_TYPE bindPoint) noexcept { - memcpy (static_cast(pushConstantData) + boundPipelineLayoutHdl->GetPushConstantInterface().GetOffset(variableName), &data, sizeof (T)); + memcpy (static_cast(pushConstantData) + bindPointData[static_cast(bindPoint)].boundPipelineLayoutHdl->GetPushConstantInterface().GetOffset(variableName), &data, sizeof (T)); }; - void ForceSetPipelineLayout (Handle pipelineLayout) noexcept; + void ForceSetPipelineLayout (Handle pipelineLayout, SH_PIPELINE_TYPE pipelineType) noexcept; - void SubmitPushConstants (void) const noexcept; + void SubmitPushConstants (SH_PIPELINE_TYPE bindPoint) const noexcept; /*-----------------------------------------------------------------------*/ /* GETTERS AND SETTERS */ diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp index ea859718..de68c583 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp @@ -91,7 +91,7 @@ namespace SHADE // new write for the binding updater.writeInfos.emplace_back(); - updater.writeHashMap.try_emplace(writeHash, updater.writeInfos.size() - 1); + updater.writeHashMap.try_emplace(writeHash, static_cast(updater.writeInfos.size()) - 1u); auto& writeInfo = updater.writeInfos.back(); // Descriptor count for the write descriptor set. Usually this is set to 1, but if binding is variable sized, set to info passed in @@ -102,10 +102,10 @@ namespace SHADE //case vk::DescriptorType::eSampler: //case vk::DescriptorType::eSampledImage: case vk::DescriptorType::eCombinedImageSampler: + case vk::DescriptorType::eStorageImage: + case vk::DescriptorType::eInputAttachment: writeInfo.descImageInfos.resize(descriptorCount); - break; - //case vk::DescriptorType::eStorageImage: - // break; + break; case vk::DescriptorType::eUniformTexelBuffer: case vk::DescriptorType::eStorageTexelBuffer: case vk::DescriptorType::eUniformBuffer: @@ -165,6 +165,7 @@ namespace SHADE if (imageViewsAndSamplers.size() > writeInfo.descImageInfos.size()) { SHLOG_ERROR("Attempting write too many descriptors into descriptor set. Failed to write to vk::WriteDescriptorSet. "); + return; } for (uint32_t i = 0; i < imageViewsAndSamplers.size(); ++i) diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h index f2b886e8..85c3ef97 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h @@ -31,6 +31,8 @@ namespace SHADE class SHVkDescriptorSetGroup { public: + using viewSamplerLayout = std::tuple, Handle, vk::ImageLayout>; + /*-----------------------------------------------------------------------------*/ /* Constructor/Destructors */ /*-----------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index 2705b4d1..40826047 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -369,7 +369,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ void SHBatch::Draw(Handle cmdBuffer, uint32_t frameIndex) { - if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS) + if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS) { SHLOG_WARNING("[SHBatch] Attempted to draw a batch with an invalid frame index."); return; @@ -385,7 +385,7 @@ namespace SHADE cmdBuffer->BindDescriptorSet ( matPropsDescSet[frameIndex], - vk::PipelineBindPoint::eGraphics, + SH_PIPELINE_TYPE::GRAPHICS, SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, dynamicOffset ); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp index add51196..14f2aa76 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp @@ -20,91 +20,91 @@ of DigiPen Institute of Technology is prohibited. namespace SHADE { - /*---------------------------------------------------------------------------------*/ - /* Constructor/Destructors */ - /*---------------------------------------------------------------------------------*/ + /*---------------------------------------------------------------------------------*/ + /* Constructor/Destructors */ + /*---------------------------------------------------------------------------------*/ - SHSuperBatch::SHSuperBatch(Handle sp) - : subpass { sp } - {} + SHSuperBatch::SHSuperBatch(Handle sp) + : subpass{ sp } + {} - /*---------------------------------------------------------------------------------*/ - /* Usage Functions */ - /*---------------------------------------------------------------------------------*/ - void SHSuperBatch::Add(const SHRenderable* renderable) noexcept + /*---------------------------------------------------------------------------------*/ + /* Usage Functions */ + /*---------------------------------------------------------------------------------*/ + void SHSuperBatch::Add(const SHRenderable* renderable) noexcept + { + const Handle PIPELINE = renderable->GetMaterial()->GetBaseMaterial()->GetPipeline(); + + // Check if we have a batch with the same pipeline first + auto batch = std::find_if(batches.begin(), batches.end(), [&](const SHBatch& batch) + { + return batch.GetPipeline() == PIPELINE; + }); + + + // Create one if not found + if (batch == batches.end()) { - const Handle PIPELINE = renderable->GetMaterial()->GetBaseMaterial()->GetPipeline(); - - // Check if we have a batch with the same pipeline first - auto batch = std::find_if(batches.begin(), batches.end(), [&](const SHBatch& batch) - { - return batch.GetPipeline() == PIPELINE; - }); - - - // Create one if not found - if (batch == batches.end()) - { - batches.emplace_back(PIPELINE); - batch = batches.end() - 1; - } - - // Add renderable in - batch->Add(renderable); + batches.emplace_back(PIPELINE); + batch = batches.end() - 1; } - void SHSuperBatch::Remove(const SHRenderable* renderable) noexcept + // Add renderable in + batch->Add(renderable); + } + + void SHSuperBatch::Remove(const SHRenderable* renderable) noexcept + { + const Handle PIPELINE = renderable->GetMaterial()->GetBaseMaterial()->GetPipeline(); + + // Check if we have a Batch with the same pipeline yet + auto batch = std::find_if(batches.begin(), batches.end(), [&](const SHBatch& batch) + { + return batch.GetPipeline() == PIPELINE; + }); + + // Attempt to remove if it exists + if (batch == batches.end()) + return; + + batch->Remove(renderable); + } + + void SHSuperBatch::Clear() noexcept + { + for (auto& batch : batches) { - const Handle PIPELINE = renderable->GetMaterial()->GetBaseMaterial()->GetPipeline(); - - // Check if we have a Batch with the same pipeline yet - auto batch = std::find_if(batches.begin(), batches.end(), [&](const SHBatch& batch) - { - return batch.GetPipeline() == PIPELINE; - }); - - // Attempt to remove if it exists - if (batch == batches.end()) - return; - - batch->Remove(renderable); + batch.Clear(); } + batches.clear(); + } - void SHSuperBatch::Clear() noexcept + void SHSuperBatch::UpdateBuffers(uint32_t frameIndex, Handle descPool) + { + for (auto& batch : batches) { - for (auto& batch : batches) - { - batch.Clear(); - } - batches.clear(); + batch.UpdateMaterialBuffer(frameIndex, descPool); + batch.UpdateTransformBuffer(frameIndex); + batch.UpdateEIDBuffer(frameIndex); } + } - void SHSuperBatch::UpdateBuffers(uint32_t frameIndex, Handle descPool) + void SHSuperBatch::Build(Handle device, Handle descPool, uint32_t frameIndex) noexcept + { + // Build all batches + for (auto& batch : batches) { - for (auto& batch : batches) - { - batch.UpdateMaterialBuffer(frameIndex, descPool); - batch.UpdateTransformBuffer(frameIndex); - batch.UpdateEIDBuffer(frameIndex); - } + batch.Build(device, descPool, frameIndex); } + } - void SHSuperBatch::Build(Handle device, Handle descPool, uint32_t frameIndex) noexcept + void SHSuperBatch::Draw(Handle cmdBuffer, uint32_t frameIndex) noexcept + { + // Build all batches + for (auto& batch : batches) { - // Build all batches - for (auto& batch : batches) - { - batch.Build(device, descPool, frameIndex); - } - } - - void SHSuperBatch::Draw(Handle cmdBuffer, uint32_t frameIndex) noexcept - { - // Build all batches - for (auto& batch : batches) - { - batch.Draw(cmdBuffer, frameIndex); - } + batch.Draw(cmdBuffer, frameIndex); } + } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 386cef54..992cbdf1 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -123,12 +123,12 @@ namespace SHADE shaderSourceLibrary.LoadShader(0, "TestCubeVs.glsl", SH_SHADER_TYPE::VERTEX, true); shaderSourceLibrary.LoadShader(1, "TestCubeFs.glsl", SH_SHADER_TYPE::FRAGMENT, true); - shaderSourceLibrary.LoadShader(2, "GreyscaleCs.glsl", SH_SHADER_TYPE::COMPUTE, true); + shaderSourceLibrary.LoadShader(2, "KirschCs.glsl", SH_SHADER_TYPE::COMPUTE, true); shaderModuleLibrary.ImportFromSourceLibrary(device, shaderSourceLibrary); auto cubeVS = shaderModuleLibrary.GetShaderModule("TestCubeVs.glsl"); auto cubeFS = shaderModuleLibrary.GetShaderModule("TestCubeFs.glsl"); - auto greyscale = shaderModuleLibrary.GetShaderModule("GreyscaleCs.glsl"); + auto greyscale = shaderModuleLibrary.GetShaderModule("KirschCs.glsl"); cubeVS->Reflect(); cubeFS->Reflect(); greyscale->Reflect(); @@ -171,28 +171,25 @@ namespace SHADE // Initialize world render graph worldRenderGraph->Init(device, swapchain); - worldRenderGraph->AddResource("Scene", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT }, windowDims.first, windowDims.second); + worldRenderGraph->AddResource("Scene Pre Postprocess", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second); + worldRenderGraph->AddResource("Scene", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second); worldRenderGraph->AddResource("Depth Buffer", { SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); worldRenderGraph->AddResource("Entity ID", { SH_ATT_DESC_TYPE_FLAGS::COLOR }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); - auto node = worldRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Scene"}, {}); // no predecessors + auto node = worldRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Scene", "Scene Pre Postprocess"}, {}); // no predecessors //First subpass to write to G-Buffer auto gBufferWriteSubpass = node->AddSubpass("G-Buffer Write"); - gBufferWriteSubpass->AddColorOutput("Scene"); + gBufferWriteSubpass->AddColorOutput("Scene Pre Postprocess"); gBufferWriteSubpass->AddColorOutput("Entity ID"); gBufferWriteSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL); - auto greyscale = shaderModuleLibrary.GetShaderModule("GreyscaleCs.glsl"); - - auto greyscaleSubpass = node->AddSubpass("Greyscale Subpass"); - greyscaleSubpass->AddGeneralInput("Scene"); - greyscaleSubpass->AddSubpassCompute(greyscale); - - // We do this to just transition our scene layout to shader read - auto sceneLayoutTransitionSubpass = node->AddSubpass("Scene Layout Transition"); - sceneLayoutTransitionSubpass->AddInput("Scene"); + //auto sceneLayoutTransitionSubpass = node->AddSubpass("Scene Layout Transition"); + //sceneLayoutTransitionSubpass->AddGeneralInput("Scene"); + + auto greyscale = shaderModuleLibrary.GetShaderModule("KirschCs.glsl"); + node->AddNodeCompute (greyscale, {"Scene Pre Postprocess", "Scene"}); // Generate world render graph worldRenderGraph->Generate(); @@ -375,7 +372,7 @@ namespace SHADE uint32_t h = static_cast(viewports[vpIndex]->GetHeight()); currentCmdBuffer->SetViewportScissor (static_cast(w), static_cast(h), w, h); - currentCmdBuffer->ForceSetPipelineLayout(SHGraphicsGlobalData::GetDummyPipelineLayout()); + currentCmdBuffer->ForceSetPipelineLayout(SHGraphicsGlobalData::GetDummyPipelineLayout(), SH_PIPELINE_TYPE::GRAPHICS); // Bind all the buffers required for meshes for (auto& [buffer, bindingPoint] : MESH_DATA) @@ -395,7 +392,7 @@ namespace SHADE currentCmdBuffer->BindDescriptorSet ( textureDescSet, - vk::PipelineBindPoint::eGraphics, + SH_PIPELINE_TYPE::GRAPHICS, 0, texDynamicOffset ); @@ -741,8 +738,8 @@ namespace SHADE auto cameraSystem = SHSystemManager::GetSystem(); #ifdef SHEDITOR - cameraSystem->GetEditorCamera()->SetWidth(resizeWidth); - cameraSystem->GetEditorCamera()->SetHeight(resizeHeight); + cameraSystem->GetEditorCamera()->SetWidth(static_cast(resizeWidth)); + cameraSystem->GetEditorCamera()->SetHeight(static_cast(resizeHeight)); #else #endif diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp index 8b41a979..ebce5c9e 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp @@ -68,7 +68,7 @@ namespace SHADE { std::vector combinedImageSampler { - std::make_tuple(offscreenRender->GetImageView(), offscreenRenderSampler, vk::ImageLayout::eShaderReadOnlyOptimal), + std::make_tuple(offscreenRender->GetImageView(), offscreenRenderSampler, vk::ImageLayout::eGeneral), }; // Register the image view and sampler with the descriptor set. Now whenever rendering to the offscreen image is done, the descriptor set will see the change diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp index 2532f308..a1806ccd 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp @@ -82,7 +82,7 @@ namespace SHADE std::array dynamicOffsets{ frameIndex * cameraDataAlignedSize }; - cmdBuffer->BindDescriptorSet(cameraDescriptorSet, vk::PipelineBindPoint::eGraphics, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 }); + cmdBuffer->BindDescriptorSet(cameraDescriptorSet, SH_PIPELINE_TYPE::GRAPHICS, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 }); } } diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineType.h b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineType.h index e7f5b6a8..2c1c80ff 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineType.h +++ b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineType.h @@ -5,9 +5,13 @@ namespace SHADE { enum class SH_PIPELINE_TYPE { - GRAPHICS, + GRAPHICS = 0, COMPUTE, + RAY_TRACING, + NUM_TYPES, }; + + } #endif \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.cpp b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.cpp index 973218d1..973ae72f 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.cpp +++ b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.cpp @@ -4,6 +4,7 @@ #include "Graphics/Shaders/SHVkShaderModule.h" #include "Graphics/Debugging/SHVulkanDebugUtil.h" #include "Graphics/RenderGraph/SHRenderGraph.h" +#include "Graphics/SHVkUtil.h" namespace SHADE { @@ -268,7 +269,7 @@ namespace SHADE , logicalDeviceHdl{ rhs.logicalDeviceHdl } , pipelineLayout { rhs.pipelineLayout } { - vkPipeline = VK_NULL_HANDLE; + rhs.vkPipeline = VK_NULL_HANDLE; } /***************************************************************************/ @@ -308,7 +309,8 @@ namespace SHADE /***************************************************************************/ SHVkPipeline::~SHVkPipeline(void) noexcept { - logicalDeviceHdl->GetVkLogicalDevice().destroyPipeline(vkPipeline, nullptr); + if (vkPipeline) + logicalDeviceHdl->GetVkLogicalDevice().destroyPipeline(vkPipeline, nullptr); } /***************************************************************************/ @@ -336,7 +338,7 @@ namespace SHADE created = rhs.created; logicalDeviceHdl = rhs.logicalDeviceHdl; - vkPipeline = VK_NULL_HANDLE; + rhs.vkPipeline = VK_NULL_HANDLE; return *this; } @@ -422,18 +424,7 @@ namespace SHADE /***************************************************************************/ vk::PipelineBindPoint SHVkPipeline::GetPipelineBindPoint(void) const noexcept { - switch (pipelineType) - { - case SH_PIPELINE_TYPE::GRAPHICS: - return vk::PipelineBindPoint::eGraphics; - case SH_PIPELINE_TYPE::COMPUTE: - return vk::PipelineBindPoint::eCompute; - break; - default: - return vk::PipelineBindPoint::eGraphics; - break; - - } + return SHVkUtil::GetPipelineBindPointFromType(pipelineType); } /***************************************************************************/ @@ -473,4 +464,9 @@ namespace SHADE return pipelineLayout; } + SH_PIPELINE_TYPE SHVkPipeline::GetPipelineType(void) const noexcept + { + return pipelineType; + } + } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.h b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.h index fe55a41e..9ec18650 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.h +++ b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.h @@ -77,6 +77,7 @@ namespace SHADE vk::Pipeline GetVkPipeline (void) const noexcept; bool GetIsCreated (void) const noexcept; Handle GetPipelineLayout (void) const noexcept; + SH_PIPELINE_TYPE GetPipelineType (void) const noexcept; }; } diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp index 7a76447d..37d00795 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp +++ b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp @@ -216,9 +216,18 @@ namespace SHADE /***************************************************************************/ void SHVkPipelineLayout::PrepareVkDescriptorSetLayouts(void) noexcept { + // pipeline layouts contain global layouts first, then layouts for allocation descriptorSetLayoutsPipeline.reserve(descriptorSetLayoutsAllocate.size() + descriptorSetLayoutsGlobal.size()); + vkDescriptorSetLayoutsPipeline.reserve(descriptorSetLayoutsAllocate.size() + descriptorSetLayoutsGlobal.size()); - // Settle allocate layouts first + // First we insert the global layouts + for (auto const& layout : descriptorSetLayoutsGlobal) + { + descriptorSetLayoutsPipeline.emplace_back(layout); + //vkDescriptorSetLayoutsPipeline.emplace_back(layout->GetVkHandle()); + } + + // Then the allocate layouts vkDescriptorSetLayoutsAllocate.reserve(descriptorSetLayoutsAllocate.size()); for (auto const& layout : descriptorSetLayoutsAllocate) { @@ -226,18 +235,13 @@ namespace SHADE vkDescriptorSetLayoutsAllocate.emplace_back(layout->GetVkHandle()); } - // pipeline layouts contain global layouts first, then layouts for allocation - vkDescriptorSetLayoutsPipeline.reserve(descriptorSetLayoutsAllocate.size() + descriptorSetLayoutsGlobal.size()); - - // First we insert the global layouts - for (auto const& layout : descriptorSetLayoutsGlobal) + for (auto const& layout : descriptorSetLayoutsPipeline) { - descriptorSetLayoutsPipeline.emplace_back(layout); vkDescriptorSetLayoutsPipeline.emplace_back(layout->GetVkHandle()); } // Then we append layouts for allocation at the back of the vector - std::copy(vkDescriptorSetLayoutsAllocate.begin(), vkDescriptorSetLayoutsAllocate.end(), std::back_inserter(vkDescriptorSetLayoutsPipeline)); + //std::copy(vkDescriptorSetLayoutsAllocate.begin(), vkDescriptorSetLayoutsAllocate.end(), std::back_inserter(vkDescriptorSetLayoutsPipeline)); } /***************************************************************************/ @@ -294,6 +298,7 @@ namespace SHADE , descriptorSetLayoutsGlobal{pipelineLayoutParams.globalDescSetLayouts } // do a copy, some other pipeline layout might need this , descriptorSetLayoutsAllocate{} , vkDescriptorSetLayoutsAllocate{} + , descriptorSetLayoutsPipeline{} , vkDescriptorSetLayoutsPipeline{} { for (auto& mod : shaderModules) @@ -318,6 +323,7 @@ namespace SHADE , descriptorSetLayoutsGlobal{} , descriptorSetLayoutsAllocate{} , vkDescriptorSetLayoutsAllocate{} + , descriptorSetLayoutsPipeline{} , vkDescriptorSetLayoutsPipeline{} { @@ -368,7 +374,8 @@ namespace SHADE , descriptorSetLayoutsGlobal {std::move (rhs.descriptorSetLayoutsGlobal)} , descriptorSetLayoutsAllocate {std::move (rhs.descriptorSetLayoutsAllocate)} , vkDescriptorSetLayoutsAllocate{std::move (rhs.vkDescriptorSetLayoutsAllocate)} - , vkDescriptorSetLayoutsPipeline{std::move (rhs.vkDescriptorSetLayoutsAllocate)} + , descriptorSetLayoutsPipeline { std::move(rhs.descriptorSetLayoutsPipeline) } + , vkDescriptorSetLayoutsPipeline{ std::move(rhs.vkDescriptorSetLayoutsPipeline) } { rhs.vkPipelineLayout = VK_NULL_HANDLE; } @@ -441,12 +448,12 @@ namespace SHADE return {}; } - std::vector> SHVkPipelineLayout::GetDescriptorSetLayoutsPipeline(void) const noexcept + std::vector> const& SHVkPipelineLayout::GetDescriptorSetLayoutsPipeline(void) const noexcept { return descriptorSetLayoutsPipeline; } - std::vector> SHVkPipelineLayout::GetDescriptorSetLayoutsAllocate(void) const noexcept + std::vector> const& SHVkPipelineLayout::GetDescriptorSetLayoutsAllocate(void) const noexcept { return descriptorSetLayoutsAllocate; } @@ -464,7 +471,8 @@ namespace SHADE descriptorSetLayoutsGlobal = std::move(rhs.descriptorSetLayoutsGlobal); descriptorSetLayoutsAllocate = std::move(rhs.descriptorSetLayoutsAllocate); vkDescriptorSetLayoutsAllocate = std::move(rhs.vkDescriptorSetLayoutsAllocate); - vkDescriptorSetLayoutsPipeline = std::move(rhs.vkDescriptorSetLayoutsAllocate); + descriptorSetLayoutsPipeline = std::move(rhs.descriptorSetLayoutsPipeline); + vkDescriptorSetLayoutsPipeline = std::move(rhs.vkDescriptorSetLayoutsPipeline); rhs.vkPipelineLayout = VK_NULL_HANDLE; diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.h b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.h index f5d363fa..b4298e00 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.h +++ b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.h @@ -74,12 +74,12 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ /*-----------------------------------------------------------------------*/ - std::vector> const& GetShaderModules (void) const noexcept; - vk::PipelineLayout GetVkPipelineLayout (void) const noexcept; - SHPushConstantInterface const& GetPushConstantInterface (void) const noexcept; - Handle GetShaderBlockInterface (uint32_t set, uint32_t binding, vk::ShaderStageFlagBits shaderStage) const noexcept; - std::vector> GetDescriptorSetLayoutsPipeline(void) const noexcept; - std::vector> GetDescriptorSetLayoutsAllocate(void) const noexcept; + std::vector> const& GetShaderModules (void) const noexcept; + vk::PipelineLayout GetVkPipelineLayout (void) const noexcept; + SHPushConstantInterface const& GetPushConstantInterface (void) const noexcept; + Handle GetShaderBlockInterface (uint32_t set, uint32_t binding, vk::ShaderStageFlagBits shaderStage) const noexcept; + std::vector> const& GetDescriptorSetLayoutsPipeline(void) const noexcept; + std::vector> const& GetDescriptorSetLayoutsAllocate(void) const noexcept; }; } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescriptionType.h b/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescriptionType.h index efd3fb0f..c4d44ea8 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescriptionType.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescriptionType.h @@ -10,7 +10,8 @@ namespace SHADE DEPTH = 0x04, STENCIL = 0x08, DEPTH_STENCIL = 0x10, - INPUT = 0x20 + INPUT = 0x20, + STORAGE = 0x40 }; } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index df588c05..1c0798f1 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -10,7 +10,7 @@ #include "Tools/SHLogger.h" #include "SHAttachmentDescInitParams.h" #include "SHRenderGraphStorage.h" -#include "Graphics/RenderGraph/SHSubpassCompute.h" +#include "Graphics/RenderGraph/SHRenderGraphNodeCompute.h" namespace SHADE { @@ -59,7 +59,7 @@ namespace SHADE format = renderGraphStorage->swapchain->GetSurfaceFormatKHR().format; } - graphResources.try_emplace(resourceName, resourceManager->Create(renderGraphStorage, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags)); + renderGraphStorage->graphResources->try_emplace(resourceName, resourceManager->Create(renderGraphStorage, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags)); } /***************************************************************************/ @@ -104,16 +104,6 @@ namespace SHADE for (auto& input : subpass->inputReferences) resourceAttFinalLayouts[input.attachment] = input.layout; - - // Go through all subpass computes and initialize final layouts to GENERAL when a resource is detected to be used in it - //for (auto sbCompute : subpass->subpassComputes) - //{ - // auto const& indices = sbCompute->attachmentDescriptionIndices; - // for (auto& index : indices) - // { - // resourceAttFinalLayouts[index] = vk::ImageLayout::eGeneral; - // } - //} } for (uint32_t j = 0; j < node->attachmentDescriptions.size(); ++j) @@ -188,7 +178,7 @@ namespace SHADE // Now we want to loop through all attachments in all subpasses in the node and query // the resources being used. For each resource we want to query the type and record it // in bit fields (1 bit for each subpass). - uint32_t colorRead = 0, colorWrite = 0, depthRead = 0, depthWrite = 0, inputDependencies = 0, descriptorDependencies = 0; + uint32_t colorRead = 0, colorWrite = 0, depthRead = 0, depthWrite = 0, inputDependencies = 0; uint32_t i = 0; @@ -227,9 +217,6 @@ namespace SHADE if (subpass->inputReferences.size()) inputDependencies |= (1 << i); - if (!subpass->subpassComputes.empty()) - descriptorDependencies |= (1 << i); - // Input attachments can be any type, so we need to check what type it is for (auto& inputAtt : subpass->inputReferences) { @@ -295,12 +282,6 @@ namespace SHADE dstAccess |= vk::AccessFlagBits::eInputAttachmentRead; } - if (descriptorDependencies & (1 << i)) - { - dstStage |= vk::PipelineStageFlagBits::eComputeShader; - dstAccess |= vk::AccessFlagBits::eShaderWrite | vk::AccessFlagBits::eShaderRead; - } - //// If subpass of first renderpass, stage flag should be bottom of pipe //if (&node == &nodes.front() && i == 0) // srcStage = vk::PipelineStageFlagBits::eBottomOfPipe; @@ -316,8 +297,8 @@ namespace SHADE dep.srcStageMask = srcStage; - // initialize the barriers - //node->subpasses[i]->InitComputeBarriers(); + // initialize input descriptors + node->subpasses[i]->CreateInputDescriptors(); } } } @@ -371,15 +352,16 @@ namespace SHADE /***************************************************************************/ void SHRenderGraph::Init(Handle logicalDevice, Handle swapchain) noexcept { + resourceManager = std::make_shared(); + renderGraphStorage = resourceManager->Create(); + renderGraphStorage->graphResources = resourceManager->Create>>(); renderGraphStorage->logicalDevice = logicalDevice; renderGraphStorage->swapchain = swapchain; renderGraphStorage->resourceManager = resourceManager; renderGraphStorage->descriptorPool = logicalDevice->CreateDescriptorPools(); - - renderGraphStorage->ptrToResources = &graphResources; } /***************************************************************************/ @@ -396,20 +378,17 @@ namespace SHADE SHRenderGraph::SHRenderGraph(void) noexcept : renderGraphStorage{} , nodes{} - , graphResources{} , resourceManager{nullptr} { - resourceManager = std::make_shared(); } SHRenderGraph::SHRenderGraph(SHRenderGraph&& rhs) noexcept : renderGraphStorage{ rhs.renderGraphStorage } , nodeIndexing{ std::move(rhs.nodeIndexing) } , nodes{ std::move(rhs.nodes) } - , graphResources{ std::move(rhs.graphResources) } , resourceManager{ std::move(rhs.resourceManager) } { - + } SHRenderGraph& SHRenderGraph::operator=(SHRenderGraph&& rhs) noexcept @@ -420,7 +399,6 @@ namespace SHADE renderGraphStorage = rhs.renderGraphStorage; nodeIndexing = std::move(rhs.nodeIndexing); nodes = std::move(rhs.nodes); - graphResources = std::move(rhs.graphResources); resourceManager = std::move(rhs.resourceManager); return *this; @@ -456,12 +434,12 @@ namespace SHADE for (auto const& instruction : resourceInstruction) { // If the resource that the new node is requesting for exists, allow the graph to reference it - if (graphResources.contains(instruction.resourceName)) + if (renderGraphStorage->graphResources->contains(instruction.resourceName)) { descInitParams.push_back( { - .resourceHdl = graphResources.at(instruction.resourceName), - .dontClearOnLoad = false, + .resourceHdl = renderGraphStorage->graphResources->at(instruction.resourceName), + .dontClearOnLoad = instruction.dontClearOnLoad, } ); } @@ -506,12 +484,31 @@ namespace SHADE /***************************************************************************/ void SHRenderGraph::Generate(void) noexcept { + CheckForNodeComputes(); ConfigureAttachmentDescriptions(); ConfigureSubpasses(); ConfigureRenderpasses(); ConfigureFramebuffers(); } + /***************************************************************************/ + /*! + + \brief + This function goes through all renderpasses and checks for existence of + node computes. If they exist, adds dummy subpasses to transition resources + into general. + + */ + /***************************************************************************/ + void SHRenderGraph::CheckForNodeComputes(void) noexcept + { + for (auto& node : nodes) + { + node->AddDummySubpassIfNeeded(); + } + } + // TODO: The graph scope buffers were meant to bind vertex buffers and index buffers for meshes. Find a // better way to manage these void SHRenderGraph::Execute(uint32_t frameIndex, Handle cmdBuffer, Handle descPool) noexcept @@ -531,7 +528,7 @@ namespace SHADE void SHRenderGraph::HandleResize(uint32_t newWidth, uint32_t newHeight) noexcept { // resize resources - for (auto& [name, resource]: graphResources) + for (auto& [name, resource] : *renderGraphStorage->graphResources) resource->HandleResize(newWidth, newHeight); for (auto& node : nodes) @@ -551,9 +548,9 @@ namespace SHADE Handle SHRenderGraph::GetRenderGraphResource(std::string const& resourceName) const noexcept { - if (graphResources.contains(resourceName)) + if (renderGraphStorage->graphResources->contains(resourceName)) { - return graphResources.at(resourceName); + return renderGraphStorage->graphResources->at(resourceName); } return {}; } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h index 529476cf..b445134c 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h @@ -66,9 +66,6 @@ namespace SHADE //! Render graph nodes std::vector> nodes; - //! Resources that exist for the entire render graph - std::unordered_map> graphResources; - //! Resource library for graph handles std::shared_ptr resourceManager; @@ -88,10 +85,11 @@ namespace SHADE 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; - void Generate (void) noexcept; - void Execute (uint32_t frameIndex, Handle cmdBuffer, Handle descPool) noexcept; - void FinaliseBatch(uint32_t frameIndex, Handle descPool); - void HandleResize (uint32_t newWidth, uint32_t newHeight) noexcept; + void Generate (void) noexcept; + void CheckForNodeComputes (void) noexcept; + void Execute (uint32_t frameIndex, Handle cmdBuffer, Handle descPool) noexcept; + void FinaliseBatch (uint32_t frameIndex, Handle descPool); + void HandleResize (uint32_t newWidth, uint32_t newHeight) noexcept; /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp index 0d88a93a..c315bffd 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp @@ -7,6 +7,8 @@ #include "SHRenderGraphResource.h" #include "SHSubpass.h" #include "SHRenderGraphStorage.h" +#include "Graphics/RenderGraph/SHRenderGraphNodeCompute.h" +#include "Graphics/SHVkUtil.h" namespace SHADE { @@ -80,7 +82,6 @@ namespace SHADE fbHeight = attResources[j]->height; } - framebuffers[i]->HandleResize(renderpass, imageViews, fbWidth, fbHeight); } @@ -88,6 +89,11 @@ namespace SHADE { subpass->HandleResize(); } + + for (auto& nodeCompute : nodeComputes) + { + nodeCompute->HandleResize(); + } } /***************************************************************************/ @@ -121,6 +127,7 @@ namespace SHADE , subpasses{} , executed{ false } , configured{ false } + , nodeComputes{} { // pipeline library initialization pipelineLibrary.Init(graphStorage->logicalDevice); @@ -181,6 +188,7 @@ namespace SHADE , batcher{ std::move(rhs.batcher) } , spDescs{ std::move(rhs.spDescs) } , spDeps{ std::move(rhs.spDeps) } + , nodeComputes{ std::move(rhs.nodeComputes) } { rhs.renderpass = {}; @@ -204,6 +212,7 @@ namespace SHADE batcher = std::move(rhs.batcher); spDescs = std::move(rhs.spDescs); spDeps = std::move(rhs.spDeps); + nodeComputes = std::move(rhs.nodeComputes); rhs.renderpass = {}; @@ -235,7 +244,7 @@ namespace SHADE } // Add subpass to container and create mapping for it - subpasses.emplace_back(graphStorage->resourceManager->Create(graphStorage, GetHandle(), subpasses.size(), &resourceAttachmentMapping)); + subpasses.emplace_back(graphStorage->resourceManager->Create(graphStorage, GetHandle(), static_cast(subpasses.size()), &resourceAttachmentMapping)); subpassIndexing.try_emplace(subpassName, static_cast(subpasses.size()) - 1u); Handle subpass = subpasses.back(); subpass->Init(*graphStorage->resourceManager); @@ -246,21 +255,84 @@ namespace SHADE return subpass; } + Handle SHRenderGraphNode::AddNodeCompute(Handle computeShaderModule, std::initializer_list resources, float numWorkGroupScale/* = 1.0f*/) noexcept + { + // Look for the required resources in the graph + std::vector> nodeComputeResources{}; + nodeComputeResources.reserve(resources.size()); + + for (auto& resourceName : resources) + { + auto resource = graphStorage->graphResources->at(resourceName); + nodeComputeResources.push_back(resource); + } + + // Create the subpass compute with the resources + auto nodeCompute = graphStorage->resourceManager->Create(graphStorage, computeShaderModule, std::move(nodeComputeResources)); + nodeComputes.push_back(nodeCompute); + + return nodeCompute; + } + + /***************************************************************************/ + /*! + + \brief + This function checks all node computes and adds a subpass to transition + all needed resources to general. + + */ + /***************************************************************************/ + void SHRenderGraphNode::AddDummySubpassIfNeeded(void) noexcept + { + if (!nodeComputes.empty()) + { + // we save the resource names involved + std::unordered_set resourcesInvolved; + for (auto& compute : nodeComputes) + { + for (auto& resource : compute->resources) + { + resourcesInvolved.emplace(resource->GetName()); + } + } + + // insert them all for a subpass to transition them. This subpass is the last subpass + auto dummySubpass = AddSubpass("dummy"); + for (auto& resource : resourcesInvolved) + { + dummySubpass->AddGeneralInput(resource); + + if (SHVkUtil::IsDepthStencilAttachment(graphStorage->graphResources->at(resource)->GetResourceFormat())) + dummySubpass->AddGeneralDepthOutput(resource); + else + dummySubpass->AddGeneralColorOutput(resource); + } + } + } + void SHRenderGraphNode::Execute(Handle& commandBuffer, Handle descPool, uint32_t frameIndex) noexcept { - frameIndex = (framebuffers.size() > 1) ? frameIndex : 0; - commandBuffer->BeginRenderpass(renderpass, framebuffers[frameIndex]); + uint32_t framebufferIndex = (framebuffers.size() > 1) ? frameIndex : 0; + commandBuffer->BeginRenderpass(renderpass, framebuffers[framebufferIndex]); for (uint32_t i = 0; i < subpasses.size(); ++i) { subpasses[i]->Execute(commandBuffer, descPool, frameIndex); // Go to next subpass if not last subpass - if (i != subpasses.size() - 1) + if (i != static_cast(subpasses.size()) - 1u) commandBuffer->NextSubpass(); } commandBuffer->EndRenderpass(); + + + // Execute all subpass computes + for (auto& sbCompute : nodeComputes) + { + sbCompute->Execute(commandBuffer, frameIndex); + } } Handle SHRenderGraphNode::GetOrCreatePipeline(std::pair, Handle> const& vsFsPair, Handle subpass) noexcept diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h index 7c3622ad..335b93e3 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h @@ -21,6 +21,7 @@ namespace SHADE class SHVkDescriptorPool; class SHGraphicsGlobalData; class SHRenderGraphStorage; + class SHRenderGraphNodeCompute; class SH_API SHRenderGraphNode : public ISelfHandle { @@ -67,6 +68,10 @@ namespace SHADE //! Every renderpass will require a pipeline library that will contain pipelines compatible with this renderpass SHPipelineLibrary pipelineLibrary; + //! Sometimes we want the subpass to do something to the images instead + //! of drawing objects on the image (i.e. compute). + std::vector> nodeComputes; + //! Whether or not the node has finished execution bool executed; @@ -75,6 +80,7 @@ namespace SHADE SHBatcher batcher; + /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ @@ -94,6 +100,9 @@ namespace SHADE /* PUBLIC MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ Handle AddSubpass(std::string subpassName) noexcept; + Handle AddNodeCompute(Handle computeShaderModule, std::initializer_list resources, float numWorkGroupScale = 1.0f) noexcept; + void AddDummySubpassIfNeeded (void) noexcept; + // TODO: RemoveSubpass() void Execute(Handle& commandBuffer, Handle descPool, uint32_t frameIndex) noexcept; Handle GetOrCreatePipeline(std::pair, Handle> const& vsFsPair, Handle subpass) noexcept; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp new file mode 100644 index 00000000..a5208fcf --- /dev/null +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp @@ -0,0 +1,109 @@ +#include "SHpch.h" +#include "SHRenderGraphNodeCompute.h" +#include "Graphics/Pipeline/SHVkPipeline.h" +#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" +#include "Graphics/Descriptors/SHVkDescriptorPool.h" +#include "Graphics/Descriptors/SHVkDescriptorSetLayout.h" +#include "Graphics/Devices/SHVkLogicalDevice.h" +#include "Graphics/Pipeline/SHVkPipelineLayout.h" +#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" +#include "SHRenderGraphStorage.h" +#include "SHRenderGraphResource.h" +#include "Graphics/Commands/SHVkCommandBuffer.h" + +namespace SHADE +{ + SHRenderGraphNodeCompute::SHRenderGraphNodeCompute(Handle graphStorage, Handle computeShaderModule, std::vector>&& subpassComputeResources, float inNumWorkGroupScale/* = 1.0f*/) noexcept + : computePipeline{} + , pipelineLayout{} + , resources{} + , groupSizeX{0} + , groupSizeY{0} + , numWorkGroupScale {std::clamp(inNumWorkGroupScale, 0.0f, 1.0f)} + { + SHPipelineLayoutParams pipelineLayoutParams + { + .shaderModules = {computeShaderModule}, + .globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts() + }; + + // Create pipeline layout from parameters + pipelineLayout = graphStorage->logicalDevice->CreatePipelineLayout (pipelineLayoutParams); + + // Create the compute pipeline + computePipeline = graphStorage->logicalDevice->CreateComputePipeline(pipelineLayout); + + // and construct it + computePipeline->ConstructPipeline(); + + // save the resources + resources = std::move (subpassComputeResources); + + //Get the descriptor set layouts required to allocate. We only want the ones for allocate because + //global descriptors are already bound in the main system. + auto const& layouts = computePipeline->GetPipelineLayout()->GetDescriptorSetLayoutsAllocate(); + + //Variable counts for the descriptor sets (all should be 1). + std::vector variableCounts{ static_cast(layouts.size()) }; + std::fill(variableCounts.begin(), variableCounts.end(), 0); + + // Allocate descriptor sets to hold the images for reading (STORAGE_IMAGE) + for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i) + { + descSetGroups[i] = graphStorage->descriptorPool->Allocate(layouts, variableCounts); + } + + + HandleResize(); + } + + void SHRenderGraphNodeCompute::Execute(Handle cmdBuffer, uint32_t frameIndex) noexcept + { + // bind the compute pipeline + cmdBuffer->BindPipeline(computePipeline); + + // bind descriptor sets + cmdBuffer->BindDescriptorSet(descSetGroups[frameIndex], SH_PIPELINE_TYPE::COMPUTE, SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, {}); + + // dispatch compute + cmdBuffer->ComputeDispatch(groupSizeX, groupSizeY, 1); + + // TODO: barrier + + } + + void SHRenderGraphNodeCompute::HandleResize(void) noexcept + { + // Get the layout for the render graph resource. We can index it this way because the container returned is a container of layouts that includes the global ones + auto pipelineDescSetLayouts = computePipeline->GetPipelineLayout()->GetDescriptorSetLayoutsPipeline()[SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE]; + + // everything below here needs resizing + for (uint32_t frameIndex = 0; frameIndex < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++frameIndex) + { + uint32_t i = 0; + + // loop through bindings and write descriptor sets + for (auto& binding : pipelineDescSetLayouts->GetBindings()) + { + uint32_t imageIndex = (resources[i]->resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) ? frameIndex : 0; + + SHVkDescriptorSetGroup::viewSamplerLayout vsl = std::make_tuple(resources[i]->GetImageView(imageIndex), Handle{}, vk::ImageLayout::eGeneral); + descSetGroups[frameIndex]->ModifyWriteDescImage(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint, { &vsl, 1 }); + descSetGroups[frameIndex]->UpdateDescriptorSetImages(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint); + ++i; + } + } + + // Get the group size from the max width and height + uint32_t maxWidth = 0, maxHeight = 0; + for (auto& resource : resources) + { + maxWidth = std::max(resource->GetWidth(), maxWidth); + maxHeight = std::max(resource->GetHeight(), maxHeight); + } + + groupSizeX = maxWidth / workGroupSizeX; + groupSizeY = maxHeight / workGroupSizeY; + } + +} diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.h new file mode 100644 index 00000000..e35326f7 --- /dev/null +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.h @@ -0,0 +1,57 @@ +#pragma once + +#include "Resource/Handle.h" +#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h" +#include +#include +#include + +namespace SHADE +{ + class SHVkPipeline; + class SHVkDescriptorSetGroup; + class SHVkDescriptorPool; + class SHVkLogicalDevice; + class SHVkPipelineLayout; + class SHRenderGraphStorage; + class SHRenderGraphResource; + class SHVkShaderModule; + class SHVkCommandBuffer; + + class SHRenderGraphNodeCompute + { + private: + static constexpr uint32_t workGroupSizeX = 16; + static constexpr uint32_t workGroupSizeY = 16; + + //! To run the dispatch command + Handle computePipeline; + + //! Pipeline layout for the pipeline creation + Handle pipelineLayout; + + //! Descriptor set group to hold the images for reading (STORAGE_IMAGE) + std::array, SHGraphicsConstants::NUM_FRAME_BUFFERS> descSetGroups; + + //! vector of resources needed by the subpass compute + std::vector> resources; + + //! X dimension work group size. Should scale with resource size. + uint32_t groupSizeX; + + //! Y dimension work group size + uint32_t groupSizeY; + + float numWorkGroupScale; + + public: + SHRenderGraphNodeCompute(Handle graphStorage, Handle computeShaderModule, std::vector>&& subpassComputeResources, float inNumWorkGroupScale = 1.0f) noexcept; + + void Execute (Handle cmdBuffer, uint32_t frameIndex) noexcept; + void HandleResize (void) noexcept; + + friend class SHRenderGraph; + friend class SHRenderGraphNode; + }; +} + diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp index 651ba88b..502e09b2 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp @@ -117,6 +117,9 @@ namespace SHADE usage |= vk::ImageUsageFlagBits::eInputAttachment; usage |= vk::ImageUsageFlagBits::eSampled; break; + case SH_ATT_DESC_TYPE_FLAGS::STORAGE: + usage |= vk::ImageUsageFlagBits::eStorage; + break; case SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT: { SHLOG_ERROR ("COLOR_PRESENT cannot be with other resource type flags. "); @@ -334,4 +337,9 @@ namespace SHADE return mipLevels; } + std::string SHRenderGraphResource::GetName(void) const noexcept + { + return resourceName; + } + } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h index 55f25864..832fa772 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h @@ -88,9 +88,11 @@ namespace SHADE Handle GetImageView (uint32_t index = NON_SWAPCHAIN_RESOURCE_INDEX) const noexcept; Handle GetImage (uint32_t index = NON_SWAPCHAIN_RESOURCE_INDEX) const noexcept; uint8_t GetMipLevels (void) const noexcept; + std::string GetName (void) const noexcept; friend class SHRenderGraphNode; friend class SHRenderGraph; friend class SHSubpass; + friend class SHRenderGraphNodeCompute; }; } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h index cb274697..f8123191 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h @@ -9,13 +9,14 @@ namespace SHADE class SHVkSwapchain; class SHGraphicsGlobalData; class SHVkDescriptorPool; + class SHRenderGraphResource; class SHRenderGraphStorage { //! Logical device for creation of vulkan objects Handle logicalDevice; - //! swapchain hdl + //! swapchain handle Handle swapchain; //! Resource manager for creation of objects @@ -24,13 +25,19 @@ namespace SHADE //! Descriptor pool for the descriptor sets to be created in the subpasses Handle descriptorPool; - //! For accessing resources anyone in the graph - std::unordered_map> const* ptrToResources; + //! For accessing resources anywhere in the graph + Handle>> graphResources; + + //SHRenderGraphStorage(void) noexcept; + //SHRenderGraphStorage(SHRenderGraphStorage&& rhs) noexcept; + //SHRenderGraphStorage& operator=(SHRenderGraphStorage&& rhs) noexcept; friend class SHRenderGraph; friend class SHRenderGraphNode; friend class SHSubpass; friend class SHRenderGraphResource; - friend class SHSubpassCompute; + friend class SHRenderGraphNodeCompute; }; + + } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp index e6472c52..5e3449c2 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp @@ -7,7 +7,6 @@ #include "Graphics/Shaders/SHVkShaderModule.h" #include "SHRenderGraphNode.h" #include "SHRenderGraphStorage.h" -#include "Graphics/RenderGraph/SHSubpassCompute.h" #include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" #include "Graphics/Swapchain/SHVkSwapchain.h" #include "Graphics/Images/SHVkSampler.h" @@ -40,7 +39,6 @@ namespace SHADE , depthReferences{} , inputReferences{} , graphStorage{ renderGraphStorage } - , subpassComputes{} , inputImageDescriptors {SHGraphicsConstants::NUM_FRAME_BUFFERS} { } @@ -66,8 +64,12 @@ namespace SHADE , resourceAttachmentMapping{ rhs.resourceAttachmentMapping } , descriptorSetLayout{ rhs.descriptorSetLayout } , exteriorDrawCalls{ std::move(rhs.exteriorDrawCalls) } - , graphStorage{ std::move(rhs.graphStorage) } - , subpassComputes{std::move (rhs.subpassComputes)} + , graphStorage{ rhs.graphStorage } + , inputNames{ std::move(rhs.inputNames) } + , inputImageDescriptors{ std::move(rhs.inputImageDescriptors) } + , inputDescriptorLayout{ rhs.inputDescriptorLayout } + , inputSamplers{ rhs.inputSamplers } + { } @@ -97,8 +99,11 @@ namespace SHADE resourceAttachmentMapping = rhs.resourceAttachmentMapping; descriptorSetLayout = rhs.descriptorSetLayout; exteriorDrawCalls = std::move(rhs.exteriorDrawCalls); - graphStorage = std::move(rhs.graphStorage); - subpassComputes = std::move(rhs.subpassComputes); + graphStorage = rhs.graphStorage; + inputNames = std::move(rhs.inputNames); + inputImageDescriptors = std::move(rhs.inputImageDescriptors); + inputDescriptorLayout = rhs.inputDescriptorLayout; + inputSamplers = rhs.inputSamplers; return *this; } @@ -117,7 +122,12 @@ namespace SHADE /***************************************************************************/ void SHSubpass::AddColorOutput(std::string resourceToReference) noexcept { - colorReferences.push_back({ resourceAttachmentMapping->at(graphStorage->ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eColorAttachmentOptimal }); + colorReferences.push_back({ resourceAttachmentMapping->at(graphStorage->graphResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eColorAttachmentOptimal }); + } + + void SHSubpass::AddGeneralColorOutput(std::string resourceToReference) noexcept + { + colorReferences.push_back({ resourceAttachmentMapping->at(graphStorage->graphResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eGeneral }); } /***************************************************************************/ @@ -154,7 +164,13 @@ namespace SHADE //Invalid return; } - depthReferences.push_back({ resourceAttachmentMapping->at(graphStorage->ptrToResources->at(resourceToReference).GetId().Raw), imageLayout }); + depthReferences.push_back({ resourceAttachmentMapping->at(graphStorage->graphResources->at(resourceToReference).GetId().Raw), imageLayout }); + } + + void SHSubpass::AddGeneralDepthOutput(std::string resourceToReference) noexcept + { + depthReferences.push_back({ resourceAttachmentMapping->at(graphStorage->graphResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eGeneral }); + } /***************************************************************************/ @@ -171,15 +187,14 @@ namespace SHADE /***************************************************************************/ void SHSubpass::AddInput(std::string resourceToReference) noexcept { - inputReferences.push_back({ resourceAttachmentMapping->at(graphStorage->ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eShaderReadOnlyOptimal }); + inputReferences.push_back({ resourceAttachmentMapping->at(graphStorage->graphResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eShaderReadOnlyOptimal }); inputNames.push_back(resourceToReference); } void SHSubpass::AddGeneralInput(std::string resourceToReference) noexcept { - inputReferences.push_back({ resourceAttachmentMapping->at(graphStorage->ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eGeneral }); - + inputReferences.push_back({ resourceAttachmentMapping->at(graphStorage->graphResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eGeneral }); } void SHSubpass::Execute(Handle& commandBuffer, Handle descPool, uint32_t frameIndex) noexcept @@ -196,11 +211,6 @@ namespace SHADE drawCall(commandBuffer); } - // if there are subpass computes, transition all to GENERAL layout first - for (auto& sbCompute : subpassComputes) - { - - } } void SHSubpass::HandleResize(void) noexcept @@ -213,29 +223,6 @@ namespace SHADE exteriorDrawCalls.push_back(newDrawCall); } - Handle SHSubpass::AddSubpassCompute(Handle computeShaderModule/*, std::initializer_list resources*/) noexcept - { - //// for the subpass compute to store indices to the resources, see member comments - //std::unordered_set attDescIndices{}; - //attDescIndices.reserve (resources.size()); - - //// Look for the required resources in the graph - //std::vector> subpassComputeResources{}; - //subpassComputeResources.reserve(resources.size()); - - //for (auto& resourceName : resources) - //{ - // auto resource = graphStorage->ptrToResources->at(resourceName); - // subpassComputeResources.push_back(resource); - // attDescIndices.emplace(resourceAttachmentMapping->at (resource.GetId().Raw)); - //} - - // Create the subpass compute with the resources - auto subpassCompute = graphStorage->resourceManager->Create(graphStorage, computeShaderModule/*, std::move(subpassComputeResources), std::move (attDescIndices)*/); - subpassComputes.push_back(subpassCompute); - - return subpassCompute; - } void SHSubpass::Init(ResourceManager& resourceManager) noexcept { @@ -245,48 +232,51 @@ namespace SHADE void SHSubpass::CreateInputDescriptors(void) noexcept { - //std::vector bindings{}; + if (inputNames.empty()) + return; - //for (auto& input : inputReferences) - //{ - // SHVkDescriptorSetLayout::Binding newBinding - // { - // .Type = (input.layout == vk::ImageLayout::eShaderReadOnlyOptimal) ? vk::DescriptorType::eInputAttachment : vk::DescriptorType::eStorageImage, - // .Stage = vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eCompute, - // .BindPoint = static_cast(bindings.size()), - // .DescriptorCount = 1, - // .flags = {}, - // }; + std::vector bindings{}; - // bindings.push_back(newBinding); - //} + for (auto& input : inputReferences) + { + SHVkDescriptorSetLayout::Binding newBinding + { + .Type = (input.layout == vk::ImageLayout::eShaderReadOnlyOptimal) ? vk::DescriptorType::eInputAttachment : vk::DescriptorType::eStorageImage, + .Stage = vk::ShaderStageFlagBits::eFragment, + .BindPoint = static_cast(bindings.size()), + .DescriptorCount = 1, + .flags = {}, + }; - //// We build a new descriptor set layout to store our images - //inputDescriptorLayout = graphStorage->logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, bindings); + bindings.push_back(newBinding); + } - //// we store a sampler if its an input attachment. if it is storage image, no need sampler, store an empty handle. - //for (uint32_t i = 0; i < bindings.size(); ++i) - //{ - // if (bindings[i].Type == vk::DescriptorType::eInputAttachment) - // { - // auto newSampler = graphStorage->logicalDevice->CreateSampler(SHVkSamplerParams - // { - // .minFilter = vk::Filter::eLinear, - // .magFilter = vk::Filter::eLinear, - // .addressMode = vk::SamplerAddressMode::eRepeat, - // .mipmapMode = vk::SamplerMipmapMode::eLinear, - // .minLod = -1000, - // .maxLod = 1000 - // } - // ); + // We build a new descriptor set layout to store our images + inputDescriptorLayout = graphStorage->logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, bindings); - // inputSamplers.push_back(newSampler); - // } - // else - // { - // inputSamplers.push_back({}); - // } - //} + // we store a sampler if its an input attachment. if it is storage image, no need sampler, store an empty handle. + for (uint32_t i = 0; i < bindings.size(); ++i) + { + if (bindings[i].Type == vk::DescriptorType::eInputAttachment) + { + auto newSampler = graphStorage->logicalDevice->CreateSampler(SHVkSamplerParams + { + .minFilter = vk::Filter::eLinear, + .magFilter = vk::Filter::eLinear, + .addressMode = vk::SamplerAddressMode::eRepeat, + .mipmapMode = vk::SamplerMipmapMode::eLinear, + .minLod = -1000, + .maxLod = 1000 + } + ); + + inputSamplers.push_back(newSampler); + } + else + { + inputSamplers.push_back({}); + } + } //// maybe do this in handle resize? //UpdateWriteDescriptors(); @@ -294,39 +284,43 @@ namespace SHADE void SHSubpass::UpdateWriteDescriptors(void) noexcept { - //auto const& bindings = inputDescriptorLayout->GetBindings(); + if (inputNames.empty()) + return; - //std::vector variableCounts{ static_cast(bindings.size()), 0 }; + auto const& bindings = inputDescriptorLayout->GetBindings(); - //uint32_t i = 0; + std::vector variableCounts{ static_cast(bindings.size()) }; + std::fill (variableCounts.begin(), variableCounts.end(), 0u); - //// For every frame's descriptor set - //for (auto& group : inputImageDescriptors) - //{ - // if (group) - // group.Free(); - // group = graphStorage->descriptorPool->Allocate({ inputDescriptorLayout }, variableCounts); + // For every frame's descriptor set + for (auto& group : inputImageDescriptors) + { + if (group) + group.Free(); - // for (auto& binding : bindings) - // { - // // get the resource - // auto resource = graphStorage->ptrToResources->at(inputNames[binding.BindPoint]); + group = graphStorage->descriptorPool->Allocate({ inputDescriptorLayout }, variableCounts); - // // If resource is swapchain image, get the correct image, if not just get 0. - // uint32_t viewIndex = (resource->resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) ? i : 0; + uint32_t i = 0; + for (auto& binding : bindings) + { + // get the resource + auto resource = graphStorage->graphResources->at(inputNames[binding.BindPoint]); - // // layout is GENERAL if image is meant to be used as storage image, if not use SHADER_READ_ONLY_OPTINAL - // vk::ImageLayout descriptorLayout = (binding.Type == vk::DescriptorType::eStorageImage) ? vk::ImageLayout::eGeneral : vk::ImageLayout::eShaderReadOnlyOptimal; + // If resource is swapchain image, get the correct image, if not just get 0. + uint32_t viewIndex = (resource->resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) ? i : 0; - // // Update descriptor sets - // auto args = std::make_tuple(resource->GetImageView(viewIndex), inputSamplers[i], descriptorLayout); - // group->ModifyWriteDescImage(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint, std::span{&args, 1}); - // group->UpdateDescriptorSetImages(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint); - // } + // layout is GENERAL if image is meant to be used as storage image, if not use SHADER_READ_ONLY_OPTINAL + vk::ImageLayout descriptorLayout = (binding.Type == vk::DescriptorType::eStorageImage) ? vk::ImageLayout::eGeneral : vk::ImageLayout::eShaderReadOnlyOptimal; - // ++i; - //} + // Update descriptor sets + auto args = std::make_tuple(resource->GetImageView(viewIndex), inputSamplers[i], descriptorLayout); + group->ModifyWriteDescImage(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint, std::span{&args, 1}); + group->UpdateDescriptorSetImages(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint); + } + + ++i; + } } //void SHSubpass::InitComputeBarriers(void) noexcept diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h index 48874a06..5a9dafb2 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h @@ -17,7 +17,6 @@ namespace SHADE class SHVkDescriptorSetGroup; class SHVkDescriptorPool; class SHRenderGraphStorage; - class SHSubpassCompute; class SHVkShaderModule; class SHVkSampler; @@ -64,9 +63,6 @@ namespace SHADE std::vector> inputSamplers; - //! Sometimes we want the subpass to do something to the images instead - //! of drawing objects on the image (i.e. compute). - std::vector> subpassComputes; ////! subpass compute image barriers. We do this because every frame has a different ////! swapchain image. If the resource we want to transition is not a swapchain image, @@ -96,7 +92,9 @@ namespace SHADE /*-----------------------------------------------------------------------*/ // Preparation functions void AddColorOutput(std::string resourceToReference) noexcept; + void AddGeneralColorOutput(std::string resourceToReference) noexcept; void AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE_FLAGS attachmentDescriptionType = SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL) noexcept; + void AddGeneralDepthOutput(std::string resourceToReference) noexcept; void AddInput(std::string resourceToReference) noexcept; void AddGeneralInput (std::string resourceToReference) noexcept; void AddExteriorDrawCalls(std::function&)> const& newDrawCall) noexcept; @@ -105,7 +103,6 @@ namespace SHADE void Execute(Handle& commandBuffer, Handle descPool, uint32_t frameIndex) noexcept; void HandleResize (void) noexcept; - Handle AddSubpassCompute(Handle computeShaderModule/*, std::initializer_list resources*/) noexcept; void Init(ResourceManager& resourceManager) noexcept; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp deleted file mode 100644 index 79242c7d..00000000 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include "SHpch.h" -#include "SHSubpassCompute.h" -#include "Graphics/Pipeline/SHVkPipeline.h" -#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" -#include "Graphics/Descriptors/SHVkDescriptorPool.h" -#include "Graphics/Devices/SHVkLogicalDevice.h" -#include "Graphics/Pipeline/SHVkPipelineLayout.h" -#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" -#include "SHRenderGraphStorage.h" -//#include "" - -namespace SHADE -{ - SHSubpassCompute::SHSubpassCompute(Handle graphStorage, Handle computeShaderModule/*, std::vector>&& subpassComputeResources, std::unordered_set&& attDescIndices*/) noexcept - : pipeline{} - { - SHPipelineLayoutParams pipelineLayoutParams - { - .shaderModules = {computeShaderModule}, - .globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts() - }; - - // Create descriptor set from - pipelineLayout = graphStorage->logicalDevice->CreatePipelineLayout (pipelineLayoutParams); - - // Create the compute pipeline - pipeline = graphStorage->logicalDevice->CreateComputePipeline(pipelineLayout); - - pipeline->ConstructPipeline(); - - // Get the descriptor set layouts required to allocate. We only want the ones for allocate because - // global descriptors are already bound in the main system. - //auto const& layouts = pipeline->GetPipelineLayout()->GetDescriptorSetLayoutsAllocate(); - - // Variable counts for the descriptor sets (all should be 1). - //std::vector variableCounts{ static_cast(layouts.size()) }; - //std::fill(variableCounts.begin(), variableCounts.end(), 0); - - //// Allocate descriptor sets to hold the images for reading (STORAGE_IMAGE) - //descSetGroup = graphStorage->descriptorPool->Allocate(layouts, variableCounts); - - //// save the resources - //resources = std::move (subpassComputeResources); - - //// we save this because when we configure the graph, we want to make sure final layouts - //// of attachment descriptions are set to GENERAL. See ConfigureAttachmentDescriptions in SHRenderGraph.cpp. - //attachmentDescriptionIndices = std::move (attDescIndices); - - //descSetGroup->ModifyWriteDescImage (SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, ) - } - - //SHSubpass -} diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.h b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.h deleted file mode 100644 index aae2a9b9..00000000 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpassCompute.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include "Resource/Handle.h" -#include -#include -#include - -namespace SHADE -{ - class SHVkPipeline; - class SHVkDescriptorSetGroup; - class SHVkDescriptorPool; - class SHVkLogicalDevice; - class SHVkPipelineLayout; - class SHRenderGraphStorage; - class SHRenderGraphResource; - class SHVkShaderModule; - - class SHSubpassCompute - { - private: - //! To run the dispatch command - Handle pipeline; - - //! Pipeline layout for the pipeline creation - Handle pipelineLayout; - - ////! Descriptor set group to hold the images for reading (STORAGE_IMAGE) - //Handle descSetGroup; - - ////! Required resources to be used in the descriptors - //std::vector resourcesRequired; - - ////! vector of resources needed by the subpass compute - //std::vector> resources; - - ////! we save this because when we configure the graph, we want to make sure final layouts - ////! of attachment descriptions are set to GENERAL. See ConfigureAttachmentDescriptions in SHRenderGraph.cpp. - //std::unordered_set attachmentDescriptionIndices{}; - - public: - SHSubpassCompute(Handle graphStorage, Handle computeShaderModule/*, std::vector>&& subpassComputeResources, std::unordered_set&& attDescIndices*/) noexcept; - - //void ExecuteSubpass (void) noexcept; - friend class SHRenderGraph; - friend class SHSubpass; - }; -} - diff --git a/SHADE_Engine/src/Graphics/SHVkUtil.cpp b/SHADE_Engine/src/Graphics/SHVkUtil.cpp index c8c563a1..cf486a7a 100644 --- a/SHADE_Engine/src/Graphics/SHVkUtil.cpp +++ b/SHADE_Engine/src/Graphics/SHVkUtil.cpp @@ -55,6 +55,21 @@ namespace SHADE return 0; } + vk::PipelineBindPoint SHVkUtil::GetPipelineBindPointFromType(SH_PIPELINE_TYPE pipelineType) noexcept + { + switch (pipelineType) + { + case SH_PIPELINE_TYPE::GRAPHICS: + return vk::PipelineBindPoint::eGraphics; + case SH_PIPELINE_TYPE::COMPUTE: + return vk::PipelineBindPoint::eCompute; + case SH_PIPELINE_TYPE::RAY_TRACING: + return vk::PipelineBindPoint::eRayTracingKHR; + default: + return vk::PipelineBindPoint::eGraphics; + } + } + void SHVkUtil::EnsureBufferAndCopyData(Handle device, Handle cmdBuffer, Handle& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage) { if (bufferHandle) diff --git a/SHADE_Engine/src/Graphics/SHVkUtil.h b/SHADE_Engine/src/Graphics/SHVkUtil.h index ca3b6f83..ab11b537 100644 --- a/SHADE_Engine/src/Graphics/SHVkUtil.h +++ b/SHADE_Engine/src/Graphics/SHVkUtil.h @@ -4,6 +4,7 @@ #include "SHVulkanIncludes.h" #include "Resource/Handle.h" +#include "Graphics/Pipeline/SHPipelineType.h" namespace SHADE { @@ -20,11 +21,12 @@ namespace SHADE class SHVkUtil { public: - static bool IsDepthOnlyFormat (vk::Format format) noexcept; - static bool IsDepthStencilAttachment (vk::Format format) noexcept; - static bool IsBlendCompatible (vk::Format format) noexcept; - static uint32_t GetBytesPerPixelFromFormat (vk::Format format) noexcept; - + static bool IsDepthOnlyFormat (vk::Format format) noexcept; + static bool IsDepthStencilAttachment (vk::Format format) noexcept; + static bool IsBlendCompatible (vk::Format format) noexcept; + static uint32_t GetBytesPerPixelFromFormat (vk::Format format) noexcept; + static vk::PipelineBindPoint GetPipelineBindPointFromType (SH_PIPELINE_TYPE pipelineType) noexcept; + /***********************************************************************************/ /*! diff --git a/TempShaderFolder/GreyscaleCs.glsl b/TempShaderFolder/GreyscaleCs.glsl deleted file mode 100644 index 3167a57c..00000000 --- a/TempShaderFolder/GreyscaleCs.glsl +++ /dev/null @@ -1,38 +0,0 @@ -/* Start Header *****************************************************************/ - -/*! \file (e.g. kirsch.comp) - - \author William Zheng, william.zheng, 60001906. Brandon Mak, brandon.hao 390003920. - - \par william.zheng\@digipen.edu. brandon.hao\@digipen.edu. - - \date Sept 20, 2022 - - \brief Copyright (C) 20xx 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. */ - - /* End Header *******************************************************************/ - -#version 450 - -layout(local_size_x = 16, local_size_y = 16) in; -layout(set = 4, binding = 0, rgba8) uniform image2D targetImage; - - -void main() -{ - // load the image - vec4 color = imageLoad (targetImage, ivec2 (gl_GlobalInvocationID)); - - // get the average - float average = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b; - - // store result into result image - imageStore(targetImage, ivec2(gl_GlobalInvocationID), vec4(average, average, average, 1.0f)); - -} - - - - diff --git a/TempShaderFolder/GreyscaleCs.spv b/TempShaderFolder/GreyscaleCs.spv deleted file mode 100644 index 5b36e00317061a12d75127def8a67c940e8969c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1400 zcmZ9K+fEZv6o$97g$e>9Ld9b%o)E04oRoku(M*~&0pb-`lVLh(CK*~%#wI3S=!H+< zjql+b_yoRy@8OM!|2NDsqkFQl*8i{5UTaTjWO2;7b8g&Cx@~uMX55Gv=O)}}roHyt zcJnmtG}qQwiI{SwERdLK#Z;urlH(xm;h2$J6c2Z1gX!XwSyFZ9z6+Gq)oc6S-k#Tf zfbRiXw{r!ROT@>?i$!bVc6<=`~7t}_mcimkhFTkei)>2zt?)5<&@oZ>0lTQi1$>J8n-3%GTe~O0W<4_ zggo$z94|=EYHH?gWE*gqJuiDyTwPLAydEOM)UOLyrQwhTO*Ae|yjJ(mp|0i7pF`}n zSTOhI%n46P*8w{8oR)^;Md@kp1W!Jgx#&s$taLrc;VzioHzgeNv*W|s=1cQ03e(^G4`hG+`DMraOTzRs|E6r`KK{*rF2o!w>dsue z3mii24gC$aL&0p8Ut;*L*#Yms|HK?%X5x*(JHqUGQo^3W^tdEpZy$u&(Ok|Qs4Dxa z<(!l=?n=%v>%QXHCI1ew_>RQU^Qwe?_;z($?gsZte(rWl0>@stkNsotpA`dcNO*_3 z#PaUQCXbz1-d)-7mUmA!?*soSuXSHG_3&A(hq9@)B(Yk{vf-`PifrBz-fBIPO+9?f z#-8D*!JeCv;+`K17x%m>3}-uiA{&ll+*8?b#XUb0CKjLFcTG0^4X^))H*&nMSK(c@ WB;*i>kN+^#y}2{>@&8uWEy*9dZd@?{ diff --git a/TempShaderFolder/KirschCs.glsl b/TempShaderFolder/KirschCs.glsl new file mode 100644 index 00000000..3dec174d --- /dev/null +++ b/TempShaderFolder/KirschCs.glsl @@ -0,0 +1,167 @@ +//#version 450 +// +//layout(local_size_x = 16, local_size_y = 16) in; +//layout(set = 4, binding = 0, rgba8) uniform image2D targetImage; +// +// +//void main() +//{ +// ivec2 imageSize = imageSize (targetImage); +// +// if (gl_GlobalInvocationID.x >= imageSize.x && gl_GlobalInvocationID.y >= imageSize.y) +// return; +// +// // load the image +// vec4 color = imageLoad (targetImage, ivec2 (gl_GlobalInvocationID)); +// +// // get the average +// float average = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b; +// +// // store result into result image +// imageStore(targetImage, ivec2(gl_GlobalInvocationID), vec4(average, average, average, 1.0f)); +// +//} +// +// +// +// + +/* Start Header *****************************************************************/ + +/*! \file (e.g. kirsch.comp) + + \author William Zheng, william.zheng, 60001906. Brandon Mak, brandon.hao 390003920. + + \par william.zheng\@digipen.edu. brandon.hao\@digipen.edu. + + \date Sept 20, 2022 + + \brief Copyright (C) 20xx 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. */ + + /* End Header *******************************************************************/ + +#version 450 + +#define MASK_WIDTH 3 +#define HALF_M_WIDTH MASK_WIDTH / 2 +#define SHM_WIDTH 18 +#define NUM_MASKS 8 + +layout(local_size_x = 16, local_size_y = 16) in; +layout(set = 4, binding = 0, rgba8) uniform image2D inputImage; +layout(set = 4, binding = 1, rgba8) uniform image2D resultImage; + +const float kirsch[8][3][3] = { + { + {5, 5, 5}, + {-3, 0, -3}, /*rotation 1 */ + {-3, -3, -3} + }, + { + {5, 5, -3}, + {5, 0, -3}, /*rotation 2 */ + {-3, -3, -3} + }, + { + {5, -3, -3}, + {5, 0, -3}, /*rotation 3 */ + {5, -3, -3} + }, + { + {-3, -3, -3}, + {5, 0, -3}, /*rotation 4 */ + {5, 5, -3} + }, + { + {-3, -3, -3}, + {-3, 0, -3}, /*rotation 5 */ + {5, 5, 5} + }, + { + {-3, -3, -3}, + {-3, 0, 5}, /*rotation 6 */ + {-3, 5, 5} + }, + { + {-3, -3, 5}, + {-3, 0, 5}, /*rotation 7 */ + {-3, -3, 5} + }, + { + {-3, 5, 5}, + {-3, 0, 5}, /*rotation 8 */ + {-3, -3, -3} + } +}; + +vec3 GetImageValues(ivec2 uv, ivec2 inputImageSize) +{ + if (uv.x >= 0 && uv.y >= 0 && uv.x < inputImageSize.x && uv.y < inputImageSize.y) + { + return imageLoad(inputImage, uv).rgb; + } + else + return vec3(0.0f); +} + +//two extra row/col +shared vec3 sData[16 + 2][16 + 2]; + +void main() +{ + // convenient variables + ivec3 globalThread = ivec3(gl_GlobalInvocationID); + ivec3 localThread = ivec3(gl_LocalInvocationID); + ivec2 inputImageSize = imageSize(inputImage); + + // load shared memory + ivec2 start = ivec2(gl_WorkGroupID) * ivec2(gl_WorkGroupSize) - ivec2(HALF_M_WIDTH); + for (int i = localThread.x; i < SHM_WIDTH; i += int(gl_WorkGroupSize.x)) + { + for (int j = localThread.y; j < SHM_WIDTH; j += int(gl_WorkGroupSize.y)) + { + // get from source image (either real values or 0) + vec3 sourceValue = GetImageValues(start + ivec2(i, j), inputImageSize); + sData[i][j] = sourceValue; + } + } + + // wait for shared memory to finish loading + barrier(); + + // max (between all 8 masks) + vec3 maxSum = vec3(0.0f); + + // loop through all masks + for (int i = 0; i < NUM_MASKS; ++i) + { + vec3 sum = vec3(0.0f); + + // start of shared memory + ivec2 shmStart = ivec2(localThread + HALF_M_WIDTH); + for (int j = -1; j < HALF_M_WIDTH + 1; ++j) + { + for (int k = -1; k < HALF_M_WIDTH + 1; ++k) + { + // Perform convolution using shared_memory + sum += sData[shmStart.x + j][shmStart.y + k] * kirsch[i][j + 1][k + 1]; + } + } + + // Get highest sum + maxSum = max(sum, maxSum); + } + + // average the max sum + maxSum = min(max(maxSum / 8, 0), 1.0f); + + // store result into result image + imageStore(resultImage, ivec2(gl_GlobalInvocationID.xy), vec4(maxSum, 1.0f)); + +} + + + + diff --git a/TempShaderFolder/KirschCs.spv b/TempShaderFolder/KirschCs.spv new file mode 100644 index 0000000000000000000000000000000000000000..1ae5408b12013ad40918e0477191c76630795dbb GIT binary patch literal 5900 zcmZXW37l1R702(ajDQHJ7)Ui}izShWqBRr@VNY^$urZgchR4hUp1fI{nKz+X;8LlW zErzX{Ek?W9YWrkm`(i7$+MX>InQNhazxVx5pWAf#{5a?Q&iY^Oebdr>^(-5o7+iMT@y8fBCu>pUzJs!ktPQ;t43(?H^6S9K zpcl-ghQ4{ZuHDFMp++)jJ;m5?>aNHfR1BBw`sS_&EM*(vz{f3DW-RQU0U^4J8@IQN@6XO4_*D~*lR zM{VjF&oMubX~{Mt&&~C=>^$W7NPTReu`|TBW-o#pEsvFl@|f0a`!supIqS+3<>cRm z94c?`tCL`_E3u>3Zeww{?rYSy4)vvR^Vnf!(M{!qwSv00*jOFK5HMIZ1+ohQL^n(tfy_grsUs`G=3pC znA_|9UBa4u8`KY_XFIYJm~$95FImp%@5Jsv%83PJ9+2~m*qP|s)?31=?ImZ9ID{^~ zKlYi2>;yhXCwqRw%=;XS9=-KD*Mj7ac-QTm3+cKXX>aY~jqQA{+dgZM&MvQiEzIp zB!j;t+4_XMJ--O7ZJsd^|0VS3HC5ohocLmW>)Z;=(O<0d6>RHFB}Ct^V(T+r8T{AK z&6l@c@Lx~7b2@L#`3>|b;5_yT{+sAii3{F2zXhyso-q;sZS<*xV*GdD^ck;=dA^Ho zzIWpuzrUSfoA2*u*v4Nw&E8Y6 zJ(Io3ej4jvi+&PV2QI{3jeKU}p3ZK$H`)=q9{pqxvCl%6Gq!}(Hg-9(2dn^Fv7PVP zi8Izc)sDIw(ESca-P6$JPUEE7k{>x>9>&x}VcX$JF_Bb6FtMAgpotb#Q;}<9H zdFb+I1LyHf<+|~^htCJD$M3TQTqyz!p7_5<9d7b3k=%6p03h%5si{hN^bl~HQ| z-5NL1Z!WR|q0CV&ii86zl*y zfw9(JrR{(qOLas{smBqltm8N5^`Hbcuv^-10B058y5-*pjMX3ChBqZ1@n7!EiEBc} zU3&|wGKHS(Wa?+mLSuKKkE*)US+vcqh6wVjtdxE_VZPAGEIr z)-qS!zI%|-_ua{-wC{V7?*l&eeLvD%W%T_3x;3Kj2hruCul9R@waitI@5qhl?!kNz z^*)3yANEb?t}E`{htZ9Zk2)Vgx6UFEc^^fW5Bp>2&KY$+j&6*6yl0<4-vR8Q-(26v zn}NQl^*wa&T-e`7FV6S_Y&q{w#QYGw*#Ae^a>jTLdy%(+ZoXo-BYy(q>}5UUt#ttM zr$GNz+)3yA8Mqn98zc8~up3;IVt$c0W9_F;&U5vQJsV}r`%CoVymw&B#k~6D%#VBH z8Ebo2t*4B7zd|qW(XX-PqMklE^S$@xdskyUzd?8Auz!p0cVssE<$8Yyn!r)OSpBZk z7=70DTVh>h%=LS8&ob`CAJFAuE`4(5$M?x^NzCy_bbI*SaE?ELI}5lh?f;+QjMX2p ze?jjmAlC9%xLAvM#zoHG(C;cBa{dly&SQc3#>M*eIq!1hKfu0ZuSNb7tOLF52?%MqhdN1z>az4R5fG%g9;2um|Gjao!S0euf%r{=YYaF1j z^V(PceyW@Z{F~ano&$VlffG3E4&>~DejvK%eGoFf6^Epl`N+5fhoZ~hNZq-}!+_iZ za36ISB7OXh>U#u`v$lHFJ{;Zti$K&~j4mIwABiq!ZSPdnQQpH|*#A+$KF)2tJ)ENx z>Ej&6JQ{QY=TMJ1mY_RFag9e{%SX(S= Date: Sun, 23 Oct 2022 16:04:58 +0800 Subject: [PATCH 17/50] Camera Director integrated Still has bug --- .../src/Application/SBApplication.cpp | 1 + SHADE_Application/src/Scenes/SBTestScene.cpp | 5 + SHADE_Engine/src/Camera/SHCameraComponent.cpp | 62 ++++- SHADE_Engine/src/Camera/SHCameraComponent.h | 2 + SHADE_Engine/src/Camera/SHCameraDirector.cpp | 65 +++++ SHADE_Engine/src/Camera/SHCameraDirector.h | 43 +++ SHADE_Engine/src/Camera/SHCameraSystem.cpp | 252 +++++++++++++----- SHADE_Engine/src/Camera/SHCameraSystem.h | 23 +- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 32 ++- .../MiddleEnd/Interface/SHRenderer.cpp | 27 +- .../Graphics/MiddleEnd/Interface/SHRenderer.h | 7 +- 11 files changed, 421 insertions(+), 98 deletions(-) create mode 100644 SHADE_Engine/src/Camera/SHCameraDirector.cpp create mode 100644 SHADE_Engine/src/Camera/SHCameraDirector.h diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index 8733e7b9..9bfd82de 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -93,6 +93,7 @@ namespace Sandbox SHSystemManager::RegisterRoutine(); SHSystemManager::RegisterRoutine(); + SHSystemManager::RegisterRoutine(); #ifdef SHEDITOR SHSystemManager::RegisterRoutine(); diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index f1d656ee..6b3fee1d 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -14,6 +14,7 @@ #include "Physics/Components/SHColliderComponent.h" #include "Assets/SHAssetManager.h" +#include "Camera/SHCameraComponent.h" using namespace SHADE; @@ -166,6 +167,10 @@ namespace Sandbox transformShowcase.SetWorldPosition({ 3.0f, -1.0f, -1.0f }); transformShowcase.SetLocalScale({ 5.0f, 5.0f, 5.0f }); scriptEngine->AddScript(raccoonShowcase, "RaccoonShowcase"); + + SHComponentManager::AddComponent(0); + SHComponentManager::RemoveComponent (0); + SHComponentManager::RemoveComponent (0); } void SBTestScene::Update(float dt) diff --git a/SHADE_Engine/src/Camera/SHCameraComponent.cpp b/SHADE_Engine/src/Camera/SHCameraComponent.cpp index 650ed3c5..5d49c887 100644 --- a/SHADE_Engine/src/Camera/SHCameraComponent.cpp +++ b/SHADE_Engine/src/Camera/SHCameraComponent.cpp @@ -1,13 +1,15 @@ #include "SHpch.h" #include "SHCameraComponent.h" #include "ECS_Base/Managers/SHComponentManager.h" - +#include "SHCameraSystem.h" +#include "ECS_Base/Managers/SHSystemManager.h" +#include "Math/Transform/SHTransformComponent.h" namespace SHADE { SHCameraComponent::SHCameraComponent() :yaw(0.0f), pitch(0.0f), roll(0.0f) - , width(1920.0f), height(1080.0f), zNear(0.01f), zFar(10000.0f), fov(90.0f), movementSpeed(1.0f), turnSpeed(1.0f) + , width(1920.0f), height(1080.0f), zNear(0.01f), zFar(10000.0f), fov(90.0f), movementSpeed(1.0f), turnSpeed(0.5f) , perspProj(true), dirtyView(true), dirtyProj(true) , viewMatrix(), projMatrix() , position() @@ -22,33 +24,69 @@ namespace SHADE void SHCameraComponent::SetYaw(float yaw) noexcept { this->yaw = yaw; + if (SHComponentManager::HasComponent(GetEID())) + { + auto transform = SHComponentManager::GetComponent(GetEID()); + SHVec3 rotation = transform->GetWorldRotation(); + transform->SetWorldRotation(SHVec3{rotation.x,yaw, rotation.z}); + } dirtyView = true; } void SHCameraComponent::SetPitch(float pitch) noexcept { this->pitch = pitch; + if (SHComponentManager::HasComponent(GetEID())) + { + auto transform = SHComponentManager::GetComponent(GetEID()); + SHVec3 rotation = transform->GetWorldRotation(); + transform->SetWorldRotation(SHVec3{ pitch,rotation.y, rotation.z }); + } dirtyView = true; } void SHCameraComponent::SetRoll(float roll) noexcept { this->roll = roll; + if (SHComponentManager::HasComponent(GetEID())) + { + auto transform = SHComponentManager::GetComponent(GetEID()); + SHVec3 rotation = transform->GetWorldRotation(); + transform->SetWorldRotation(SHVec3{ rotation.x,rotation.y, roll}); + } dirtyView = true; } void SHCameraComponent::SetPositionX(float x) noexcept { position.x = x; + if (SHComponentManager::HasComponent(GetEID())) + { + auto transform = SHComponentManager::GetComponent(GetEID()); + SHVec3 position = transform->GetWorldPosition(); + transform->SetWorldRotation(SHVec3{ x,position.y, position.z}); + } dirtyView = true; } void SHCameraComponent::SetPositionY(float y) noexcept { position.y = y; + if (SHComponentManager::HasComponent(GetEID())) + { + auto transform = SHComponentManager::GetComponent(GetEID()); + SHVec3 position = transform->GetWorldPosition(); + transform->SetWorldRotation(SHVec3{ position.x,y, position.z }); + } dirtyView = true; } void SHCameraComponent::SetPositionZ(float z) noexcept { position.z = z; + if (SHComponentManager::HasComponent(GetEID())) + { + auto transform = SHComponentManager::GetComponent(GetEID()); + SHVec3 position = transform->GetWorldPosition(); + transform->SetWorldRotation(SHVec3{ position.x,position.y, z }); + } dirtyView = true; } void SHCameraComponent::SetPosition(float x,float y, float z) noexcept @@ -56,11 +94,23 @@ namespace SHADE position.x = x; position.y = y; position.z = z; + if (SHComponentManager::HasComponent(GetEID())) + { + auto transform = SHComponentManager::GetComponent(GetEID()); + SHVec3 position = transform->GetWorldPosition(); + transform->SetWorldRotation(SHVec3{ x,y, z }); + } dirtyView = true; } void SHCameraComponent::SetPosition(SHVec3& pos) noexcept { this->position = pos; + if (SHComponentManager::HasComponent(GetEID())) + { + auto transform = SHComponentManager::GetComponent(GetEID()); + SHVec3 position = transform->GetWorldPosition(); + transform->SetWorldRotation(pos); + } dirtyView = true; } @@ -128,4 +178,12 @@ namespace SHADE return projMatrix; } + void SHCameraComponent::SetMainCamera(size_t directorCameraIndex) noexcept + { + auto system = SHSystemManager::GetSystem(); + system->GetDirector(directorCameraIndex)->SetMainCamera(*this); + } + + + } diff --git a/SHADE_Engine/src/Camera/SHCameraComponent.h b/SHADE_Engine/src/Camera/SHCameraComponent.h index c86fa160..1149b1e1 100644 --- a/SHADE_Engine/src/Camera/SHCameraComponent.h +++ b/SHADE_Engine/src/Camera/SHCameraComponent.h @@ -70,6 +70,8 @@ namespace SHADE const SHMatrix& GetViewMatrix() const noexcept; const SHMatrix& GetProjMatrix() const noexcept; + void SetMainCamera(size_t cameraDirectorIndex = 0) noexcept; + float movementSpeed; SHVec3 turnSpeed; diff --git a/SHADE_Engine/src/Camera/SHCameraDirector.cpp b/SHADE_Engine/src/Camera/SHCameraDirector.cpp new file mode 100644 index 00000000..559897c0 --- /dev/null +++ b/SHADE_Engine/src/Camera/SHCameraDirector.cpp @@ -0,0 +1,65 @@ +#include "SHpch.h" +#include "SHCameraDirector.h" +#include "SHCameraComponent.h" +#include "ECS_Base/Managers/SHComponentManager.h" +#include "ECS_Base/SHECSMacros.h" +#include "ECS_Base/Managers/SHEntityManager.h" +#include "Tools/SHLog.h" + +namespace SHADE +{ + SHCameraDirector::SHCameraDirector() + :mainCameraEID(MAX_EID), transitionCameraEID(MAX_EID) + { + } + + + SHMatrix SHCameraDirector::GetViewMatrix() const noexcept + { + return viewMatrix; + } + SHMatrix SHCameraDirector::GetProjMatrix() const noexcept + { + return projMatrix; + } + SHMatrix SHCameraDirector::GetVPMatrix() const noexcept + { + return projMatrix * viewMatrix; + } + + void SHCameraDirector::UpdateMatrix() noexcept + { + if (mainCameraEID == MAX_EID) + { + auto& dense = SHComponentManager::GetDense(); + if (dense.size() == 0) + { + return; + } + mainCameraEID = dense[0].GetEID(); + } + SHCameraComponent* camComponent = SHComponentManager::GetComponent_s(mainCameraEID); + if (!camComponent) + { + SHLOG_WARNING("Camera Director warning: Entity does not have a camera"); + } + else + { + viewMatrix = camComponent->GetViewMatrix(); + projMatrix = camComponent->GetProjMatrix(); + } + } + + void SHCameraDirector::SetMainCamera(SHCameraComponent& camera) noexcept + { + if (SHEntityManager::IsValidEID(camera.GetEID()) == false) + { + SHLOG_WARNING("Camera Director Warning: Attempting to set an invalid entity as main camera.") + return; + } + mainCameraEID = camera.GetEID(); + } + + + +} diff --git a/SHADE_Engine/src/Camera/SHCameraDirector.h b/SHADE_Engine/src/Camera/SHCameraDirector.h new file mode 100644 index 00000000..b1311147 --- /dev/null +++ b/SHADE_Engine/src/Camera/SHCameraDirector.h @@ -0,0 +1,43 @@ +#pragma once + +#include "SH_API.h" +#include "ECS_Base/Entity/SHEntity.h" +#include "Math/SHMatrix.h" +#include "Resource/Handle.h" + + +namespace SHADE +{ + class SHCameraComponent; + + + + class SH_API SHCameraDirector + { + public: + SHCameraDirector(); + ~SHCameraDirector() = default; + + + EntityID mainCameraEID; + EntityID transitionCameraEID; + + SHMatrix GetViewMatrix() const noexcept; + SHMatrix GetProjMatrix() const noexcept; + SHMatrix GetVPMatrix() const noexcept; + void UpdateMatrix() noexcept; + void SetMainCamera(SHCameraComponent& cam) noexcept; + + + private: + + + protected: + SHMatrix viewMatrix; + SHMatrix projMatrix; + + }; + + typedef Handle DirectorHandle; + +} diff --git a/SHADE_Engine/src/Camera/SHCameraSystem.cpp b/SHADE_Engine/src/Camera/SHCameraSystem.cpp index c9822b82..40b63294 100644 --- a/SHADE_Engine/src/Camera/SHCameraSystem.cpp +++ b/SHADE_Engine/src/Camera/SHCameraSystem.cpp @@ -2,67 +2,115 @@ #include "SHCameraSystem.h" #include "Math/SHMathHelpers.h" #include "Input/SHInputManager.h" - +#include "Math/Vector/SHVec2.h" +#include "ECS_Base/Managers/SHComponentManager.h" +#include "Math/Transform/SHTransformComponent.h" namespace SHADE { + void SHCameraSystem::UpdateEditorCamera(double dt) noexcept + { + + auto& camera = editorCamera; + SHVec3 view, right, UP; + GetCameraAxis(camera, view, right, UP); + if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::A)) + { + camera.position -= right * dt * camera.movementSpeed; + camera.dirtyView = true; + } + if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::D)) + { + camera.position += right * dt * camera.movementSpeed; + camera.dirtyView = true; + } + if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::W)) + { + camera.position += view * dt * camera.movementSpeed; + camera.dirtyView = true; + } + if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::S)) + { + camera.position -= view * dt * camera.movementSpeed; + camera.dirtyView = true; + } + if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::Q)) + { + camera.position += UP * dt * camera.movementSpeed; + camera.dirtyView = true; + } + if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::E)) + { + camera.position -= UP * dt * camera.movementSpeed; + camera.dirtyView = true; + } + if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::RMB)) + { + double mouseX, mouseY; + SHInputManager::GetMouseVelocity(&mouseX, &mouseY); + + //std::cout << camera.yaw << std::endl; + + camera.pitch -= mouseY * dt * camera.turnSpeed.x; + camera.yaw -= mouseX * dt * camera.turnSpeed.y; + camera.dirtyView = true; + } + + UpdateCameraComponent(editorCamera); + } void SHCameraSystem::EditorCameraUpdate::Execute(double dt) noexcept { SHCameraSystem* system = static_cast(GetSystem()); auto& camera = system->editorCamera; - SHVec3 target{ 0.0f,0.0f,-1.0f }; - SHVec3 up = { 0.0f,1.0f,0.0f }; - - - SHVec3::RotateY(target, SHMath::DegreesToRadians(camera.yaw)); - SHVec3::RotateX(target, SHMath::DegreesToRadians(camera.pitch)); - target += camera.position; - ////SHVec3::RotateZ(target, SHMath::DegreesToRadians(camera.roll)); - - //target = SHVec3::Normalise(target); - - SHVec3::RotateZ(up, camera.roll); - up = SHVec3::Normalise(up); - - - SHVec3 view = target - camera.position; view = SHVec3::Normalise(view); - SHVec3 right = SHVec3::Cross(view, up); right = SHVec3::Normalise(right); - const SHVec3 UP = SHVec3::Cross(view, right); - + SHVec3 view, right, UP; + system->GetCameraAxis(camera, view, right, UP); if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::A)) { - system->editorCamera.position -= right * dt * camera.movementSpeed; - system->editorCamera.dirtyView = true; + //std::cout << "Camera movement: "<editorCamera.position += right * dt * camera.movementSpeed; - system->editorCamera.dirtyView = true; + camera.position += right * dt * camera.movementSpeed; + camera.dirtyView = true; } if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::W)) { - system->editorCamera.position += view * dt * camera.movementSpeed; - system->editorCamera.dirtyView = true; + camera.position += view * dt * camera.movementSpeed; + camera.dirtyView = true; } if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::S)) { - system->editorCamera.position -= view * dt * camera.movementSpeed; - system->editorCamera.dirtyView = true; + camera.position -= view * dt * camera.movementSpeed; + camera.dirtyView = true; } if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::Q)) { - system->editorCamera.position += UP * dt * camera.movementSpeed; - system->editorCamera.dirtyView = true; + camera.position += UP * dt * camera.movementSpeed; + camera.dirtyView = true; } if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::E)) { - system->editorCamera.position -= UP * dt * camera.movementSpeed; - system->editorCamera.dirtyView = true; + camera.position -= UP * dt * camera.movementSpeed; + camera.dirtyView = true; + } + if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::RMB)) + { + double mouseX, mouseY; + SHInputManager::GetMouseVelocity(&mouseX,&mouseY); + + //std::cout << camera.yaw << std::endl; + + camera.pitch -= mouseY * dt * camera.turnSpeed.x; + camera.yaw -= mouseX * dt * camera.turnSpeed.y; + camera.dirtyView = true; } + //std::cout << "Camera position: " << camera.position.x << " " << camera.position.y << std::endl; system->UpdateCameraComponent(system->editorCamera); } @@ -88,26 +136,26 @@ namespace SHADE void SHCameraSystem::UpdateCameraComponent(SHCameraComponent& camera) noexcept { + if (SHComponentManager::HasComponent(camera.GetEID()) == true && &camera != &editorCamera) + { + auto transform = SHComponentManager::GetComponent(camera.GetEID()); + SHVec3 rotation = transform->GetWorldRotation(); + camera.pitch = SHMath::RadiansToDegrees(rotation.x); + camera.yaw = SHMath::RadiansToDegrees(rotation.y); + camera.roll = SHMath::RadiansToDegrees(rotation.z); + camera.position = transform->GetWorldPosition(); + } + + if (camera.dirtyView) { - SHVec3 target{ 0.0f,0.0f,-1.0f }; - SHVec3 up = { 0.0f,1.0f,0.0f }; + + SHVec3 view, right, UP; + + //ClampCameraRotation(camera); - SHVec3::RotateY(target, SHMath::DegreesToRadians(camera.yaw)); - SHVec3::RotateX(target, SHMath::DegreesToRadians(camera.pitch)); - target += camera.position; - ////SHVec3::RotateZ(target, SHMath::DegreesToRadians(camera.roll)); - - //target = SHVec3::Normalise(target); - - SHVec3::RotateZ(up, camera.roll); - up = SHVec3::Normalise(up); - - - SHVec3 view = target - camera.position; view = SHVec3::Normalise(view); - SHVec3 right = SHVec3::Cross(view, up); right = SHVec3::Normalise(right); - const SHVec3 UP = SHVec3::Cross(view, right); + GetCameraAxis(camera, view, right, UP); camera.viewMatrix = SHMatrix::Identity; camera.viewMatrix(0, 0) = right[0]; @@ -143,38 +191,100 @@ namespace SHADE camera.projMatrix(3, 2) = 1.0f; camera.projMatrix(2, 3) = -(camera.zFar * camera.zNear) / (camera.zFar - camera.zNear); - //const float fov_rad = SHMath::DegreesToRadians(camera.fov); - //const float focal_length = 1.0f / tan(fov_rad * 0.5f); - - //camera.projMatrix(0,0) = focal_length / camera.GetAspectRatio(); - //camera.projMatrix(1,1) = -focal_length; - //camera.projMatrix(2,2) = camera.zNear / (camera.zFar - camera.zNear); - //camera.projMatrix(2,3) = camera.zFar * (camera.zNear / (camera.zFar - camera.zNear)); - //camera.projMatrix(3,2) = -1.0f; - //camera.projMatrix(3,3) = 0.0f; - - //camera.projMatrix = SHMatrix::Inverse(camera.projMatrix); - + camera.dirtyProj = false; } else { - const float R = camera.width * 0.5f; - const float L = -R; - const float T = camera.height * 0.5f; - const float B = -T; + //const float R = camera.width * 0.5f; + //const float L = -R; + //const float T = camera.height * 0.5f; + //const float B = -T; - camera.projMatrix = SHMatrix::Identity; - camera.projMatrix(0, 0) = 2.0f / (R - L); - camera.projMatrix(1, 1) = 2.0f / (B - T); - camera.projMatrix(2, 2) = 1.0f / (camera.zFar - camera.zNear); - camera.projMatrix(3, 0) = -(R + L) / (R - L); - camera.projMatrix(3, 1) = -(B + T) / (B - T); - camera.projMatrix(3, 2) = -camera.zNear / (camera.zFar - camera.zNear); + //camera.projMatrix = SHMatrix::Identity; + //camera.projMatrix(0, 0) = 2.0f / (R - L); + //camera.projMatrix(1, 1) = 2.0f / (B - T); + //camera.projMatrix(2, 2) = 1.0f / (camera.zFar - camera.zNear); + //camera.projMatrix(3, 0) = -(R + L) / (R - L); + //camera.projMatrix(3, 1) = -(B + T) / (B - T); + //camera.projMatrix(3, 2) = -camera.zNear / (camera.zFar - camera.zNear); camera.dirtyProj = false; } } } + void SHCameraSystem::GetCameraAxis(SHCameraComponent const& camera, SHVec3& forward, SHVec3& right, SHVec3& upVec) const noexcept + { + SHVec3 target{ 0.0f,0.0f,-1.0f }; + SHVec3 up = { 0.0f,1.0f,0.0f }; + + + target = SHVec3::RotateY(target, SHMath::DegreesToRadians(camera.yaw)); + target =SHVec3::RotateX(target, SHMath::DegreesToRadians(camera.pitch)); + target += camera.position; + ////SHVec3::RotateZ(target, SHMath::DegreesToRadians(camera.roll)); + + //target = SHVec3::Normalise(target); + + SHVec3::RotateZ(up, camera.roll); + up = SHVec3::Normalise(up); + + + forward = target - camera.position; forward = SHVec3::Normalise(forward); + right = SHVec3::Cross(forward, up); right = SHVec3::Normalise(right); + upVec = SHVec3::Cross(forward, right); + } + + void SHCameraSystem::CameraSystemUpdate::Execute(double dt) noexcept + { + SHCameraSystem* system = static_cast(GetSystem()); + auto& dense = SHComponentManager::GetDense(); + for (auto& cam : dense) + { + system->UpdateCameraComponent(cam); + } + for (auto& handle : system->directorHandleList) + { + handle->UpdateMatrix(); + } + + + } + + + DirectorHandle SHCameraSystem::CreateDirector() noexcept + { + auto handle = directorLibrary.Create(); + directorHandleList.emplace_back(handle); + return handle; + } + + DirectorHandle SHCameraSystem::GetDirector(size_t index) noexcept + { + if (index < directorHandleList.size()) + { + return directorHandleList[index]; + } + else + { + return CreateDirector(); + } + } + void SHCameraSystem::ClampCameraRotation(SHCameraComponent& camera) noexcept + { + + + + if (camera.pitch > 85) + camera.SetPitch(85); + if (camera.pitch < -85) + camera.SetPitch(-85); + if (camera.roll > 85) + camera.SetRoll(85); + if (camera.roll < -85) + camera.SetRoll(-85); + + } + } diff --git a/SHADE_Engine/src/Camera/SHCameraSystem.h b/SHADE_Engine/src/Camera/SHCameraSystem.h index fe7fd145..dacda574 100644 --- a/SHADE_Engine/src/Camera/SHCameraSystem.h +++ b/SHADE_Engine/src/Camera/SHCameraSystem.h @@ -3,9 +3,10 @@ #include "ECS_Base/System/SHSystem.h" #include "SHCameraComponent.h" #include "ECS_Base/System/SHSystemRoutine.h" +#include "Resource/ResourceLibrary.h" +#include "SHCameraDirector.h" #include "SH_API.h" - namespace SHADE { class SH_API SHCameraSystem final : public SHSystem @@ -14,8 +15,9 @@ namespace SHADE //A camera component that represents editor camera. //This is not tied to any entity. Hence this EID should not be used. SHCameraComponent editorCamera; - + ResourceLibrary directorLibrary; + std::vector directorHandleList; public: SHCameraSystem(void) = default; @@ -34,12 +36,27 @@ namespace SHADE }; friend class EditorCameraUpdate; - SHCameraComponent* GetEditorCamera (void) noexcept; + class SH_API CameraSystemUpdate final: public SHSystemRoutine + { + public: + CameraSystemUpdate() : SHSystemRoutine("Camera System Update", false) {}; + virtual void Execute(double dt)noexcept override final; + }; + friend class CameraSystemUpdate; + + SHCameraComponent* GetEditorCamera (void) noexcept; + void GetCameraAxis(SHCameraComponent const& camera, SHVec3& forward, SHVec3& right, SHVec3& up) const noexcept; + DirectorHandle CreateDirector() noexcept; + DirectorHandle GetDirector(size_t index) noexcept; + void ClampCameraRotation(SHCameraComponent& camera) noexcept; + void UpdateEditorCamera(double dt) noexcept; protected: void UpdateCameraComponent(SHCameraComponent& camera) noexcept; + + }; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 992cbdf1..cbf3ad95 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -147,6 +147,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ auto windowDims = window->GetWindowSize(); + auto cameraSystem = SHSystemManager::GetSystem(); // Set Up Cameras screenCamera = resourceManager.Create(); @@ -198,6 +199,8 @@ namespace SHADE worldRenderer = worldViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph); worldRenderer->SetCamera(worldCamera); + worldRenderer->SetCameraDirector(cameraSystem->CreateDirector()); + auto cubeVS = shaderModuleLibrary.GetShaderModule("TestCubeVs.glsl"); auto cubeFS = shaderModuleLibrary.GetShaderModule("TestCubeFs.glsl"); @@ -335,21 +338,7 @@ namespace SHADE auto cameraSystem = SHSystemManager::GetSystem(); -#ifdef SHEDITOR - auto editorSystem = SHSystemManager::GetSystem(); - if (editorSystem->editorState != SHEditor::State::PLAY) - { - worldRenderer->SetViewProjectionMatrix(SHMatrix::Transpose(cameraSystem->GetEditorCamera()->GetProjMatrix() * cameraSystem->GetEditorCamera()->GetViewMatrix())); - } - else - { - // main camera - } - -#else - // main camera -#endif // For every viewport for (int vpIndex = 0; vpIndex < static_cast(viewports.size()); ++vpIndex) @@ -399,7 +388,22 @@ namespace SHADE } // bind camera data + //renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex); + +#ifdef SHEDITOR + if (renderers[renIndex] == worldRenderer) + { + auto editorSystem = SHSystemManager::GetSystem(); + if (editorSystem->editorState != SHEditor::State::PLAY) + worldRenderer->UpdateDataAndBind(currentCmdBuffer, frameIndex, SHMatrix::Transpose(cameraSystem->GetEditorCamera()->GetProjMatrix() * cameraSystem->GetEditorCamera()->GetViewMatrix())); + else + renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex); + } + else + renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex); +#else renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex); +#endif // Draw first renderers[renIndex]->Draw(frameIndex, descPool); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp index a1806ccd..962130be 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp @@ -21,6 +21,7 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h" #include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" #include "Graphics/Buffers/SHVkBuffer.h" +#include "Camera/SHCameraDirector.h" namespace SHADE { @@ -65,6 +66,11 @@ namespace SHADE camera = _camera; } + void SHRenderer::SetCameraDirector(Handle director) noexcept + { + cameraDirector = director; + } + /*-----------------------------------------------------------------------------------*/ /* Drawing Functions */ /*-----------------------------------------------------------------------------------*/ @@ -75,17 +81,24 @@ namespace SHADE void SHRenderer::UpdateDataAndBind(Handle cmdBuffer, uint32_t frameIndex) noexcept { - if (camera) + if (camera && cameraDirector) { - //cpuCameraData.viewProjectionMatrix = camera->GetViewProjectionMatrix(); - cameraBuffer->WriteToMemory(&cpuCameraData, sizeof(SHShaderCameraData), 0, cameraDataAlignedSize * frameIndex); - - std::array dynamicOffsets{ frameIndex * cameraDataAlignedSize }; - - cmdBuffer->BindDescriptorSet(cameraDescriptorSet, SH_PIPELINE_TYPE::GRAPHICS, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 }); + UpdateDataAndBind(cmdBuffer, frameIndex, SHMatrix::Transpose(cameraDirector->GetVPMatrix())); } } + void SHRenderer::UpdateDataAndBind(Handle cmdBuffer, uint32_t frameIndex, SHMatrix exteriorMatrix) noexcept + { + SetViewProjectionMatrix(exteriorMatrix); + + //cpuCameraData.viewProjectionMatrix = camera->GetViewProjectionMatrix(); + cameraBuffer->WriteToMemory(&cpuCameraData, sizeof(SHShaderCameraData), 0, cameraDataAlignedSize * frameIndex); + + std::array dynamicOffsets{ frameIndex * cameraDataAlignedSize }; + + cmdBuffer->BindDescriptorSet(cameraDescriptorSet, SH_PIPELINE_TYPE::GRAPHICS, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 }); + } + void SHRenderer::UpdateCameraDataToBuffer(void) noexcept { } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h index 57c63e7f..a70e1996 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h @@ -40,6 +40,7 @@ namespace SHADE class SHGraphicsGlobalData; class SHVkDescriptorPool; class SHVkBuffer; + class SHCameraDirector; struct SHShaderCameraData { @@ -71,12 +72,14 @@ namespace SHADE /* Camera Registration */ /*-----------------------------------------------------------------------------*/ void SetCamera(Handle _camera); + void SetCameraDirector (Handle director) noexcept; /*-----------------------------------------------------------------------------*/ /* Drawing Functions */ /*-----------------------------------------------------------------------------*/ void Draw(uint32_t frameIndex, Handle descPool) noexcept; - void UpdateDataAndBind (Handle cmdBuffer, uint32_t frameIndex) noexcept; + void UpdateDataAndBind(Handle cmdBuffer, uint32_t frameIndex) noexcept; + void UpdateDataAndBind(Handle cmdBuffer, uint32_t frameIndex, SHMatrix exteriorMatrix) noexcept; void UpdateCameraDataToBuffer (void) noexcept; void SetViewProjectionMatrix (SHMatrix const& vpMatrix) noexcept; @@ -99,6 +102,8 @@ namespace SHADE Handle cameraDescriptorSet; Handle cameraBuffer; + Handle cameraDirector; + // we really only need 1 copy even though we need %swapchainImages copies for // GPU. SHShaderCameraData cpuCameraData; From a81ef91373ff317e74f5545a3d3d2bcf04071faa Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Sun, 23 Oct 2022 16:47:39 +0800 Subject: [PATCH 18/50] Removed some commented code --- .../src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 0de5af17..7ecd92d2 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -185,10 +185,6 @@ namespace SHADE gBufferWriteSubpass->AddColorOutput("Entity ID"); gBufferWriteSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL); - // We do this to just transition our scene layout to shader read - //auto sceneLayoutTransitionSubpass = node->AddSubpass("Scene Layout Transition"); - //sceneLayoutTransitionSubpass->AddGeneralInput("Scene"); - auto greyscale = shaderModuleLibrary.GetShaderModule("KirschCs.glsl"); node->AddNodeCompute (greyscale, {"Scene Pre-Process", "Scene"}); From 33a6d3798c38ce0de2dcfe2aff19c94c8a39452f Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Sun, 23 Oct 2022 16:55:01 +0800 Subject: [PATCH 19/50] Added orientation interface and fixed compatibility between physics and transform --- SHADE_Application/src/Scenes/SBTestScene.cpp | 2 +- SHADE_Engine/src/Math/SHQuaternion.cpp | 4 ++ SHADE_Engine/src/Math/SHQuaternion.h | 1 + .../Math/Transform/SHTransformComponent.cpp | 14 +++- .../src/Math/Transform/SHTransformComponent.h | 6 +- .../src/Math/Transform/SHTransformSystem.cpp | 68 +++++++++++++++---- SHADE_Engine/src/Math/Vector/SHVec4.cpp | 9 +++ SHADE_Engine/src/Math/Vector/SHVec4.h | 14 ++-- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 6 +- 9 files changed, 99 insertions(+), 25 deletions(-) diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index 23259ee4..966a00a5 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -101,7 +101,7 @@ namespace Sandbox //Set initial positions transform.SetWorldPosition(TEST_OBJ_START_POS + SHVec3{ x * TEST_OBJ_SPACING.x, y * TEST_OBJ_SPACING.y, SHMath::GenerateRandomNumber(-3.5f, -5.0f) }); //transform.SetWorldPosition({-1.0f, -1.0f, -1.0f}); - transform.SetWorldRotation(SHMath::GenerateRandomNumber(), SHMath::GenerateRandomNumber(), SHMath::GenerateRandomNumber()); + transform.SetWorldRotation(SHMath::GenerateRandomNumber(0.0f, 360.0f), SHMath::GenerateRandomNumber(0.0f, 360.0f), SHMath::GenerateRandomNumber(0.0f, 360.0f)); transform.SetWorldScale(TEST_OBJ_SCALE); //if (const bool IS_EVEN = (y * NUM_ROWS + x) % 2; IS_EVEN) diff --git a/SHADE_Engine/src/Math/SHQuaternion.cpp b/SHADE_Engine/src/Math/SHQuaternion.cpp index 924ac67a..3878cea1 100644 --- a/SHADE_Engine/src/Math/SHQuaternion.cpp +++ b/SHADE_Engine/src/Math/SHQuaternion.cpp @@ -36,6 +36,10 @@ namespace SHADE : XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f ) {} + SHQuaternion::SHQuaternion(const SHVec4& vec4) noexcept + : XMFLOAT4( vec4.x, vec4.y, vec4.z, vec4.w ) + {} + SHQuaternion::SHQuaternion(float _x, float _y, float _z, float _w) noexcept : XMFLOAT4( _x, _y, _z, _w ) {} diff --git a/SHADE_Engine/src/Math/SHQuaternion.h b/SHADE_Engine/src/Math/SHQuaternion.h index f3ce3d61..cc1b5ff4 100644 --- a/SHADE_Engine/src/Math/SHQuaternion.h +++ b/SHADE_Engine/src/Math/SHQuaternion.h @@ -49,6 +49,7 @@ namespace SHADE SHQuaternion (SHQuaternion&& rhs) = default; SHQuaternion () noexcept; + SHQuaternion (const SHVec4& vec4) noexcept; SHQuaternion (float x, float y, float z, float w) noexcept; SHQuaternion (float yaw, float pitch, float roll) noexcept; diff --git a/SHADE_Engine/src/Math/Transform/SHTransformComponent.cpp b/SHADE_Engine/src/Math/Transform/SHTransformComponent.cpp index 306cde67..e56cbc8d 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformComponent.cpp +++ b/SHADE_Engine/src/Math/Transform/SHTransformComponent.cpp @@ -103,7 +103,9 @@ namespace SHADE void SHTransformComponent::SetLocalRotation(const SHVec3& newLocalRotation) noexcept { dirty = true; + localRotation = newLocalRotation; + updateQueue.push({ UpdateCommandType::LOCAL_ROTATION, newLocalRotation }); } void SHTransformComponent::SetLocalRotation(float pitch, float yaw, float roll) noexcept @@ -113,11 +115,16 @@ namespace SHADE localRotation.x = pitch; localRotation.y = yaw; localRotation.z = roll; + + updateQueue.push({ UpdateCommandType::LOCAL_ROTATION, SHVec3{pitch, yaw, roll} }); } void SHTransformComponent::SetLocalOrientation(const SHQuaternion& newLocalOrientation) noexcept { - + dirty = true; + + local.orientation = newLocalOrientation; + updateQueue.push({ UpdateCommandType::LOCAL_ORIENTATION, newLocalOrientation }); } void SHTransformComponent::SetLocalScale(const SHVec3& newLocalScale) noexcept @@ -155,7 +162,10 @@ namespace SHADE void SHTransformComponent::SetWorldOrientation(const SHQuaternion& newWorldOrientation) noexcept { - + dirty = true; + + world.orientation = newWorldOrientation; + updateQueue.push({ UpdateCommandType::WORLD_ORIENTATION, newWorldOrientation }); } void SHTransformComponent::SetWorldScale(const SHVec3& newWorldScale) noexcept diff --git a/SHADE_Engine/src/Math/Transform/SHTransformComponent.h b/SHADE_Engine/src/Math/Transform/SHTransformComponent.h index d1d21bec..ce8bb6fe 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformComponent.h +++ b/SHADE_Engine/src/Math/Transform/SHTransformComponent.h @@ -97,7 +97,9 @@ namespace SHADE enum class UpdateCommandType { - WORLD_POSITION + LOCAL_ROTATION + , LOCAL_ORIENTATION + , WORLD_POSITION , WORLD_ROTATION , WORLD_ORIENTATION , WORLD_SCALE @@ -111,7 +113,7 @@ namespace SHADE /*-------------------------------------------------------------------------------*/ UpdateCommandType type; - SHVec3 data; + SHVec4 data; }; using UpdateQueue = std::queue; diff --git a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp index 3244db1b..8bd01fb4 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp +++ b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp @@ -200,6 +200,8 @@ namespace SHADE SHMatrix localToWorld = SHMatrix::Identity; SHMatrix worldToLocal = SHMatrix::Identity; + bool convertRotation = true; + if (parent) { localToWorld = parent->GetTRS(); @@ -212,27 +214,44 @@ namespace SHADE switch (UPDATE_COMMAND.type) { + case SHTransformComponent::UpdateCommandType::LOCAL_ROTATION: + { + convertRotation = true; + break; + } + case SHTransformComponent::UpdateCommandType::LOCAL_ORIENTATION: + { + convertRotation = false; + break; + } case SHTransformComponent::UpdateCommandType::WORLD_POSITION: { - tf.local.position = SHVec3::Transform(UPDATE_COMMAND.data, worldToLocal); + tf.local.position = SHVec3::Transform(UPDATE_COMMAND.data.ToVec3(), worldToLocal); break; } case SHTransformComponent::UpdateCommandType::WORLD_ROTATION: { - tf.localRotation = tf.worldRotation; + tf.localRotation = UPDATE_COMMAND.data.ToVec3(); if (parent) tf.localRotation -= parent->GetLocalRotation(); + convertRotation = true; + break; } case SHTransformComponent::UpdateCommandType::WORLD_ORIENTATION: { - // TODO(Diren): Test using scripts by concat quaternions? + tf.local.orientation = UPDATE_COMMAND.data; + if (parent) + tf.local.orientation /= parent->GetLocalOrientation(); + + convertRotation = false; + break; } case SHTransformComponent::UpdateCommandType::WORLD_SCALE: { - tf.local.scale = tf.world.scale; + tf.local.scale = UPDATE_COMMAND.data.ToVec3(); if (parent) tf.local.scale /= parent->GetLocalScale(); @@ -247,17 +266,42 @@ namespace SHADE tf.local.trs = localToWorld; + // Compute world transforms tf.world.position = SHVec3::Transform(tf.local.position, localToWorld); - - tf.worldRotation = tf.localRotation + (parent ? parent->GetLocalRotation() : SHVec3::Zero); - - // TODO(Diren): Wrap rotations between -360 and 360 - - tf.world.orientation = SHQuaternion::FromEuler(tf.worldRotation); - tf.local.orientation = SHQuaternion::FromEuler(tf.localRotation); - tf.world.scale = tf.local.scale * (parent ? parent->GetLocalScale() : SHVec3::One); + SHVec3 worldRotRad, localRotRad; + + if (convertRotation) + { + tf.worldRotation = tf.localRotation + (parent ? parent->GetLocalRotation() : SHVec3::Zero); + + // Set the orientation + // Wrap rotations between -360 and 360 and convert to radians + for (size_t i = 0; i < SHVec3::SIZE; ++i) + { + worldRotRad[i] = SHMath::DegreesToRadians(SHMath::Wrap(tf.worldRotation[i], -360.0f, 360.0f)); + localRotRad[i] = SHMath::DegreesToRadians(SHMath::Wrap(tf.localRotation[i], -360.0f, 360.0f)); + } + + tf.world.orientation = SHQuaternion::FromEuler(worldRotRad); + tf.local.orientation = SHQuaternion::FromEuler(localRotRad); + } + else + { + tf.world.orientation = (parent ? parent->GetLocalOrientation() : SHQuaternion::Identity) * tf.local.orientation; + + // Set the euler angle rotations + worldRotRad = tf.world.orientation.ToEuler(); + localRotRad = tf.local.orientation.ToEuler(); + + for (size_t i = 0; i < SHVec3::SIZE; ++i) + { + tf.worldRotation[i] = SHMath::RadiansToDegrees(worldRotRad[i]); + tf.localRotation[i] = SHMath::RadiansToDegrees(localRotRad[i]); + } + } + tf.world.ComputeTRS(); } diff --git a/SHADE_Engine/src/Math/Vector/SHVec4.cpp b/SHADE_Engine/src/Math/Vector/SHVec4.cpp index bcf2ef97..9857818a 100644 --- a/SHADE_Engine/src/Math/Vector/SHVec4.cpp +++ b/SHADE_Engine/src/Math/Vector/SHVec4.cpp @@ -38,6 +38,10 @@ namespace SHADE : XMFLOAT4( 0.0f, 0.0f, 0.0f, 0.0f ) {} + SHVec4::SHVec4(const SHVec3& vec3) noexcept + : XMFLOAT4( vec3.x, vec3.y, vec3.z, 1.0f ) + {} + SHVec4::SHVec4(const XMFLOAT4& xmfloat4) noexcept : XMFLOAT4( xmfloat4.x, xmfloat4.y, xmfloat4.z, xmfloat4.w ) {} @@ -271,6 +275,11 @@ namespace SHADE return result; } + SHVec3 SHVec4::ToVec3() const noexcept + { + return SHVec3{ x, y, z }; + } + /*-----------------------------------------------------------------------------------*/ /* Static Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Math/Vector/SHVec4.h b/SHADE_Engine/src/Math/Vector/SHVec4.h index 911a714e..ce341bed 100644 --- a/SHADE_Engine/src/Math/Vector/SHVec4.h +++ b/SHADE_Engine/src/Math/Vector/SHVec4.h @@ -16,6 +16,7 @@ // Project Headers #include "SH_API.h" +#include "SHVec3.h" namespace SHADE { @@ -53,6 +54,7 @@ namespace SHADE ~SHVec4 () = default; SHVec4 () noexcept; + SHVec4 (const SHVec3& vec3) noexcept; SHVec4 (const XMFLOAT4& xmfloat4) noexcept; SHVec4 (float x, float y, float z, float w) noexcept; @@ -102,16 +104,18 @@ namespace SHADE [[nodiscard]] float Dot3D (const SHVec4& rhs) const noexcept; [[nodiscard]] SHVec4 Cross3D (const SHVec4& rhs) const noexcept; [[nodiscard]] SHVec4 Cross (const SHVec4& v1, const SHVec4& v2) const noexcept; + + [[nodiscard]] SHVec3 ToVec3 () const noexcept; /*---------------------------------------------------------------------------------*/ /* Static Function Members */ /*---------------------------------------------------------------------------------*/ - [[nodiscard]] static SHVec4 Normalise (const SHVec4& v) noexcept; - [[nodiscard]] static SHVec4 Normalise3D (const SHVec4& v) noexcept; - [[nodiscard]] static SHVec4 Abs (const SHVec4& v) noexcept; - [[nodiscard]] static SHVec4 Min (const std::initializer_list& vs) noexcept; - [[nodiscard]] static SHVec4 Max (const std::initializer_list& vs) noexcept; + [[nodiscard]] static SHVec4 Normalise (const SHVec4& v) noexcept; + [[nodiscard]] static SHVec4 Normalise3D (const SHVec4& v) noexcept; + [[nodiscard]] static SHVec4 Abs (const SHVec4& v) noexcept; + [[nodiscard]] static SHVec4 Min (const std::initializer_list& vs) noexcept; + [[nodiscard]] static SHVec4 Max (const std::initializer_list& vs) noexcept; [[nodiscard]] static SHVec4 Clamp (const SHVec4& v, const SHVec4& vMin, const SHVec4& vMax) noexcept; [[nodiscard]] static SHVec4 Lerp (const SHVec4& a, const SHVec4& b, float t) noexcept; [[nodiscard]] static SHVec4 ClampedLerp (const SHVec4& a, const SHVec4& b, float t, float tMin = 0.0f, float tMax = 1.0f) noexcept; diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index 7dc6c44e..a1994ad2 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -16,6 +16,7 @@ // Project Headers #include "ECS_Base/Managers/SHComponentManager.h" #include "ECS_Base/Managers/SHEntityManager.h" +#include "Math/SHMathHelpers.h" #include "Scene/SHSceneManager.h" #include "Math/Transform/SHTransformComponent.h" @@ -315,7 +316,7 @@ namespace SHADE if (TF->HasChanged()) { physicsObject.SetPosition(TF->GetWorldPosition()); - physicsObject.SetRotation(TF->GetWorldRotation()); + physicsObject.SetOrientation(TF->GetWorldOrientation()); } } } @@ -492,8 +493,7 @@ namespace SHADE // Convert RP3D Transform to SHADE auto* tfComponent = SHComponentManager::GetComponent(entityID); tfComponent->SetWorldPosition(rp3dPos); - tfComponent->SetWorldRotation(SHQuaternion{ rp3dRot }.ToEuler()); - + tfComponent->SetWorldOrientation(SHQuaternion{ rp3dRot }); // Cache transforms physicsObject.prevTransform = CURRENT_TF; From a83d1f8f04ae82332d9fd065b34eec911e2e4ff3 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Sun, 23 Oct 2022 16:55:57 +0800 Subject: [PATCH 20/50] Removed line that loaded all assets Separated template function in asset manager into hpp file Fixed bug in checking map contains --- SHADE_Engine/src/Assets/SHAssetManager.cpp | 17 +++++------- SHADE_Engine/src/Assets/SHAssetManager.h | 22 +++------------- SHADE_Engine/src/Assets/SHAssetManager.hpp | 26 +++++++++++++++++++ .../src/Resource/SHResourceManager.hpp | 2 +- 4 files changed, 37 insertions(+), 30 deletions(-) create mode 100644 SHADE_Engine/src/Assets/SHAssetManager.hpp diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index bcae992e..3032ba51 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -56,18 +56,15 @@ namespace SHADE ****************************************************************************/ void SHAssetManager::Unload() noexcept { - for (auto const& asset : assetCollection) - { - SHAssetMetaHandler::WriteMetaData(asset); - } + } - void SHAssetManager::Unload(AssetID assetId) noexcept - { - // TODO - } + void SHAssetManager::Unload(AssetID assetId) noexcept + { + // TODO + } - AssetPath SHAssetManager::GenerateLocalPath(AssetPath path) noexcept + AssetPath SHAssetManager::GenerateLocalPath(AssetPath path) noexcept { if (!IsRecognised(path.extension().string().c_str())) { @@ -256,7 +253,7 @@ namespace SHADE { InitLoaders(); BuildAssetCollection(); - LoadAllData(); + //LoadAllData(); } /**************************************************************************** diff --git a/SHADE_Engine/src/Assets/SHAssetManager.h b/SHADE_Engine/src/Assets/SHAssetManager.h index 4c1ded71..9ee7ab92 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.h +++ b/SHADE_Engine/src/Assets/SHAssetManager.h @@ -76,25 +76,7 @@ namespace SHADE // -------------------------------------------------------------------------/ template - static std::enable_if_t, T const * const> GetData(AssetID id) noexcept - { - if (assetData.contains(id)) - { - for (auto const& asset : assetCollection) - { - if (asset.id == id) - { - assetData.emplace(id, LoadData(asset)); - return dynamic_cast(assetData[id]); - } - } - - SHLOG_ERROR("Asset ID provided does not exist: {}", id); - return nullptr; - } - - return dynamic_cast(assetData[id]); - } + static std::enable_if_t, T const* const> GetData(AssetID id) noexcept; private: /**************************************************************************** * \brief Load resource data into memory @@ -121,3 +103,5 @@ namespace SHADE static std::unordered_map assetData; }; } + +#include "SHAssetManager.hpp" diff --git a/SHADE_Engine/src/Assets/SHAssetManager.hpp b/SHADE_Engine/src/Assets/SHAssetManager.hpp new file mode 100644 index 00000000..6c420778 --- /dev/null +++ b/SHADE_Engine/src/Assets/SHAssetManager.hpp @@ -0,0 +1,26 @@ + +#include "SHAssetManager.h" + +namespace SHADE +{ + template + std::enable_if_t, T const* const> SHAssetManager::GetData(AssetID id) noexcept + { + if (!assetData.contains(id)) + { + for (auto const& asset : assetCollection) + { + if (asset.id == id) + { + assetData.emplace(id, LoadData(asset)); + return dynamic_cast(assetData[id]); + } + } + + SHLOG_ERROR("Asset ID provided does not exist: {}", id); + return nullptr; + } + + return dynamic_cast(assetData[id]); + } +} diff --git a/SHADE_Engine/src/Resource/SHResourceManager.hpp b/SHADE_Engine/src/Resource/SHResourceManager.hpp index fb0dcc6a..cff4e84b 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.hpp +++ b/SHADE_Engine/src/Resource/SHResourceManager.hpp @@ -134,7 +134,7 @@ namespace SHADE /* Query Functions */ /*-----------------------------------------------------------------------------------*/ template - static std::optional SHResourceManager::GetAssetID(Handle handle) + std::optional SHResourceManager::GetAssetID(Handle handle) { const Handle GENERIC_HANDLE = Handle(handle); auto [typedHandleMap, typedAssetIdMap] = getAssetHandleMap(); From f9a28c81d4ab01f182114524119b8ef290627ad8 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Sun, 23 Oct 2022 17:18:46 +0800 Subject: [PATCH 21/50] Fixed vulkan breaking error --- SHADE_Application/src/Scenes/SBTestScene.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index b414ecaf..0c06a092 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -52,7 +52,7 @@ namespace Sandbox if (asset.name == "Cube.012") handles.emplace_back(SHResourceManager::LoadOrGet(asset.id)); break; - case AssetType::TEXTURE: + case AssetType::IMAGE: texHandles.emplace_back(SHResourceManager::LoadOrGet(asset.id)); break; } From e15f7696e62ad51896e58fde0bda32df87339d8a Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Sun, 23 Oct 2022 18:22:58 +0800 Subject: [PATCH 22/50] Rotations are stored as radians to reduce the number of conversions --- .../src/Math/Transform/SHTransformComponent.h | 4 ++-- .../src/Math/Transform/SHTransformSystem.cpp | 17 ++++++----------- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/SHADE_Engine/src/Math/Transform/SHTransformComponent.h b/SHADE_Engine/src/Math/Transform/SHTransformComponent.h index ce8bb6fe..2fe67bdd 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformComponent.h +++ b/SHADE_Engine/src/Math/Transform/SHTransformComponent.h @@ -127,8 +127,8 @@ namespace SHADE // We store euler angle rotations separately to interface with transform quaternions. // Reading quaternions are unreliable. - SHVec3 localRotation; // Stored in degrees - SHVec3 worldRotation; // Stored in degrees + SHVec3 localRotation; // Stored in Radians + SHVec3 worldRotation; // Stored in Radians SHTransform local; // Local TRS holds Local To World Transform SHTransform world; diff --git a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp index 8bd01fb4..5a540cd4 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp +++ b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp @@ -270,7 +270,7 @@ namespace SHADE tf.world.position = SHVec3::Transform(tf.local.position, localToWorld); tf.world.scale = tf.local.scale * (parent ? parent->GetLocalScale() : SHVec3::One); - SHVec3 worldRotRad, localRotRad; + if (convertRotation) { @@ -278,10 +278,11 @@ namespace SHADE // Set the orientation // Wrap rotations between -360 and 360 and convert to radians + SHVec3 worldRotRad, localRotRad; for (size_t i = 0; i < SHVec3::SIZE; ++i) { - worldRotRad[i] = SHMath::DegreesToRadians(SHMath::Wrap(tf.worldRotation[i], -360.0f, 360.0f)); - localRotRad[i] = SHMath::DegreesToRadians(SHMath::Wrap(tf.localRotation[i], -360.0f, 360.0f)); + 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); } tf.world.orientation = SHQuaternion::FromEuler(worldRotRad); @@ -292,14 +293,8 @@ namespace SHADE tf.world.orientation = (parent ? parent->GetLocalOrientation() : SHQuaternion::Identity) * tf.local.orientation; // Set the euler angle rotations - worldRotRad = tf.world.orientation.ToEuler(); - localRotRad = tf.local.orientation.ToEuler(); - - for (size_t i = 0; i < SHVec3::SIZE; ++i) - { - tf.worldRotation[i] = SHMath::RadiansToDegrees(worldRotRad[i]); - tf.localRotation[i] = SHMath::RadiansToDegrees(localRotRad[i]); - } + tf.worldRotation = tf.world.orientation.ToEuler(); + tf.localRotation = tf.local.orientation.ToEuler(); } tf.world.ComputeTRS(); From 57f9898e07667e00fede342e79fc4bee42551693 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Sun, 23 Oct 2022 20:03:18 +0800 Subject: [PATCH 23/50] Finished quaternion implementation --- SHADE_Engine/src/Math/SHQuaternion.cpp | 125 +++++++++++++++++++++---- SHADE_Engine/src/Math/SHQuaternion.h | 40 ++++---- SHADE_Managed/Quaternion.hxx | 17 ++++ SHADE_Managed/src/Math/Vector3.hxx | 1 + 4 files changed, 148 insertions(+), 35 deletions(-) create mode 100644 SHADE_Managed/Quaternion.hxx diff --git a/SHADE_Engine/src/Math/SHQuaternion.cpp b/SHADE_Engine/src/Math/SHQuaternion.cpp index 3878cea1..3564916a 100644 --- a/SHADE_Engine/src/Math/SHQuaternion.cpp +++ b/SHADE_Engine/src/Math/SHQuaternion.cpp @@ -211,15 +211,6 @@ namespace SHADE return XMVectorGetX(XMQuaternionDot(*this, rhs)); } - SHQuaternion SHQuaternion::RotateTowards(const SHQuaternion&, float) const noexcept - { - SHQuaternion result; - - // TODO (Diren) - - return result; - } - SHVec3 SHQuaternion::ToEuler() const noexcept { const float XX = x * x; @@ -317,19 +308,32 @@ namespace SHADE } - float SHQuaternion::Angle(const SHQuaternion&, const SHQuaternion&) noexcept + float SHQuaternion::Angle(const SHQuaternion& q1, const SHQuaternion& q2) noexcept { - // TODO (Diren) + XMVECTOR R = XMQuaternionMultiply(XMQuaternionConjugate(q1), q2); - return 0.0f; + const float RS = XMVectorGetW(R); + R = XMVector3Length(R); + return 2.0f * atan2f(XMVectorGetX(R), RS); } - SHQuaternion SHQuaternion::Lerp(const SHQuaternion&, const SHQuaternion&, float) noexcept + SHQuaternion SHQuaternion::Lerp(const SHQuaternion& q1, const SHQuaternion& q2, float t) noexcept { SHQuaternion result; - // TODO (Diren) + XMVECTOR R = XMVectorZero(); + if (XMVector4GreaterOrEqual(XMVector4Dot(q1, q2), R)) + { + R = XMVectorLerp(q1, q2, t); + } + else + { + const XMVECTOR X0 = XMVectorMultiply(q1, XMVectorReplicate(1.f - t)); + const XMVECTOR X1 = XMVectorMultiply(q2, XMVectorReplicate(t)); + R = XMVectorSubtract(X0, X1); + } + XMStoreFloat4(&result, XMQuaternionNormalize(R)); return result; } @@ -341,13 +345,102 @@ namespace SHADE return result; } - SHQuaternion SHQuaternion::Rotate(const SHVec3& , const SHVec3&) noexcept + SHQuaternion SHQuaternion::ClampedLerp(const SHQuaternion& q1, const SHQuaternion& q2, float t, float tMin, float tMax) noexcept { + return Lerp(q1, q2, std::clamp(t, tMin, tMax)); + } + + + SHQuaternion SHQuaternion::ClampedSlerp(const SHQuaternion& q1, const SHQuaternion& q2, float t, float tMin, float tMax) noexcept + { + return Slerp(q1, q2, std::clamp(t, tMin, tMax)); + } + + SHQuaternion SHQuaternion::FromToRotation(const SHVec3& from, const SHVec3& to) noexcept + { + // Melax, "The Shortest Arc Quaternion", Game Programming Gems + SHQuaternion result; - // TODO (Diren) + const XMVECTOR F = XMVector3Normalize(from); + const XMVECTOR T = XMVector3Normalize(to); + + const float dot = XMVectorGetX(XMVector3Dot(F, T)); + if (dot >= 1.f) + { + result = Identity; + } + else if (dot <= -1.f) + { + XMVECTOR axis = XMVector3Cross(F, SHVec3::Right); + if (XMVector3NearEqual(XMVector3LengthSq(axis), g_XMZero, g_XMEpsilon)) + { + axis = XMVector3Cross(F, SHVec3::Up); + } + + const XMVECTOR Q = XMQuaternionRotationAxis(axis, XM_PI); + XMStoreFloat4(&result, Q); + } + else + { + const XMVECTOR C = XMVector3Cross(F, T); + XMStoreFloat4(&result, C); + + const float s = sqrtf((1.f + dot) * 2.f); + result.x /= s; + result.y /= s; + result.z /= s; + result.w = s * 0.5f; + } return result; } + SHQuaternion SHQuaternion::LookRotation(const SHVec3& forward, const SHVec3& up) noexcept + { + SHQuaternion result; + + const SHQuaternion Q1 = FromToRotation(SHVec3::Forward, forward); + + const XMVECTOR C = XMVector3Cross(forward, up); + if (XMVector3NearEqual(XMVector3LengthSq(C), g_XMZero, g_XMEpsilon)) + { + // forward and up are co-linear + return Q1; + } + + SHVec3 qU; + XMStoreFloat3(&qU, XMQuaternionMultiply(Q1, SHVec3::Up)); + + const SHQuaternion Q2 = FromToRotation(qU, up); + + XMStoreFloat4(&result, XMQuaternionMultiply(Q2, Q1)); + + return result; + } + + SHQuaternion SHQuaternion::RotateTowards(const SHQuaternion& from, const SHQuaternion& to, float maxAngleInRad) noexcept + { + SHQuaternion result; + + // We can use the conjugate here instead of inverse assuming q1 & q2 are normalized. + const XMVECTOR R = XMQuaternionMultiply(XMQuaternionConjugate(from), to); + + const float RS = XMVectorGetW(R); + const XMVECTOR L = XMVector3Length(R); + const float angle = 2.f * atan2f(XMVectorGetX(L), RS); + if (angle > maxAngleInRad) + { + const XMVECTOR delta = XMQuaternionRotationAxis(R, maxAngleInRad); + const XMVECTOR Q = XMQuaternionMultiply(delta, from); + XMStoreFloat4(&result, Q); + } + else + { + // Don't overshoot. + result = to; + } + return result; + } + } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Math/SHQuaternion.h b/SHADE_Engine/src/Math/SHQuaternion.h index cc1b5ff4..fa5b5d36 100644 --- a/SHADE_Engine/src/Math/SHQuaternion.h +++ b/SHADE_Engine/src/Math/SHQuaternion.h @@ -51,7 +51,6 @@ namespace SHADE SHQuaternion () noexcept; SHQuaternion (const SHVec4& vec4) noexcept; SHQuaternion (float x, float y, float z, float w) noexcept; - SHQuaternion (float yaw, float pitch, float roll) noexcept; // Conversion from other math types @@ -98,34 +97,37 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ - void Invert () noexcept; + void Invert () noexcept; - [[nodiscard]] float Length () const noexcept; - [[nodiscard]] float LengthSquared () const noexcept; - [[nodiscard]] float Dot (const SHQuaternion& rhs) const noexcept; - [[nodiscard]] SHQuaternion RotateTowards (const SHQuaternion& target, float maxAngleInRad) const noexcept; + [[nodiscard]] float Length () const noexcept; + [[nodiscard]] float LengthSquared () const noexcept; + [[nodiscard]] float Dot (const SHQuaternion& rhs) const noexcept; - [[nodiscard]] SHVec3 ToEuler () const noexcept; - [[nodiscard]] std::string ToString () const noexcept; + [[nodiscard]] SHVec3 ToEuler () const noexcept; + [[nodiscard]] std::string ToString () const noexcept; /*---------------------------------------------------------------------------------*/ /* Static Function Members */ /*---------------------------------------------------------------------------------*/ - [[nodiscard]] static SHQuaternion FromEuler (const SHVec3& eulerAngles) noexcept; - [[nodiscard]] static SHQuaternion FromPitchYawRoll (float pitch, float yaw, float roll) noexcept; - [[nodiscard]] static SHQuaternion FromAxisAngle (const SHVec3& axis, float angle) noexcept; - [[nodiscard]] static SHQuaternion FromRotationMatrix(const SHMatrix& rotationMatrix) noexcept; + [[nodiscard]] static SHQuaternion FromEuler (const SHVec3& eulerAngles) noexcept; + [[nodiscard]] static SHQuaternion FromPitchYawRoll (float pitch, float yaw, float roll) noexcept; + [[nodiscard]] static SHQuaternion FromAxisAngle (const SHVec3& axis, float angle) noexcept; + [[nodiscard]] static SHQuaternion FromRotationMatrix(const SHMatrix& rotationMatrix) noexcept; - [[nodiscard]] static SHQuaternion Normalise (const SHQuaternion& q) noexcept; - [[nodiscard]] static SHQuaternion Conjugate (const SHQuaternion& q) noexcept; - [[nodiscard]] static SHQuaternion Inverse (const SHQuaternion& q) noexcept; - [[nodiscard]] static float Angle (const SHQuaternion& q1, const SHQuaternion& q2) noexcept; + [[nodiscard]] static SHQuaternion Normalise (const SHQuaternion& q) noexcept; + [[nodiscard]] static SHQuaternion Conjugate (const SHQuaternion& q) noexcept; + [[nodiscard]] static SHQuaternion Inverse (const SHQuaternion& q) noexcept; + [[nodiscard]] static float Angle (const SHQuaternion& q1, const SHQuaternion& q2) noexcept; - [[nodiscard]] static SHQuaternion Lerp (const SHQuaternion& q1, const SHQuaternion& q2, float t) noexcept; - [[nodiscard]] static SHQuaternion Slerp (const SHQuaternion& q1, const SHQuaternion& q2, float t) noexcept; + [[nodiscard]] static SHQuaternion Lerp (const SHQuaternion& q1, const SHQuaternion& q2, float t) noexcept; + [[nodiscard]] static SHQuaternion Slerp (const SHQuaternion& q1, const SHQuaternion& q2, float t) noexcept; + [[nodiscard]] static SHQuaternion ClampedLerp (const SHQuaternion& q1, const SHQuaternion& q2, float t, float tMin = 0.0f, float tMax = 1.0f) noexcept; + [[nodiscard]] static SHQuaternion ClampedSlerp (const SHQuaternion& q1, const SHQuaternion& q2, float t, float tMin = 0.0f, float tMax = 1.0f) noexcept; - [[nodiscard]] static SHQuaternion Rotate (const SHVec3& from, const SHVec3& to) noexcept; + [[nodiscard]] static SHQuaternion FromToRotation (const SHVec3& from, const SHVec3& to) noexcept; + [[nodiscard]] static SHQuaternion LookRotation (const SHVec3& forward, const SHVec3& up) noexcept; + [[nodiscard]] static SHQuaternion RotateTowards (const SHQuaternion& from, const SHQuaternion& to, float maxAngleInRad) noexcept; }; SHQuaternion operator*(float lhs, const SHQuaternion& rhs) noexcept; diff --git a/SHADE_Managed/Quaternion.hxx b/SHADE_Managed/Quaternion.hxx new file mode 100644 index 00000000..0b07a34e --- /dev/null +++ b/SHADE_Managed/Quaternion.hxx @@ -0,0 +1,17 @@ +/************************************************************************************//*! +\file Quaternion.hxx +\author Diren D Bharwani, diren.dbharwani, 390002520 +\par email: diren.dbharwani\@digipen.edu +\date Oct 23, 2022 +\brief Contains the definitions of Quaternion struct. + + 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 +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ + +#pragma once + +// TODO(Diren) diff --git a/SHADE_Managed/src/Math/Vector3.hxx b/SHADE_Managed/src/Math/Vector3.hxx index e6cdc7d4..8b66439c 100644 --- a/SHADE_Managed/src/Math/Vector3.hxx +++ b/SHADE_Managed/src/Math/Vector3.hxx @@ -11,6 +11,7 @@ Copyright (C) 2021 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 // Standard Libraries From c34faade8679b7d34735ad47332e445bafc4abb8 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Mon, 24 Oct 2022 02:45:47 +0800 Subject: [PATCH 24/50] Converted doubles to floats in SHADE Managed. Added Quaternions. --- SHADE_Managed/Quaternion.hxx | 17 -- SHADE_Managed/src/Math/Math.cxx | 14 +- SHADE_Managed/src/Math/Math.hxx | 24 +-- SHADE_Managed/src/Math/Quaternion.cxx | 170 ++++++++++++++++++ SHADE_Managed/src/Math/Quaternion.hxx | 237 ++++++++++++++++++++++++++ SHADE_Managed/src/Math/Vector2.cxx | 52 +++--- SHADE_Managed/src/Math/Vector2.hxx | 76 ++++----- SHADE_Managed/src/Math/Vector3.cxx | 61 +++---- SHADE_Managed/src/Math/Vector3.hxx | 98 +++++------ SHADE_Managed/src/Utility/Convert.cxx | 19 ++- SHADE_Managed/src/Utility/Convert.hxx | 14 ++ 11 files changed, 596 insertions(+), 186 deletions(-) delete mode 100644 SHADE_Managed/Quaternion.hxx create mode 100644 SHADE_Managed/src/Math/Quaternion.cxx create mode 100644 SHADE_Managed/src/Math/Quaternion.hxx diff --git a/SHADE_Managed/Quaternion.hxx b/SHADE_Managed/Quaternion.hxx deleted file mode 100644 index 0b07a34e..00000000 --- a/SHADE_Managed/Quaternion.hxx +++ /dev/null @@ -1,17 +0,0 @@ -/************************************************************************************//*! -\file Quaternion.hxx -\author Diren D Bharwani, diren.dbharwani, 390002520 -\par email: diren.dbharwani\@digipen.edu -\date Oct 23, 2022 -\brief Contains the definitions of Quaternion struct. - - 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 -of DigiPen Institute of Technology is prohibited. -*//*************************************************************************************/ - -#pragma once - -// TODO(Diren) diff --git a/SHADE_Managed/src/Math/Math.cxx b/SHADE_Managed/src/Math/Math.cxx index 5ec850a1..fa72e2b6 100644 --- a/SHADE_Managed/src/Math/Math.cxx +++ b/SHADE_Managed/src/Math/Math.cxx @@ -21,7 +21,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Utility Functions */ /*---------------------------------------------------------------------------------*/ - double Math::Wrap(double value, double min, double max) + float Math::Wrap(float value, float min, float max) { while (value < min) { @@ -33,24 +33,24 @@ namespace SHADE } return value; } - double Math::DegreesToRadians(double degrees) + float Math::DegreesToRadians(float degrees) { return degrees * Deg2Rad; } - double Math::RadiansToDegrees(double radians) + float Math::RadiansToDegrees(float radians) { return radians * Rad2Deg; } - double Math::Lerp(double a, double b, double t) + float Math::Lerp(float a, float b, float t) { - return LerpUnclamped(a, b, System::Math::Clamp(t, 0.0, 1.0)); + return LerpUnclamped(a, b, System::Math::Clamp(t, 0.0f, 1.0f)); } - double Math::LerpUnclamped(double a, double b, double t) + float Math::LerpUnclamped(float a, float b, float t) { return a + t * (b - a); } - double Math::InverseLerp(double a, double b, double value) + float Math::InverseLerp(float a, float b, float value) { return (value - a) / (b - a); } diff --git a/SHADE_Managed/src/Math/Math.hxx b/SHADE_Managed/src/Math/Math.hxx index 3ddc5149..1578d97c 100644 --- a/SHADE_Managed/src/Math/Math.hxx +++ b/SHADE_Managed/src/Math/Math.hxx @@ -27,11 +27,11 @@ namespace SHADE /// /// Degrees-to-radians conversion constant /// - static constexpr double Deg2Rad = System::Math::PI / 180.0; + static constexpr float Deg2Rad = System::Math::PI / 180.0f; /// /// Radians-to-degrees conversion constant /// - static constexpr double Rad2Deg = 180.0 / System::Math::PI; + static constexpr float Rad2Deg = 180.0f / System::Math::PI; /// /// Small value used for single precision floating point comparisons. /// @@ -47,28 +47,28 @@ namespace SHADE /// Minimum value to wrap at. /// Maximum value to wrap at. /// Wrapped value. - static double Wrap(double value, double min, double max); + static float Wrap(float value, float min, float max); /// /// Converts an angle from degree representation to radian representation. /// /// Degree-based angle to convert. /// The specified angle in radians. - static double DegreesToRadians(double degrees); + static float DegreesToRadians(float degrees); /// /// Converts an angle from radian representation to degree representation. /// /// Radian-based angle to convert. /// The specified angle in degrees. - static double RadiansToDegrees(double radians); + static float RadiansToDegrees(float radians); /// /// Linearly interpolates between a and b by t. /// The parameter t is clamped to the range [0, 1]. /// /// The start value. /// The end value. - /// The interpolation value between the two double. - /// The interpolated double result between the two double values. - static double Lerp(double a, double b, double t); + /// The interpolation value between the two float. + /// The interpolated float result between the two float values. + static float Lerp(float a, float b, float t); /// /// Linearly interpolates between a and b by t. /// The parameter t is not clamped and a value based on a and b is supported. @@ -77,9 +77,9 @@ namespace SHADE /// /// The start value. /// The end value. - /// The interpolation value between the two double. - /// The interpolated double result between the two double values. - static double LerpUnclamped(double a, double b, double t); + /// The interpolation value between the two float. + /// The interpolated float result between the two float values. + static float LerpUnclamped(float a, float b, float t); /// /// Calculates the linear parameter t that produces the interpolant value within the range [a, b]. /// @@ -87,6 +87,6 @@ namespace SHADE /// End value. /// Value between start and end. /// Percentage of value between start and end. - static double InverseLerp(double a, double b, double value); + static float InverseLerp(float a, float b, float value); }; } diff --git a/SHADE_Managed/src/Math/Quaternion.cxx b/SHADE_Managed/src/Math/Quaternion.cxx new file mode 100644 index 00000000..863241ac --- /dev/null +++ b/SHADE_Managed/src/Math/Quaternion.cxx @@ -0,0 +1,170 @@ +/************************************************************************************//*! +\file Quaternion.cxx +\author Diren D Bharwani, diren.dbharwani, 390002520 +\par email: diren.dbharwani\@digipen.edu +\date Oct 23, 2022 +\brief Contains the definitions of functions in the Quaternion struct. + + 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 +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ + +// Precompiled Headers +#include "SHpch.h" +// Primary Header +#include "Quaternion.hxx" +// External Dependencies +#include "Math/SHQuaternion.h" +#include "Math/Vector/SHVec4.h" +// Project Headers +#include "Utility/Convert.hxx" +#include "Math.hxx" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Constructors */ + /*---------------------------------------------------------------------------------*/ + + Quaternion::Quaternion(float _x, float _y, float _z, float _w) + : x { _x } + , y { _y } + , z { _z } + , w { _w } + {} + + /*---------------------------------------------------------------------------------*/ + /* Usage Functions */ + /*---------------------------------------------------------------------------------*/ + + void Quaternion::SetFromToRotation(Vector3 fromDirection, Vector3 toDirection) + { + const SHQuaternion R = SHQuaternion::FromToRotation(Convert::ToNative(fromDirection), Convert::ToNative(toDirection)); + *this = Convert::ToCLI(R); + } + + void Quaternion::SetLookRotation(Vector3 view, Vector3 up) + { + const SHQuaternion R = SHQuaternion::LookRotation(Convert::ToNative(view), Convert::ToNative(up)); + *this = Convert::ToCLI(R); + } + + void Quaternion::ToAngleAxis(float^% angle, Vector3^% axis) + { + const SHVec4 NATIVE_AXIS_ANGLE = Convert::ToNative(*this).GetAxisAngle(); + axis = Convert::ToCLI(NATIVE_AXIS_ANGLE.ToVec3()); + angle = NATIVE_AXIS_ANGLE.w; + } + + System::String^ Quaternion::ToString() + { + return ValueType::ToString(); + } + + /*---------------------------------------------------------------------------------*/ + /* IEquatable */ + /*---------------------------------------------------------------------------------*/ + + bool Quaternion::Equals(Quaternion other) + { + const float DOT = Dot(*this, other); + return fabs(1.0f - DOT) <= Math::Epsilon; + } + + /*---------------------------------------------------------------------------------*/ + /* Object Overrides */ + /*---------------------------------------------------------------------------------*/ + + bool Quaternion::Equals(Object^ o) + { + return ValueType::Equals(o); + } + + int Quaternion::GetHashCode() + { + return ValueType::GetHashCode(); + } + + /*---------------------------------------------------------------------------------*/ + /* Static Functions */ + /*---------------------------------------------------------------------------------*/ + + float Quaternion::Angle(Quaternion a, Quaternion b) + { + return SHQuaternion::Angle(Convert::ToNative(a), Convert::ToNative(b)); + } + + Quaternion Quaternion::AngleAxis(float angle, Vector3 axis) + { + return Convert::ToCLI(SHQuaternion::FromAxisAngle(Convert::ToNative(axis), angle)); + } + + float Quaternion::Dot(Quaternion a, Quaternion b) + { + return (a.x * b.x) + (a.y * b.y) + (a.z * b.z) + (a.w * b.w); + } + + Quaternion Quaternion::Euler(float _x, float _y, float _z) + { + return Convert::ToCLI(SHQuaternion::FromPitchYawRoll(_x, _y, _z)); + } + + Quaternion Quaternion::FromToRotation(Vector3 fromDirection, Vector3 toDirection) + { + return Convert::ToCLI(SHQuaternion::FromToRotation(Convert::ToNative(fromDirection), Convert::ToNative(toDirection))); + } + + Quaternion Quaternion::Inverse(Quaternion rotation) + { + return Convert::ToCLI(SHQuaternion::Inverse(Convert::ToNative(rotation))); + } + + Quaternion Quaternion::Lerp(Quaternion a, Quaternion b, float t) + { + return Convert::ToCLI(SHQuaternion::ClampedLerp(Convert::ToNative(a), Convert::ToNative(b), t)); + } + + Quaternion Quaternion::LerpUnclamped(Quaternion a, Quaternion b, float t) + { + return Convert::ToCLI(SHQuaternion::Lerp(Convert::ToNative(a), Convert::ToNative(b), t)); + } + + Quaternion Quaternion::LookRotation(Vector3 forward, Vector3 upwards) + { + return Convert::ToCLI(SHQuaternion::LookRotation(Convert::ToNative(forward), Convert::ToNative(upwards))); + } + + Quaternion Quaternion::Normalize(Quaternion q) + { + return Convert::ToCLI(SHQuaternion::Normalise(Convert::ToNative(q))); + } + + Quaternion Quaternion::RotateTowards(Quaternion from, Quaternion to, float maxDegreesDelta) + { + return Convert::ToCLI(SHQuaternion::RotateTowards(Convert::ToNative(from), Convert::ToNative(to), Math::DegreesToRadians(maxDegreesDelta))); + } + + Quaternion Quaternion::Slerp(Quaternion a, Quaternion b, float t) + { + return Convert::ToCLI(SHQuaternion::ClampedSlerp(Convert::ToNative(a), Convert::ToNative(b), t)); + } + + Quaternion Quaternion::SlerpUnclamped(Quaternion a, Quaternion b, float t) + { + return Convert::ToCLI(SHQuaternion::Slerp(Convert::ToNative(a), Convert::ToNative(b), t)); + } + + + Quaternion Quaternion::operator*(Quaternion lhs, Quaternion rhs) + { + return Convert::ToCLI(Convert::ToNative(lhs) * Convert::ToNative(rhs)); + } + + bool Quaternion::operator==(Quaternion lhs, Quaternion rhs) + { + return lhs.Equals(rhs); + } +} \ No newline at end of file diff --git a/SHADE_Managed/src/Math/Quaternion.hxx b/SHADE_Managed/src/Math/Quaternion.hxx new file mode 100644 index 00000000..783038c9 --- /dev/null +++ b/SHADE_Managed/src/Math/Quaternion.hxx @@ -0,0 +1,237 @@ +/************************************************************************************//*! +\file Quaternion.hxx +\author Diren D Bharwani, diren.dbharwani, 390002520 +\par email: diren.dbharwani\@digipen.edu +\date Oct 23, 2022 +\brief Contains the definitions of Quaternion struct. + + 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 +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ + +#pragma once + +// Standard Libraries +#include +// Project Includes +#include "Vector3.hxx" + +namespace SHADE +{ + /// + /// CLR version of SHADE's Quaternion class that represents an orientation. + /// Designed to closely match Unity's Quaternion struct. + /// + [System::Runtime::InteropServices::StructLayout(System::Runtime::InteropServices::LayoutKind::Sequential)] + public value struct Quaternion : public System::IEquatable + { + public: + /*-----------------------------------------------------------------------------*/ + /* Constants */ + /*-----------------------------------------------------------------------------*/ +#pragma region Constants + + /// + /// Shorthand for writing Quaternion(0, 0, 0, 1). + /// + static initonly Quaternion Identity = Quaternion(0.0f, 0.0f, 0.0f, 1.0f); + +#pragma endregion + + /*-----------------------------------------------------------------------------*/ + /* Public Members */ + /*-----------------------------------------------------------------------------*/ + + /// + /// X-component of the Quaternion. + /// Don't modify this directly unless you know quaternions inside out. + /// + float x; + /// + /// Y-component of the Quaternion. + /// Don't modify this directly unless you know quaternions inside out. + /// + float y; + /// + /// Z-component of the Quaternion. + /// Don't modify this directly unless you know quaternions inside out. + /// + float z; + /// + /// W-component of the Quaternion. Do not directly modify quaternions. + /// + float w; + + /*-----------------------------------------------------------------------------*/ + /* Constructors */ + /*-----------------------------------------------------------------------------*/ + + /// + /// Constructor to construct a Quaternion with the specified components. + /// + /// X-coordinate to set. + /// Y-coordinate to set. + /// Z-coordinate to set. + /// W-coordinate to set. + Quaternion(float _x, float _y, float _z, float _w); + + /*-----------------------------------------------------------------------------*/ + /* Usage Functions */ + /*-----------------------------------------------------------------------------*/ + + /// + /// Creates a rotation which rotates from fromDirection to toDirection.
+ /// Use this to create a rotation which starts at the first Vector (fromDirection) and rotates to the second Vector (toDirection). + /// These Vectors must be set up in a script. + ///
+ void SetFromToRotation(Vector3 fromDirection, Vector3 toDirection); + + /// + /// Creates a rotation with the specified forward and upwards directions.
+ /// The result is applied to this quaternion. + /// If used to orient a Transform, the Z axis will be aligned with forward and the Y axis with upwards, assuming these vectors are orthogonal. + /// Logs an error if the forward direction is zero. + ///
+ /// The direction to look in. + /// The vector that defines in which direction up is. + void SetLookRotation(Vector3 view, Vector3 up); + + /// + /// Converts a rotation to angle-axis representation (angles in degrees). + /// + void ToAngleAxis(float^% angle, Vector3^% axis); + + System::String^ ToString() override; + + /*-----------------------------------------------------------------------------*/ + /* IEquatable */ + /*-----------------------------------------------------------------------------*/ + + /// + /// Compares equality with an object of the same type. + /// + /// The object to compare with. + /// True if both objects are the same. + virtual bool Equals(Quaternion other); + + /*-----------------------------------------------------------------------------*/ + /* Object */ + /*-----------------------------------------------------------------------------*/ + + /// + /// Compares equality with another unboxed object. + /// + /// The unboxed object to compare with. + /// True if both objects are the same. + bool Equals(Object^ o) override; + + /// + /// Gets a unique hash for this object. + /// + /// Unique hash for this object. + int GetHashCode() override; + + /*-----------------------------------------------------------------------------*/ + /* Static Functions */ + /*-----------------------------------------------------------------------------*/ + + /// + /// Returns the angle in degrees between two rotations a and b.
+ ///
+ /// The angle in degrees between the two vectors. + static float Angle(Quaternion a, Quaternion b); + + /// + /// Creates a rotation which rotates angle degrees around axis. + /// + static Quaternion AngleAxis(float angle, Vector3 axis); + + /// + /// The dot product between two rotations. + /// + static float Dot(Quaternion a, Quaternion b); + + /// + /// Returns a rotation that rotates y degrees around the y axis, x degrees around the x axis, and z degrees around the z axis; applied in that order. + /// + static Quaternion Euler(float _x, float _y, float _z); + + /// + /// Creates a rotation which rotates from fromDirection to toDirection. + /// + static Quaternion FromToRotation(Vector3 fromDirection, Vector3 toDirection); + + /// + /// Returns the Inverse of rotation. + /// + static Quaternion Inverse(Quaternion rotation); + + /// + /// Interpolates between a and b by t and normalizes the result afterwards. The parameter t is clamped to the range [0, 1]. + /// + /// Start value, returned when t = 0. + /// End value, returned when t = 1. + /// Interpolation ratio. + /// A quaternion interpolated between quaternions a and b. + static Quaternion Lerp(Quaternion a, Quaternion b, float t); + + /// + /// Interpolates between a and b by t and normalizes the result afterwards. The parameter t is not clamped. + /// + static Quaternion LerpUnclamped(Quaternion a, Quaternion b, float t); + + /// + /// Creates a rotation with the specified forward and upwards directions.
+ /// Z axis will be aligned with forward, X axis aligned with cross product between forward and upwards, and Y axis aligned with cross product between Z and X. + ///
+ static Quaternion LookRotation(Vector3 forward, Vector3 upwards); + + /// + /// Converts this quaternion to one with the same orientation but with a magnitude of 1. + /// + static Quaternion Normalize(Quaternion q); + + /// + /// Rotates a rotation from towards to.
+ /// The from quaternion is rotated towards to by an angular step of maxDegreesDelta (but note that the rotation will not overshoot). + /// Negative values of maxDegreesDelta will move away from to until the rotation is exactly the opposite direction. + ///
+ static Quaternion RotateTowards(Quaternion from, Quaternion to, float maxDegreesDelta); + + /// + /// Spherically interpolates between quaternions a and b by ratio t. The parameter t is clamped to the range [0, 1]. + /// + /// Start value, returned when t = 0. + /// End value, returned when t = 1. + /// Interpolation ratio. + /// A quaternion spherically interpolated between quaternions a and b. + static Quaternion Slerp(Quaternion a, Quaternion b, float t); + + /// + /// Spherically interpolates between a and b by t. The parameter t is not clamped. + /// + static Quaternion SlerpUnclamped(Quaternion a, Quaternion b, float t); + + /*-----------------------------------------------------------------------------*/ + /* Overloaded Operators */ + /*-----------------------------------------------------------------------------*/ + + /// + /// Combines rotations lhs and rhs. + /// + /// Left-hand side quaternion. + /// Right-hand side quaternion. + static Quaternion operator*(Quaternion lhs, Quaternion rhs); + + /// + /// Are two quaternions equal to each other? + /// + /// Left-hand side quaternion. + /// Right-hand side quaternion. + static bool operator==(Quaternion lhs, Quaternion rhs); + }; + +} // namespace SHADE diff --git a/SHADE_Managed/src/Math/Vector2.cxx b/SHADE_Managed/src/Math/Vector2.cxx index d40e2323..b110d4f8 100644 --- a/SHADE_Managed/src/Math/Vector2.cxx +++ b/SHADE_Managed/src/Math/Vector2.cxx @@ -26,10 +26,10 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Constructors */ /*---------------------------------------------------------------------------------*/ - Vector2::Vector2(double _x) - : Vector2 { _x, 0.0 } + Vector2::Vector2(float _x) + : Vector2 { _x, 0.0f } {} - Vector2::Vector2(double _x, double _y) + Vector2::Vector2(float _x, float _y) : x { _x } , y { _y } {} @@ -47,22 +47,22 @@ namespace SHADE return *this / GetMagnitude(); } - double Vector2::GetMagnitude() + float Vector2::GetMagnitude() { return sqrt(x * x + y * y); } - double Vector2::GetSqrMagnitude() + float Vector2::GetSqrMagnitude() { return x * x + y * y; } - double Vector2::AngleFromRightRadians() + float Vector2::AngleFromRightRadians() { return atan2(y, x); } - double Vector2::AngleFromRightDegrees() + float Vector2::AngleFromRightDegrees() { return Math::RadiansToDegrees(AngleFromRightRadians()); } @@ -72,7 +72,7 @@ namespace SHADE return IsNearPoint(point, Math::Epsilon); } - bool Vector2::IsNearPoint(Vector2 point, double tolerance) + bool Vector2::IsNearPoint(Vector2 point, float tolerance) { return (*this - point).GetSqrMagnitude() < (tolerance * tolerance); } @@ -113,13 +113,13 @@ namespace SHADE { return IsNear(lhs, rhs, Math::Epsilon); } - bool Vector2::IsNear(Vector2 lhs, Vector2 rhs, double tolerance) + bool Vector2::IsNear(Vector2 lhs, Vector2 rhs, float tolerance) { return (std::abs(lhs.x) - std::abs(rhs.x)) < tolerance && (std::abs(lhs.y) - std::abs(rhs.y)) < tolerance; } - double Vector2::Dot(Vector2 lhs, Vector2 rhs) + float Vector2::Dot(Vector2 lhs, Vector2 rhs) { return lhs.x * rhs.x + lhs.y * rhs.y; } @@ -153,12 +153,12 @@ namespace SHADE } Vector2 Vector2::Reflect(Vector2 vec, Vector2 normal) { - return vec - (Project(vec, normal.GetNormalised()) * 2.0); + return vec - (Project(vec, normal.GetNormalised()) * 2.0f); } - Vector2 Vector2::RotateRadians(Vector2 vec, double radians) + Vector2 Vector2::RotateRadians(Vector2 vec, float radians) { - const double SINE = sin(radians); - const double COSINE = cos(radians); + const float SINE = sin(radians); + const float COSINE = cos(radians); return Vector2 ( @@ -166,35 +166,35 @@ namespace SHADE vec.x * SINE + vec.y * COSINE ); } - Vector2 Vector2::RotateDegrees(Vector2 vec, double degrees) + Vector2 Vector2::RotateDegrees(Vector2 vec, float degrees) { return RotateRadians(vec, Math::DegreesToRadians(degrees)); } Vector2 Vector2::Min(Vector2 lhs, Vector2 rhs) { - double lx = lhs.x, rx = rhs.x; - double ly = lhs.y, ry = rhs.y; + float lx = lhs.x, rx = rhs.x; + float ly = lhs.y, ry = rhs.y; return Vector2(std::min(lx, rx), std::min(ly, ry)); } Vector2 Vector2::Max(Vector2 lhs, Vector2 rhs) { - double lx = lhs.x, rx = rhs.x; - double ly = lhs.y, ry = rhs.y; + float lx = lhs.x, rx = rhs.x; + float ly = lhs.y, ry = rhs.y; return Vector2(std::max(lx, rx), std::max(ly, ry)); } - Vector2 Vector2::Lerp(Vector2 a, Vector2 b, double t) + Vector2 Vector2::Lerp(Vector2 a, Vector2 b, float t) { - return LerpUnclamped(a, b, std::clamp(t, 0.0, 1.0)); + return LerpUnclamped(a, b, std::clamp(t, 0.0f, 1.0f)); } - Vector2 Vector2::LerpUnclamped(Vector2 a, Vector2 b, double t) + Vector2 Vector2::LerpUnclamped(Vector2 a, Vector2 b, float t) { return a + ((b - a) * t); } - Vector2 Vector2::MoveTowards(Vector2 current, Vector2 target, double maxDistanceDelta) + Vector2 Vector2::MoveTowards(Vector2 current, Vector2 target, float maxDistanceDelta) { // Ignore if it is exactly on the same point if (current == target) @@ -206,7 +206,7 @@ namespace SHADE // Check if check if is behind or ahead of target Vector2 DIFF = target - newPos; - if (Dot(DELTA, DIFF) < 0.0) + if (Dot(DELTA, DIFF) < 0.0f) { newPos = target; } @@ -236,7 +236,7 @@ namespace SHADE lhs.y * rhs.y ); } - Vector2 Vector2::operator*(Vector2 lhs, double rhs) + Vector2 Vector2::operator*(Vector2 lhs, float rhs) { return Vector2 ( @@ -244,7 +244,7 @@ namespace SHADE lhs.y * rhs ); } - Vector2 Vector2::operator/(Vector2 lhs, double rhs) + Vector2 Vector2::operator/(Vector2 lhs, float rhs) { return Vector2 ( diff --git a/SHADE_Managed/src/Math/Vector2.hxx b/SHADE_Managed/src/Math/Vector2.hxx index 9253a703..94b1989f 100644 --- a/SHADE_Managed/src/Math/Vector2.hxx +++ b/SHADE_Managed/src/Math/Vector2.hxx @@ -19,8 +19,8 @@ of DigiPen Institute of Technology is prohibited. namespace SHADE { /// - /// CLR version of the the SHADE Engine's Vector2 class that represents a - /// 2-Dimensional Vector. Designed to closely match Unity's Vector2 struct. + /// CLR version of SHADE Engine's Vector2 class that represents a 2-Dimensional Vector. + /// Designed to closely match Unity's Vector2 struct. /// [System::Runtime::InteropServices::StructLayout(System::Runtime::InteropServices::LayoutKind::Sequential)] public value struct Vector2 : public System::IEquatable @@ -33,37 +33,37 @@ namespace SHADE /// /// Shorthand for writing Vector2(0, -1). /// - static initonly Vector2 Down = Vector2(0.0, -1.0); + static initonly Vector2 Down = Vector2(0.0f, -1.0f); /// /// Shorthand for writing Vector2(-1, 0). /// - static initonly Vector2 Left = Vector2(-1.0, 0.0); + static initonly Vector2 Left = Vector2(-1.0f, 0.0f); /// - /// Shorthand for writing Vector2(double.NegativeInfinity, - /// double.NegativeInfinity). + /// Shorthand for writing Vector2(float.NegativeInfinity, + /// float.NegativeInfinity). /// - static initonly Vector2 NegativeInfinity = Vector2(std::numeric_limits::lowest(), std::numeric_limits::lowest()); + static initonly Vector2 NegativeInfinity = Vector2(std::numeric_limits::lowest(), std::numeric_limits::lowest()); /// /// Shorthand for writing Vector2(1, 1). /// - static initonly Vector2 One = Vector2(1.0, 1.0); + static initonly Vector2 One = Vector2(1.0f, 1.0f); /// - /// Shorthand for writing Vector2(double.PositiveInfinity, - /// double.PositiveInfinity). + /// Shorthand for writing Vector2(float.PositiveInfinity, + /// float.PositiveInfinity). /// - static initonly Vector2 PositiveInfinity = Vector2(std::numeric_limits::max(), std::numeric_limits::max()); + static initonly Vector2 PositiveInfinity = Vector2(std::numeric_limits::max(), std::numeric_limits::max()); /// /// Shorthand for writing Vector2(1, 0). /// - static initonly Vector2 Right = Vector2(1.0, 0.0); + static initonly Vector2 Right = Vector2(1.0f, 0.0f); /// /// Shorthand for writing Vector2(0, 1). /// - static initonly Vector2 Up = Vector2(0.0, 1.0); + static initonly Vector2 Up = Vector2(0.0f, 1.0f); /// /// Shorthand for writing Vector2(0, 0). /// - static initonly Vector2 Zero = Vector2(0.0, 0.0); + static initonly Vector2 Zero = Vector2(0.0f, 0.0f); #pragma endregion /*-----------------------------------------------------------------------------*/ @@ -72,27 +72,27 @@ namespace SHADE /// /// X-component of the Vector2. /// - double x; + float x; /// /// Y-component of the Vector2. /// - double y; + float y; /*-----------------------------------------------------------------------------*/ /* Constructors */ /*-----------------------------------------------------------------------------*/ /// /// Constructor to construct a Vector2 with the specified components with the - /// Y-component set to 0.0. + /// Y-component set to 0.0f. /// /// X-coordinate to set. - Vector2(double _x); + Vector2(float _x); /// /// Constructor to construct a Vector2 with the specified components.. /// /// X-coordinate to set. /// Y-coordinate to set. - Vector2(double _x, double _y); + Vector2(float _x, float _y); /*-----------------------------------------------------------------------------*/ /* Usage Functions */ @@ -117,24 +117,24 @@ namespace SHADE /// need the precise magnitude, consider using GetSqrMagnitude() instead. /// /// Returns the length of this Vector2. - double GetMagnitude(); + float GetMagnitude(); /// /// Calculates and returns the squared magnitude of this Vector2. /// /// Returns the squared length of this Vector2. - double GetSqrMagnitude(); + float GetSqrMagnitude(); /// /// Calculates and returns the angle of this vector from the right vector. This /// function returns values between -Math.PI and Math.PI. /// /// Returns the angle of this vector from the right vector in radians. - double AngleFromRightRadians(); + float AngleFromRightRadians(); /// /// Calculates and returns the angle of this vector from the right vector. This - /// function returns values between -180.0 and 180.0. + /// function returns values between -180.0f and 180.0f. /// /// Returns the angle of this vector from the right vector in degrees. - double AngleFromRightDegrees(); + float AngleFromRightDegrees(); /// /// Checks if a specified point is near this Vector2 that represents a point with /// a tolerance value of PLS_EPSILON. @@ -156,7 +156,7 @@ namespace SHADE /// True if this Vector2 representing a point and the specified point are within /// the range of the specified tolerance. False otherwise. /// - bool IsNearPoint(Vector2 point, double tolerance); + bool IsNearPoint(Vector2 point, float tolerance); /*-----------------------------------------------------------------------------*/ /* IEquatable */ @@ -206,7 +206,7 @@ namespace SHADE /// /// True if the two Vector2s are within the tolerance value specified /// - static bool IsNear(Vector2 lhs, Vector2 rhs, double tolerance); + static bool IsNear(Vector2 lhs, Vector2 rhs, float tolerance); /// /// Computes and returns the dot product of 2 specified Vector2s. /// @@ -215,7 +215,7 @@ namespace SHADE /// /// Scalar value representing the dot product of the two Vector2s. /// - static double Dot(Vector2 lhs, Vector2 rhs); + static float Dot(Vector2 lhs, Vector2 rhs); /// /// Computes the inward perpendicular Vector2 to the specified Vector2. /// Equivalent to calling Perpendicular(lhs, true). This means, the @@ -260,7 +260,7 @@ namespace SHADE /// Angle to rotate the vector by in an anti-clockwise direction in radians. /// /// The Vector2 that represents the rotated vector. - static Vector2 RotateRadians(Vector2 vec, double radians); + static Vector2 RotateRadians(Vector2 vec, float radians); /// /// Rotates a Vector2 on the Z-axis by a specified angle in an anti-clockwise /// direction. @@ -270,7 +270,7 @@ namespace SHADE /// Angle to rotate the vector by in an anti-clockwise direction in degrees. /// /// The Vector2 that represents the rotated vector. - static Vector2 RotateDegrees(Vector2 vec, double degrees); + static Vector2 RotateDegrees(Vector2 vec, float degrees); /// /// Computes and returns a Vector2 that is made from the smallest components of /// the two specified Vector2s. @@ -298,25 +298,25 @@ namespace SHADE /// This is most commonly used to find a point some fraction of the way along a /// line between two endpoints. /// - /// The start Vector2, returned when t = 0.0. - /// The end Vector2, returned when t = 1.0. + /// The start Vector2, returned when t = 0.0f. + /// The end Vector2, returned when t = 1.0f. /// /// Value used to interpolate between a and b which is clamped to /// the range[0, 1]. /// /// The interpolated Vector2. - static Vector2 Lerp(Vector2 a, Vector2 b, double t); + static Vector2 Lerp(Vector2 a, Vector2 b, float t); /// /// Linearly interpolates between two specified points. /// This is most commonly used to find a point some fraction of the way along a /// line between two endpoints. /// Unlike Lerp(), t is not clamped to a range at all. /// - /// The start Vector2, returned when t = 0.0. - /// The end Vector2, returned when t = 1.0. + /// The start Vector2, returned when t = 0.0f. + /// The end Vector2, returned when t = 1.0f. /// Value used to interpolate between a and b. /// The interpolated Vector2. - static Vector2 LerpUnclamped(Vector2 a, Vector2 b, double t); + static Vector2 LerpUnclamped(Vector2 a, Vector2 b, float t); /// /// Moves a point current towards target. /// Similar to Lerp(), however, the function will ensure that the distance never @@ -327,7 +327,7 @@ namespace SHADE /// The target position to move to. /// Maximum distance moved per call. /// Vector representing the moved point. - static Vector2 MoveTowards(Vector2 current, Vector2 target, double maxDistanceDelta); + static Vector2 MoveTowards(Vector2 current, Vector2 target, float maxDistanceDelta); /*-----------------------------------------------------------------------------*/ /* Overloaded Operators */ @@ -361,7 +361,7 @@ namespace SHADE /// Vector2 to multiply with. /// Scalar to multiply with. /// The result of the scalar multiplication. - static Vector2 operator*(Vector2 lhs, double rhs); + static Vector2 operator*(Vector2 lhs, float rhs); /// /// Calculates the division of a Vector2 with a scalar value and returns /// the result. @@ -369,7 +369,7 @@ namespace SHADE /// Scalar to divide with. /// Vector2 to divide with. /// The result of the scalar division. - static Vector2 operator/(Vector2 lhs, double rhs); + static Vector2 operator/(Vector2 lhs, float rhs); /// /// Checks if two Vector2s are approximately equal. This is equivalent to /// calling Vector2.IsNear() with default tolerance values. diff --git a/SHADE_Managed/src/Math/Vector3.cxx b/SHADE_Managed/src/Math/Vector3.cxx index 26ff5a72..adbb4d3a 100644 --- a/SHADE_Managed/src/Math/Vector3.cxx +++ b/SHADE_Managed/src/Math/Vector3.cxx @@ -11,6 +11,7 @@ Copyright (C) 2021 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 @@ -26,13 +27,13 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Constructors */ /*---------------------------------------------------------------------------------*/ - Vector3::Vector3(double _x) - : Vector3 {_x, 0.0, 0.0} + Vector3::Vector3(float _x) + : Vector3 {_x, 0.0f, 0.0f} {} - Vector3::Vector3(double _x, double _y) - : Vector3 {_x, _y, 0.0} + Vector3::Vector3(float _x, float _y) + : Vector3 {_x, _y, 0.0f} {} - Vector3::Vector3(double _x, double _y, double _z) + Vector3::Vector3(float _x, float _y, float _z) : x { _x } , y { _y } , z { _z } @@ -54,22 +55,22 @@ namespace SHADE return *this / GetSqrMagnitude(); } - double Vector3::GetMagnitude() + float Vector3::GetMagnitude() { return sqrt(x * x + y * y + z * z); } - double Vector3::GetSqrMagnitude() + float Vector3::GetSqrMagnitude() { return x * x + y * y + z * z; } - double Vector3::Angle2DFromRightRadians() + float Vector3::Angle2DFromRightRadians() { return atan2(y, x); } - double Vector3::Angle2DFromRightDegrees() + float Vector3::Angle2DFromRightDegrees() { return Math::RadiansToDegrees(Angle2DFromRightRadians()); } @@ -79,7 +80,7 @@ namespace SHADE return IsNearPoint(point, Math::Epsilon); } - bool Vector3::IsNearPoint(Vector3 point, double tolerance) + bool Vector3::IsNearPoint(Vector3 point, float tolerance) { return (*this - point).GetSqrMagnitude() < (tolerance * tolerance); } @@ -121,7 +122,7 @@ namespace SHADE { return IsNear(lhs, rhs, Math::Epsilon); } - bool Vector3::IsNear(Vector3 lhs, Vector3 rhs, double tolerance) + bool Vector3::IsNear(Vector3 lhs, Vector3 rhs, float tolerance) { return (std::abs(lhs.x) - std::abs(rhs.x)) < tolerance && @@ -129,7 +130,7 @@ namespace SHADE && (std::abs(lhs.z) - std::abs(rhs.z)) < tolerance; } - double Vector3::Dot(Vector3 lhs, Vector3 rhs) + float Vector3::Dot(Vector3 lhs, Vector3 rhs) { return lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z; } @@ -145,12 +146,12 @@ namespace SHADE } Vector3 Vector3::Reflect(Vector3 vec, Vector3 normal) { - return vec - (Project(vec, normal.GetNormalised()) * 2.0); + return vec - (Project(vec, normal.GetNormalised()) * 2.0f); } - Vector3 Vector3::RotateRadians(Vector3 vec, double radians) + Vector3 Vector3::RotateRadians(Vector3 vec, float radians) { - const double SINE = sin(radians); - const double COSINE = cos(radians); + const float SINE = sin(radians); + const float COSINE = cos(radians); return Vector3 ( @@ -159,15 +160,15 @@ namespace SHADE vec.z ); } - Vector3 Vector3::RotateDegrees(Vector3 vec, double degrees) + Vector3 Vector3::RotateDegrees(Vector3 vec, float degrees) { return RotateRadians(vec, Math::DegreesToRadians(degrees)); } Vector3 Vector3::Min(Vector3 lhs, Vector3 rhs) { - double lx = lhs.x, rx = rhs.x; - double ly = lhs.y, ry = rhs.y; - double lz = lhs.z, rz = rhs.z; + float lx = lhs.x, rx = rhs.x; + float ly = lhs.y, ry = rhs.y; + float lz = lhs.z, rz = rhs.z; return Vector3(std::min(lx, rx), std::min(ly, ry), @@ -175,23 +176,23 @@ namespace SHADE } Vector3 Vector3::Max(Vector3 lhs, Vector3 rhs) { - double lx = lhs.x, rx = rhs.x; - double ly = lhs.y, ry = rhs.y; - double lz = lhs.z, rz = rhs.z; + float lx = lhs.x, rx = rhs.x; + float ly = lhs.y, ry = rhs.y; + float lz = lhs.z, rz = rhs.z; return Vector3(std::max(lx, rx), std::max(ly, ry), std::max(lz, rz)); } - Vector3 Vector3::Lerp(Vector3 a, Vector3 b, double t) + Vector3 Vector3::Lerp(Vector3 a, Vector3 b, float t) { - return LerpUnclamped(a, b, std::clamp(t, 0.0, 1.0)); + return LerpUnclamped(a, b, std::clamp(t, 0.0f, 1.0f)); } - Vector3 Vector3::LerpUnclamped(Vector3 a, Vector3 b, double t) + Vector3 Vector3::LerpUnclamped(Vector3 a, Vector3 b, float t) { return a + ((b - a) * t); } - Vector3 Vector3::MoveTowards(Vector3 current, Vector3 target, double maxDistanceDelta) + Vector3 Vector3::MoveTowards(Vector3 current, Vector3 target, float maxDistanceDelta) { // Ignore if it is exactly on the same point if (current == target) @@ -203,7 +204,7 @@ namespace SHADE // Check if check if is behind or ahead of target Vector3 DIFF = target - newPos; - if (Dot(DELTA, DIFF) < 0.0) + if (Dot(DELTA, DIFF) < 0.0f) { newPos = target; } @@ -236,7 +237,7 @@ namespace SHADE lhs.z * rhs.z ); } - Vector3 Vector3::operator*(Vector3 lhs, double rhs) + Vector3 Vector3::operator*(Vector3 lhs, float rhs) { return Vector3 ( @@ -245,7 +246,7 @@ namespace SHADE lhs.z * rhs ); } - Vector3 Vector3::operator/(Vector3 lhs, double rhs) + Vector3 Vector3::operator/(Vector3 lhs, float rhs) { return Vector3 ( diff --git a/SHADE_Managed/src/Math/Vector3.hxx b/SHADE_Managed/src/Math/Vector3.hxx index 8b66439c..70cff88f 100644 --- a/SHADE_Managed/src/Math/Vector3.hxx +++ b/SHADE_Managed/src/Math/Vector3.hxx @@ -22,8 +22,8 @@ of DigiPen Institute of Technology is prohibited. namespace SHADE { /// - /// CLR version of the the PlushieEngine's Vector3 class that represents a - /// 3-Dimensional Vector. Designed to closely match Unity's Vector3 struct. + /// CLR version of SHADE Engine's Vector3 class that represents a 3-Dimensional Vector. + /// Designed to closely match Unity's Vector3 struct. /// [System::Runtime::InteropServices::StructLayout(System::Runtime::InteropServices::LayoutKind::Sequential)] public value struct Vector3 : public System::IEquatable @@ -36,49 +36,49 @@ namespace SHADE /// /// Shorthand for writing Vector3(0, 0, -1). /// - static initonly Vector3 Back = Vector3(0.0, 0.0, -1.0); + static initonly Vector3 Back = Vector3(0.0f, 0.0f, -1.0f); /// /// Shorthand for writing Vector3(0, -1, 0). /// - static initonly Vector3 Down = Vector3(0.0, -1.0, 0.0); + static initonly Vector3 Down = Vector3(0.0f, -1.0f, 0.0f); /// /// Shorthand for writing Vector3(0, 0, 1). /// - static initonly Vector3 Forward = Vector3(0.0, 0.0, 1.0); + static initonly Vector3 Forward = Vector3(0.0f, 0.0f, 1.0f); /// /// Shorthand for writing Vector3(-1, 0, 0). /// - static initonly Vector3 Left = Vector3(-1.0, 0.0, 0.0); + static initonly Vector3 Left = Vector3(-1.0f, 0.0f, 0.0f); /// - /// Shorthand for writing Vector3(double.NegativeInfinity, - /// double.NegativeInfinity, double.NegativeInfinity). + /// Shorthand for writing Vector3(float.NegativeInfinity, + /// float.NegativeInfinity, float.NegativeInfinity). /// - static initonly Vector3 NegativeInfinity = Vector3(std::numeric_limits::lowest(), - std::numeric_limits::lowest(), - std::numeric_limits::lowest()); + static initonly Vector3 NegativeInfinity = Vector3(std::numeric_limits::lowest(), + std::numeric_limits::lowest(), + std::numeric_limits::lowest()); /// /// Shorthand for writing Vector3(1, 1, 1). /// - static initonly Vector3 One = Vector3(1.0, 1.0, 1.0); + static initonly Vector3 One = Vector3(1.0f, 1.0f, 1.0f); /// - /// Shorthand for writing Vector3(double.PositiveInfinity, - /// double.PositiveInfinity, double.PositiveInfinity). + /// Shorthand for writing Vector3(float.PositiveInfinity, + /// float.PositiveInfinity, float.PositiveInfinity). /// - static initonly Vector3 PositiveInfinity = Vector3(std::numeric_limits::max(), - std::numeric_limits::max(), - std::numeric_limits::max()); + static initonly Vector3 PositiveInfinity = Vector3(std::numeric_limits::max(), + std::numeric_limits::max(), + std::numeric_limits::max()); /// /// Shorthand for writing Vector3(1, 0, 0). /// - static initonly Vector3 Right = Vector3(1.0, 0.0, 0.0); + static initonly Vector3 Right = Vector3(1.0f, 0.0f, 0.0f); /// /// Shorthand for writing Vector3(0, 1, 0). /// - static initonly Vector3 Up = Vector3(0.0, 1.0, 0.0); + static initonly Vector3 Up = Vector3(0.0f, 1.0f, 0.0f); /// /// Shorthand for writing Vector3(0, 0, 0). /// - static initonly Vector3 Zero = Vector3(0.0, 0.0, 0.0); + static initonly Vector3 Zero = Vector3(0.0f, 0.0f, 0.0f); #pragma endregion /*-----------------------------------------------------------------------------*/ @@ -87,39 +87,39 @@ namespace SHADE /// /// X-component of the Vector3. /// - double x; + float x; /// /// Y-component of the Vector3. /// - double y; + float y; /// /// Z-component of the Vector3. /// - double z; + float z; /*-----------------------------------------------------------------------------*/ /* Constructors */ /*-----------------------------------------------------------------------------*/ /// /// Constructor to construct a Vector3 with the specified components with the - /// Y and Z-component set to 0.0. + /// Y and Z-component set to 0.0f. /// /// X-coordinate to set. - Vector3(double _x); + Vector3(float _x); /// /// Constructor to construct a Vector3 with the specified components with the - /// Z-component set to 0.0. + /// Z-component set to 0.0f. /// /// X-coordinate to set. /// Y-coordinate to set. - Vector3(double _x, double _y); + Vector3(float _x, float _y); /// /// Constructor to construct a Vector3 with the specified components. /// /// X-coordinate to set. /// Y-coordinate to set. /// Z-coordinate to set. - Vector3(double _x, double _y, double _z); + Vector3(float _x, float _y, float _z); /// /// Conversion constructor to construct a Vector3 using a Vector2. /// @@ -149,24 +149,24 @@ namespace SHADE /// need the precise magnitude, consider using GetSqrMagnitude() instead. /// /// Returns the length of this Vector3. - double GetMagnitude(); + float GetMagnitude(); /// /// Calculates and returns the squared magnitude of this Vector3. /// /// Returns the squared length of this Vector3. - double GetSqrMagnitude(); + float GetSqrMagnitude(); /// /// Calculates and returns the angle of this vector from the right vector. This /// function returns values between -Math.PI and Math.PI. /// /// Returns the angle of this vector from the right vector in radians. - double Angle2DFromRightRadians(); + float Angle2DFromRightRadians(); /// /// Calculates and returns the angle of this vector from the right vector. This - /// function returns values between -180.0 and 180.0. + /// function returns values between -180.0f and 180.0f. /// /// Returns the angle of this vector from the right vector in degrees. - double Angle2DFromRightDegrees(); + float Angle2DFromRightDegrees(); /// /// Checks if a specified point is near this Vector3 that represents a point with /// a tolerance value of PLS_EPSILON. @@ -188,7 +188,7 @@ namespace SHADE /// True if this Vector3 representing a point and the specified point are within /// the range of the specified tolerance. False otherwise. /// - bool IsNearPoint(Vector3 point, double tolerance); + bool IsNearPoint(Vector3 point, float tolerance); /*-----------------------------------------------------------------------------*/ /* IEquatable */ @@ -208,12 +208,12 @@ namespace SHADE /// /// The unboxed object to compare with. /// True if both objects are the same. - bool Equals(Object^ o) override; + bool Equals(Object^ o) override; /// /// Gets a unique hash for this object. /// /// Unique hash for this object. - int GetHashCode() override; + int GetHashCode() override; /*-----------------------------------------------------------------------------*/ /* Static Functions */ @@ -236,14 +236,14 @@ namespace SHADE /// /// True if the two Vector3s are within the tolerance value specified /// - static bool IsNear(Vector3 lhs, Vector3 rhs, double tolerance); + static bool IsNear(Vector3 lhs, Vector3 rhs, float tolerance); /// /// Computes and returns the dot product of 2 specified Vector3s. /// /// Vector3 to calculate dot product with. /// Another Vector3 to calculate dot product with. /// Scalar value representing the dot product of the two Vector3s. - static double Dot(Vector3 lhs, Vector3 rhs); + static float Dot(Vector3 lhs, Vector3 rhs); /// /// Computes and returns the cross product of 2 specified Vector3s. /// @@ -274,7 +274,7 @@ namespace SHADE /// Angle to rotate the vector by in an anti-clockwise direction in radians. /// /// The Vector3 that represents the rotated vector. - static Vector3 RotateRadians(Vector3 vec, double radians); + static Vector3 RotateRadians(Vector3 vec, float radians); /// /// Rotates a Vector3 on the Z-axis by a specified angle in an anti-clockwise /// direction. @@ -284,7 +284,7 @@ namespace SHADE /// Angle to rotate the vector by in an anti-clockwise direction in degrees. /// /// The Vector3 that represents the rotated vector. - static Vector3 RotateDegrees(Vector3 vec, double degrees); + static Vector3 RotateDegrees(Vector3 vec, float degrees); /// /// Computes and returns a Vector3 that is made from the smallest components of /// the two specified Vector3s. @@ -312,25 +312,25 @@ namespace SHADE /// This is most commonly used to find a point some fraction of the way along a /// line between two endpoints. /// - /// The start Vector3, returned when t = 0.0. - /// The end Vector3, returned when t = 1.0. + /// The start Vector3, returned when t = 0.0f. + /// The end Vector3, returned when t = 1.0f. /// /// Value used to interpolate between a and b which is clamped to /// the range[0, 1]. /// /// The interpolated Vector3. - static Vector3 Lerp(Vector3 a, Vector3 b, double t); + static Vector3 Lerp(Vector3 a, Vector3 b, float t); /// /// Linearly interpolates between two specified points. /// This is most commonly used to find a point some fraction of the way along a /// line between two endpoints. /// Unlike Lerp(), t is not clamped to a range at all. /// - /// The start Vector3, returned when t = 0.0. - /// The end Vector3, returned when t = 1.0. + /// The start Vector3, returned when t = 0.0f. + /// The end Vector3, returned when t = 1.0f. /// Value used to interpolate between a and b. /// The interpolated Vector3. - static Vector3 LerpUnclamped(Vector3 a, Vector3 b, double t); + static Vector3 LerpUnclamped(Vector3 a, Vector3 b, float t); /// /// Moves a point current towards target. /// Similar to Lerp(), however, the function will ensure that the distance never @@ -341,7 +341,7 @@ namespace SHADE /// The target position to move to. /// Maximum distance moved per call. /// Vector representing the moved point. - static Vector3 MoveTowards(Vector3 current, Vector3 target, double maxDistanceDelta); + static Vector3 MoveTowards(Vector3 current, Vector3 target, float maxDistanceDelta); /*-----------------------------------------------------------------------------*/ /* Overloaded Operators */ @@ -375,7 +375,7 @@ namespace SHADE /// Vector3 to multiply with. /// Scalar to multiply with. /// The result of the scalar multiplication. - static Vector3 operator*(Vector3 lhs, double rhs); + static Vector3 operator*(Vector3 lhs, float rhs); /// /// Calculates the division of a Vector3 with a scalar value and returns /// the result. @@ -383,7 +383,7 @@ namespace SHADE /// Scalar to divide with. /// Vector3 to divide with. /// The result of the scalar division. - static Vector3 operator/(Vector3 lhs, double rhs); + static Vector3 operator/(Vector3 lhs, float rhs); /// /// Checks if two Vector3s are approximately equal. This is equivalent to /// calling Vector3.IsNear() with default tolerance values. diff --git a/SHADE_Managed/src/Utility/Convert.cxx b/SHADE_Managed/src/Utility/Convert.cxx index 661eb3e4..4646194b 100644 --- a/SHADE_Managed/src/Utility/Convert.cxx +++ b/SHADE_Managed/src/Utility/Convert.cxx @@ -35,10 +35,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ SHVec3 Convert::ToNative(Vector3 vec) { - const double X = vec.x; - const double Y = vec.y; - const double Z = vec.z; - return SHVec3(X, Y, Z); + return SHVec3(vec.x, vec.y, vec.z); } Vector3 Convert::ToCLI(const SHVec3& vec) { @@ -46,9 +43,7 @@ namespace SHADE } SHVec2 Convert::ToNative(Vector2 vec) { - const double X = vec.x; - const double Y = vec.y; - return SHVec2(X, Y); + return SHVec2(vec.x, vec.y); } Vector2 Convert::ToCLI(const SHVec2& vec) @@ -56,6 +51,16 @@ namespace SHADE return Vector2(vec.x, vec.y); } + SHQuaternion Convert::ToNative(Quaternion quat) + { + return SHQuaternion{ quat.x, quat.y, quat.z, quat.w }; + } + + Quaternion Convert::ToCLI(const SHQuaternion& quat) + { + return Quaternion{ quat.x, quat.y, quat.z, quat.w }; + } + /*---------------------------------------------------------------------------------*/ /* String Conversions */ /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Managed/src/Utility/Convert.hxx b/SHADE_Managed/src/Utility/Convert.hxx index f04cbf4b..d694ca6a 100644 --- a/SHADE_Managed/src/Utility/Convert.hxx +++ b/SHADE_Managed/src/Utility/Convert.hxx @@ -18,10 +18,12 @@ of DigiPen Institute of Technology is prohibited. #include "ECS_Base/Entity/SHEntity.h" #include "Math/Vector/SHVec2.h" #include "Math/Vector/SHVec3.h" +#include "Math/SHQuaternion.h" // Project Includes #include "Engine/Entity.hxx" #include "Math/Vector2.hxx" #include "Math/Vector3.hxx" +#include "Math/Quaternion.hxx" namespace SHADE { @@ -74,6 +76,18 @@ namespace SHADE /// The native Vector2 to convert from. /// Managed copy of a native Vector2. static Vector2 ToCLI(const SHVec2& vec); + /// + /// Converts from a managed Quaternion to a native Quaternion. + /// + /// The managed Quaternion to convert from. + /// Native copy of a managed Quaternion. + static SHQuaternion ToNative(Quaternion quat); + /// + /// Converts from a native Quaternion to a managed Quaternion. + /// + /// The native Quaternion to convert from. + /// Managed copy of a native Quaternion. + static Quaternion ToCLI(const SHQuaternion& quat); /*-----------------------------------------------------------------------------*/ /* String Conversions */ From 26eb4ad18cf98d7d9b8f8b7806a52e97ce2f8c97 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Mon, 24 Oct 2022 16:18:18 +0800 Subject: [PATCH 25/50] Fix command registrations and mouse pick polling when using transform gizmo --- Assets/Editor/Layouts/UserLayout.ini | 54 ----- .../src/Application/SBApplication.cpp | 10 +- .../HierarchyPanel/SHHierarchyPanel.cpp | 2 +- .../Inspector/SHEditorComponentView.hpp | 4 + .../ViewportWindow/SHEditorViewport.cpp | 2 +- .../src/Editor/Gizmos/SHTransformGizmo.cpp | 65 +++--- .../src/Editor/Gizmos/SHTransformGizmo.h | 6 + SHADE_Engine/src/Editor/SHEditor.cpp | 2 +- SHADE_Engine/src/Editor/SHEditorWidgets.hpp | 191 +++++++++--------- 9 files changed, 151 insertions(+), 185 deletions(-) delete mode 100644 Assets/Editor/Layouts/UserLayout.ini diff --git a/Assets/Editor/Layouts/UserLayout.ini b/Assets/Editor/Layouts/UserLayout.ini deleted file mode 100644 index baced6b8..00000000 --- a/Assets/Editor/Layouts/UserLayout.ini +++ /dev/null @@ -1,54 +0,0 @@ -[Window][MainStatusBar] -Pos=0,1060 -Size=1920,20 -Collapsed=0 - -[Window][SHEditorMenuBar] -Pos=0,48 -Size=1920,1012 -Collapsed=0 - -[Window][Hierarchy Panel] -Pos=0,142 -Size=387,918 -Collapsed=0 -DockId=0x00000004,0 - -[Window][Debug##Default] -Pos=60,60 -Size=400,400 -Collapsed=0 - -[Window][Inspector] -Pos=1649,48 -Size=271,1012 -Collapsed=0 -DockId=0x00000006,0 - -[Window][Profiler] -Pos=0,48 -Size=387,92 -Collapsed=0 -DockId=0x00000003,0 - -[Window][Viewport] -Pos=648,48 -Size=2519,1319 -Collapsed=0 -DockId=0x00000002,0 - -[Window][ Viewport] -Pos=389,48 -Size=1258,1012 -Collapsed=0 -DockId=0x00000002,0 - -[Docking][Data] -DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,79 Size=1920,1012 Split=X - DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1992,1036 Split=X - DockNode ID=0x00000001 Parent=0x00000005 SizeRef=387,1036 Split=Y Selected=0x1E6EB881 - DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,94 Selected=0x1E6EB881 - DockNode ID=0x00000004 Parent=0x00000001 SizeRef=225,940 Selected=0xE096E5AE - DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1258,1036 CentralNode=1 Selected=0xB41284E7 - DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=271,1036 Selected=0xE7039252 - diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index a93148d5..54dc0ccf 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -56,8 +56,8 @@ namespace Sandbox _In_ INT nCmdShow ) { - // Set working directory - SHFileUtilities::SetWorkDirToExecDir(); + // Set working directory + SHFileUtilities::SetWorkDirToExecDir(); window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow); @@ -152,16 +152,16 @@ namespace Sandbox SHSceneManager::SceneUpdate(0.016f); #endif SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, 0.016f); - //editor->PollPicking(); + editor->PollPicking(); } // Finish all graphics jobs first - graphicsSystem->AwaitGraphicsExecution(); + graphicsSystem->AwaitGraphicsExecution(); } void SBApplication::Exit(void) { - #ifdef SHEDITOR + #ifdef SHEDITOR SDL_DestroyWindow(sdlWindow); SDL_Quit(); #endif diff --git a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp index 27e46d98..972d4ae3 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp @@ -94,7 +94,7 @@ namespace SHADE if (ImGui::BeginMenuBar()) { - ImGui::SetCursorPosX(ImGui::GetContentRegionAvail().x - 35.0f); + ImGui::SetCursorPosX(ImGui::GetContentRegionAvail().x - 40.0f); if(ImGui::SmallButton(ICON_MD_DESELECT)) { auto editor = SHSystemManager::GetSystem(); diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index 08f5695b..0bbbe0dd 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -39,6 +39,10 @@ namespace SHADE { SHComponentManager::RemoveComponent(component->GetEID()); } + if (ImGui::Selectable(std::format("{} Reset {}", ICON_MD_RESTART_ALT, componentName.data()).data())) + { + *component = T(); + } ImGui::EndPopup(); } } diff --git a/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp index b06c37c7..cb30fa81 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp @@ -24,7 +24,7 @@ namespace SHADE void SHEditorViewport::Init() { SHEditorWindow::Init(); - + transformGizmo.Init(); } void SHEditorViewport::Update() diff --git a/SHADE_Engine/src/Editor/Gizmos/SHTransformGizmo.cpp b/SHADE_Engine/src/Editor/Gizmos/SHTransformGizmo.cpp index a53b8c10..3c984051 100644 --- a/SHADE_Engine/src/Editor/Gizmos/SHTransformGizmo.cpp +++ b/SHADE_Engine/src/Editor/Gizmos/SHTransformGizmo.cpp @@ -13,6 +13,12 @@ #include "Editor/EditorWindow/ViewportWindow/SHEditorViewport.h" namespace SHADE { + void SHTransformGizmo::Init() + { + auto& style = ImGuizmo::GetStyle(); + style.RotationLineThickness = 2.5f; + } + void SHTransformGizmo::Draw() { bool justChangedTfm = false; @@ -26,9 +32,12 @@ namespace SHADE SHMatrix view = SHMatrix::Transpose(editorCamera->GetViewMatrix()); SHMatrix proj = SHMatrix::Transpose(editorCamera->GetProjMatrix()); + + //Invert projection y-axis proj(1, 1) *= -1; + static SHMatrix gridMat = SHMatrix::Translate(0, -0.5f, 0.f) * SHMatrix::Identity; - //ImGuizmo::DrawGrid(&view._11, &proj._11, &gridMat._11, 100.f); + if (selectedEntityTransformComponent == nullptr) { SHEditor* editor = SHSystemManager::GetSystem(); @@ -55,31 +64,37 @@ namespace SHADE return; SHMatrix mat = selectedEntityTransformComponent->GetTRS(); - isManipulating = ImGuizmo::Manipulate(&view._11, &proj._11, static_cast(operation), ImGuizmo::MODE::WORLD, &mat._11); - if (!justChangedTfm) + useSnap = ImGui::IsKeyDown(ImGuiKey_LeftCtrl); + if(useSnap) { - if (ImGui::IsItemClicked()) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(selectedEntityTransformComponent->GetTRS(), mat, [tfm = std::move(selectedEntityTransformComponent)](SHMatrix const& mtx) - { - if (!tfm) - return; - SHVec3 translate{}, rotate{}, scale{}; - mtx.Decompose(translate, rotate, scale); - tfm->SetWorldPosition(translate); - tfm->SetWorldRotation(rotate); - tfm->SetWorldScale(scale); - }))); - else if (ImGui::IsItemHovered(ImGuiMouseButton_Left) && ImGui::IsMouseDown(ImGuiMouseButton_Left) && isManipulating) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(selectedEntityTransformComponent->GetTRS(), mat, [tfm = std::move(selectedEntityTransformComponent)](SHMatrix const& mtx) - { - if (!tfm) - return; - SHVec3 translate{}, rotate{}, scale{}; - mtx.Decompose(translate, rotate, scale); - tfm->SetWorldPosition(translate); - tfm->SetWorldRotation(rotate); - tfm->SetWorldScale(scale); - })), true); + switch (operation) + { + case Operation::TRANSLATE: snap = &translationSnap.x; break; + case Operation::ROTATE: snap = &rotationSnap; break; + case Operation::SCALE: snap = &scaleSnap; break; + default: snap = &translationSnap.x; + } } + ImGuizmo::Manipulate(&view._11, &proj._11, static_cast(operation), ImGuizmo::MODE::WORLD, &mat._11, nullptr, useSnap ? snap : nullptr); + static bool startRecording = false; + if (!justChangedTfm && ImGuizmo::IsUsing()) + { + + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(selectedEntityTransformComponent->GetTRS(), mat, [tfm = (selectedEntityTransformComponent)](SHMatrix const& mtx) + { + if (!tfm) + return; + SHVec3 translate{}, rotate{}, scale{}; + mtx.Decompose(translate, rotate, scale); + tfm->SetWorldPosition(translate); + tfm->SetWorldRotation(rotate); + tfm->SetWorldScale(scale); + })), startRecording); + if(!startRecording) + startRecording = true; + } + isManipulating = ImGuizmo::IsUsing() || startRecording; + if(startRecording && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) + startRecording = false; } } diff --git a/SHADE_Engine/src/Editor/Gizmos/SHTransformGizmo.h b/SHADE_Engine/src/Editor/Gizmos/SHTransformGizmo.h index 2565575f..fd847335 100644 --- a/SHADE_Engine/src/Editor/Gizmos/SHTransformGizmo.h +++ b/SHADE_Engine/src/Editor/Gizmos/SHTransformGizmo.h @@ -37,11 +37,17 @@ namespace SHADE UNIVERSAL = TRANSLATE | ROTATE | SCALEU }; + void Init(); void Draw(); bool isManipulating = false; + bool useSnap = false; Mode mode = Mode::WORLD; Operation operation = Operation::TRANSLATE; private: + float scaleSnap = 0.25f; + float rotationSnap = 1.0f; + SHVec3 translationSnap = SHVec3(0.25f, 0.25f, 0.25f); + float* snap = nullptr; SHTransformComponent* selectedEntityTransformComponent{nullptr}; SHCameraComponent* editorCamera{nullptr}; }; diff --git a/SHADE_Engine/src/Editor/SHEditor.cpp b/SHADE_Engine/src/Editor/SHEditor.cpp index aff1eaad..912f9d0f 100644 --- a/SHADE_Engine/src/Editor/SHEditor.cpp +++ b/SHADE_Engine/src/Editor/SHEditor.cpp @@ -134,7 +134,7 @@ namespace SHADE } } - PollPicking(); + //PollPicking(); if(ImGui::IsKeyDown(ImGuiKey_LeftShift) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_Z)) { diff --git a/SHADE_Engine/src/Editor/SHEditorWidgets.hpp b/SHADE_Engine/src/Editor/SHEditorWidgets.hpp index 5788dc15..dc65d6c2 100644 --- a/SHADE_Engine/src/Editor/SHEditorWidgets.hpp +++ b/SHADE_Engine/src/Editor/SHEditorWidgets.hpp @@ -40,7 +40,6 @@ namespace SHADE { ImGui::BeginGroup(); - auto cursorPos = ImGui::GetCursorScreenPos(); auto itemSpacing = ImGui::GetStyle().ItemSpacing; ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f)); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f)); @@ -175,7 +174,7 @@ namespace SHADE ImGui::SetColumnWidth(-1, 80.0f); ImGui::Text(fieldLabel.c_str()); if (isHovered) - *isHovered = ImGui::IsItemHovered(); + *isHovered = ImGui::IsItemHovered(); ImGui::NextColumn(); for (std::size_t i = 0; i < N; ++i) { @@ -208,21 +207,16 @@ namespace SHADE ImGuiSliderFlags flags = 0) { SHVec2 values = get(); - bool changed = false; - if (DragN(fieldLabel, componentLabels, { &values.x, &values.y }, speed, displayFormat, valueMin, valueMax, flags)) - { - changed = true; - } - + bool const changed = DragN(fieldLabel, componentLabels, { &values.x, &values.y }, speed, displayFormat, valueMin, valueMax, flags); + static bool startRecording = false; if (changed) { - if (ImGui::IsMouseClicked(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); - else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), true); - else if (ImGui::IsItemDeactivatedAfterEdit()) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), startRecording); + if (!startRecording) + startRecording = true; } + if (startRecording && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) + startRecording = false; return changed; } @@ -232,20 +226,20 @@ namespace SHADE ImGuiSliderFlags flags = 0) { SHVec3 values = get(); - bool changed = false; - if (DragN(fieldLabel, componentLabels, { &values.x, &values.y, &values.z }, speed, displayFormat, valueMin, valueMax, flags)) - { - changed = true; - } + bool const changed = DragN(fieldLabel, componentLabels, { &values.x, &values.y, &values.z }, speed, displayFormat, valueMin, valueMax, flags); + + static bool startRecording = false; if (changed) { - if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); - else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), true); - else if (ImGui::IsItemDeactivatedAfterEdit()) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); + SHVec3 old = get(); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(old, values, set)), startRecording); + if (!startRecording) + startRecording = true; + } + if (startRecording && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) + { + startRecording = false; } return changed; @@ -256,20 +250,17 @@ namespace SHADE ImGuiSliderFlags flags = 0) { SHVec4 values = get(); - bool changed = false; - if (DragN(fieldLabel, componentLabels, { &values.x, &values.y, &values.z, &values.w }, speed, displayFormat, valueMin, valueMax, flags)) - { - changed = true; - } - + bool const changed = DragN(fieldLabel, componentLabels, { &values.x, &values.y, &values.z, &values.w }, speed, displayFormat, valueMin, valueMax, flags); + static bool startRecording = false; if (changed) { - if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); - else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), true); - else if (ImGui::IsItemDeactivatedAfterEdit()) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), startRecording); + if (!startRecording) + startRecording = true; + } + if (startRecording && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) + { + startRecording = false; } return changed; @@ -325,112 +316,116 @@ namespace SHADE float speed = 1.0f, T p_min = T(), T p_max = T(), const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0) { T value = get(); - std::cout << value << " \n"; - //bool hasChange = ImGui::DragScalar(fieldLabel.c_str(), data_type, &value, speed, &p_min, &p_max, displayFormat, flags); - - if (ImGui::DragScalar(fieldLabel.c_str(), data_type, &value, speed, &p_min, &p_max, displayFormat, flags)) + const bool hasChange = ImGui::DragScalar(fieldLabel.c_str(), data_type, &value, speed, &p_min, &p_max, displayFormat, flags); + static bool startRecording = false; + if (hasChange) { - if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); - else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); - else if (ImGui::IsItemDeactivatedAfterEdit()) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); - - return true; + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), startRecording); + if (!startRecording) + startRecording = true; } - return false; + if (startRecording && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) + { + startRecording = false; + } + return hasChange; } static bool DragFloat(const std::string& fieldLabel, std::function get, std::function set, float speed = 0.1f, float p_min = float(), float p_max = float(), const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0) { float value = get(); - //bool hasChange = ImGui::DragFloat(fieldLabel.c_str(), &value, speed, p_min, p_max, displayFormat, flags); - if (ImGui::DragFloat(fieldLabel.c_str(), &value, speed, p_min, p_max, displayFormat, flags)) + const bool hasChange = ImGui::DragFloat(fieldLabel.c_str(), &value, speed, p_min, p_max, displayFormat, flags); + static bool startRecording = false; + if (hasChange) { - if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); - else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); - else if (ImGui::IsItemDeactivatedAfterEdit()) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); - - return true; + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), startRecording); + if (!startRecording) + startRecording = true; } - - return false; + if (startRecording && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) + { + startRecording = false; + } + return hasChange; } static bool DragInt(const std::string& fieldLabel, std::function get, std::function set, float speed = 1.0f, int p_min = int(), int p_max = int(), const char* displayFormat = "%d", ImGuiSliderFlags flags = 0) { int value = get(); - //bool hasChange = ImGui::DragFloat(fieldLabel.c_str(), &value, speed, p_min, p_max, displayFormat, flags); - if (ImGui::DragInt(fieldLabel.c_str(), &value, speed, p_min, p_max, displayFormat, flags)) + const bool hasChange = ImGui::DragInt(fieldLabel.c_str(), &value, speed, p_min, p_max, displayFormat, flags); + static bool startRecording = false; + if (hasChange) { - if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); - else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); - else if (ImGui::IsItemDeactivatedAfterEdit()) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); - - return true; + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), startRecording); + if (!startRecording) + startRecording = true; } - - return false; + if (startRecording && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) + { + startRecording = false; + } + return hasChange; } template static bool SliderScalar(const std::string& fieldLabel, ImGuiDataType data_type, T min, T max, std::function get, std::function set, const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0) { T value = get(); - if (ImGui::SliderScalar(fieldLabel.c_str(), data_type, &value, &min, &max, displayFormat, flags)) + bool const changed = ImGui::SliderScalar(fieldLabel.c_str(), data_type, &value, &min, &max, displayFormat, flags); + static bool startRecording = false; + if (changed) { - if (ImGui::IsMouseClicked(ImGuiMouseButton_Left, false) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); - else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), startRecording); + if (!startRecording) + startRecording = true; - return true; } - - return false; + if (startRecording && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) + { + startRecording = false; + } + return changed; } static bool SliderFloat(const std::string& fieldLabel, float min, float max, std::function get, std::function set, const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0) { float value = get(); - if (ImGui::SliderFloat(fieldLabel.c_str(), &value, min, max, displayFormat, flags)) + bool const changed = ImGui::SliderFloat(fieldLabel.c_str(), &value, min, max, displayFormat, flags); + static bool startRecording = false; + if (changed) { - if (ImGui::IsMouseClicked(ImGuiMouseButton_Left, false) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); - else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), startRecording); + if (!startRecording) + startRecording = true; - - return true; } - - return false; + if (startRecording && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) + { + startRecording = false; + } + return changed; } static bool SliderInt(const std::string& fieldLabel, int min, int max, std::function get, std::function set, const char* displayFormat = "%d", ImGuiSliderFlags flags = 0) { int value = get(); - if (ImGui::SliderInt(fieldLabel.c_str(), &value, min, max, displayFormat, flags)) + bool const changed = ImGui::SliderInt(fieldLabel.c_str(), &value, min, max, displayFormat, flags); + static bool startRecording = false; + if (changed) { - if (ImGui::IsMouseClicked(ImGuiMouseButton_Left, false) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); - else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); - return true; + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), startRecording); + if (!startRecording) + startRecording = true; + } + if (startRecording && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) + { + startRecording = false; } - return false; } From 24c591ec27b186431ea145e7053d2d8542d23031 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Mon, 24 Oct 2022 20:07:59 +0800 Subject: [PATCH 26/50] Modified Managed Transform Interface to use Quaternions --- SHADE_Managed/src/Components/Transform.cxx | 16 ++++++++-------- SHADE_Managed/src/Components/Transform.hxx | 21 ++++++++++----------- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/SHADE_Managed/src/Components/Transform.cxx b/SHADE_Managed/src/Components/Transform.cxx index 0f0716dc..41298c21 100644 --- a/SHADE_Managed/src/Components/Transform.cxx +++ b/SHADE_Managed/src/Components/Transform.cxx @@ -29,13 +29,13 @@ namespace SHADE { GetNativeComponent()->SetLocalPosition(Convert::ToNative(val)); } - Vector3 Transform::LocalRotation::get() + Quaternion Transform::LocalRotation::get() { - return Convert::ToCLI(GetNativeComponent()->GetLocalRotation()); + return Convert::ToCLI(GetNativeComponent()->GetLocalOrientation()); } - void Transform::LocalRotation::set(Vector3 val) + void Transform::LocalRotation::set(Quaternion val) { - GetNativeComponent()->SetLocalRotation(Convert::ToNative(val)); + GetNativeComponent()->SetLocalOrientation(Convert::ToNative(val)); } Vector3 Transform::LocalScale::get() { @@ -54,13 +54,13 @@ namespace SHADE { GetNativeComponent()->SetWorldPosition(Convert::ToNative(val)); } - Vector3 Transform::GlobalRotation::get() + Quaternion Transform::GlobalRotation::get() { - return Convert::ToCLI(GetNativeComponent()->GetWorldRotation()); + return Convert::ToCLI(GetNativeComponent()->GetLocalOrientation()); } - void Transform::GlobalRotation::set(Vector3 val) + void Transform::GlobalRotation::set(Quaternion val) { - GetNativeComponent()->SetWorldRotation(Convert::ToNative(val)); + GetNativeComponent()->SetWorldOrientation(Convert::ToNative(val)); } Vector3 Transform::GlobalScale::get() { diff --git a/SHADE_Managed/src/Components/Transform.hxx b/SHADE_Managed/src/Components/Transform.hxx index 9efd2927..43118b1f 100644 --- a/SHADE_Managed/src/Components/Transform.hxx +++ b/SHADE_Managed/src/Components/Transform.hxx @@ -17,14 +17,14 @@ of DigiPen Institute of Technology is prohibited. // Project Includes #include "Components/Component.hxx" #include "Math/Vector3.hxx" -#include "Utility/Convert.hxx" +#include "Math/Quaternion.hxx" // External Dependencies #include "Math/Transform/SHTransformComponent.h" namespace SHADE { /// - /// CLR version of the the SHADE Engine's TransformComponent. + /// CLR version of the SHADE Engine's TransformComponent. /// public ref class Transform : public Component { @@ -52,12 +52,12 @@ namespace SHADE void set(Vector3 val); } /// - /// Local Z-axis rotation angle stored by this Transform in Radians. + /// Local rotation quaternion stored by this Transform. /// - property Vector3 LocalRotation + property Quaternion LocalRotation { - Vector3 get(); - void set(Vector3 val); + Quaternion get(); + void set(Quaternion val); } /// /// Local scale stored by this Transform. @@ -76,16 +76,15 @@ namespace SHADE void set(Vector3 val); } /// - /// Global Z-axis rotation angle stored by this Transform in Radians. + /// Global rotation quaternion stored by this Transform. /// - property Vector3 GlobalRotation + property Quaternion GlobalRotation { - Vector3 get(); - void set(Vector3 val); + Quaternion get(); + void set(Quaternion val); } /// /// Global scale stored by this Transform. - /// Note that this operation is expensive. /// property Vector3 GlobalScale { From ff025f212cc93e3668dd435015c8bab632b7889f Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Mon, 24 Oct 2022 22:41:36 +0800 Subject: [PATCH 27/50] Added Euler Angles properties to Managed Transforms --- SHADE_Managed/src/Components/Transform.cxx | 16 ++++++++++++++++ SHADE_Managed/src/Components/Transform.hxx | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/SHADE_Managed/src/Components/Transform.cxx b/SHADE_Managed/src/Components/Transform.cxx index 41298c21..98f0da4f 100644 --- a/SHADE_Managed/src/Components/Transform.cxx +++ b/SHADE_Managed/src/Components/Transform.cxx @@ -37,6 +37,14 @@ namespace SHADE { GetNativeComponent()->SetLocalOrientation(Convert::ToNative(val)); } + Vector3 Transform::LocalEulerAngles::get() + { + return Convert::ToCLI(GetNativeComponent()->GetLocalRotation()); + } + void Transform::LocalEulerAngles::set(Vector3 val) + { + GetNativeComponent()->SetLocalRotation(Convert::ToNative(val)); + } Vector3 Transform::LocalScale::get() { return Convert::ToCLI(GetNativeComponent()->GetLocalScale()); @@ -62,6 +70,14 @@ namespace SHADE { GetNativeComponent()->SetWorldOrientation(Convert::ToNative(val)); } + Vector3 Transform::GlobalEulerAngles::get() + { + return Convert::ToCLI(GetNativeComponent()->GetWorldRotation()); + } + void Transform::GlobalEulerAngles::set(Vector3 val) + { + GetNativeComponent()->SetWorldRotation(Convert::ToNative(val)); + } Vector3 Transform::GlobalScale::get() { return Convert::ToCLI(GetNativeComponent()->GetWorldScale()); diff --git a/SHADE_Managed/src/Components/Transform.hxx b/SHADE_Managed/src/Components/Transform.hxx index 43118b1f..bbe9fd19 100644 --- a/SHADE_Managed/src/Components/Transform.hxx +++ b/SHADE_Managed/src/Components/Transform.hxx @@ -60,6 +60,14 @@ namespace SHADE void set(Quaternion val); } /// + /// Local euler angle rotations stored by this Transform. + /// + property Vector3 LocalEulerAngles + { + Vector3 get(); + void set(Vector3 val); + } + /// /// Local scale stored by this Transform. /// property Vector3 LocalScale @@ -84,6 +92,14 @@ namespace SHADE void set(Quaternion val); } /// + /// Global euler angle rotations stored by this Transform. + /// + property Vector3 GlobalEulerAngles + { + Vector3 get(); + void set(Vector3 val); + } + /// /// Global scale stored by this Transform. /// property Vector3 GlobalScale From 8fb0eddcc1bfd795e6b0b1e4dfcd7579d7728d24 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Tue, 25 Oct 2022 00:00:22 +0800 Subject: [PATCH 28/50] Lights WIP --- Assets/Editor/Layouts/UserLayout.ini | 12 +- .../src/Graphics/Instance/SHVkInstance.cpp | 2 +- .../GlobalData/SHGraphicsGlobalData.cpp | 2 +- .../MiddleEnd/Interface/SHGraphicsConstants.h | 2 +- .../MiddleEnd/Lights/SHLightComponent.cpp | 109 ++++++++ .../MiddleEnd/Lights/SHLightComponent.h | 54 ++++ .../Graphics/MiddleEnd/Lights/SHLightData.cpp | 21 ++ .../Graphics/MiddleEnd/Lights/SHLightData.h | 55 ++++ .../MiddleEnd/Lights/SHLightingSubSystem.cpp | 250 ++++++++++++++++++ .../MiddleEnd/Lights/SHLightingSubSystem.h | 109 ++++++++ SHADE_Engine/src/Tools/SHUtilities.h | 9 + SHADE_Engine/src/Tools/SHUtilities.hpp | 6 + 12 files changed, 622 insertions(+), 9 deletions(-) create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.cpp create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.h create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightData.cpp create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightData.h create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.h diff --git a/Assets/Editor/Layouts/UserLayout.ini b/Assets/Editor/Layouts/UserLayout.ini index baced6b8..9add170c 100644 --- a/Assets/Editor/Layouts/UserLayout.ini +++ b/Assets/Editor/Layouts/UserLayout.ini @@ -10,7 +10,7 @@ Collapsed=0 [Window][Hierarchy Panel] Pos=0,142 -Size=387,918 +Size=768,918 Collapsed=0 DockId=0x00000004,0 @@ -27,7 +27,7 @@ DockId=0x00000006,0 [Window][Profiler] Pos=0,48 -Size=387,92 +Size=768,92 Collapsed=0 DockId=0x00000003,0 @@ -38,17 +38,17 @@ Collapsed=0 DockId=0x00000002,0 [Window][ Viewport] -Pos=389,48 -Size=1258,1012 +Pos=770,48 +Size=877,1012 Collapsed=0 DockId=0x00000002,0 [Docking][Data] DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,79 Size=1920,1012 Split=X DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1992,1036 Split=X - DockNode ID=0x00000001 Parent=0x00000005 SizeRef=387,1036 Split=Y Selected=0x1E6EB881 + DockNode ID=0x00000001 Parent=0x00000005 SizeRef=768,1036 Split=Y Selected=0x1E6EB881 DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,94 Selected=0x1E6EB881 DockNode ID=0x00000004 Parent=0x00000001 SizeRef=225,940 Selected=0xE096E5AE - DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1258,1036 CentralNode=1 Selected=0xB41284E7 + DockNode ID=0x00000002 Parent=0x00000005 SizeRef=877,1036 CentralNode=1 Selected=0xB41284E7 DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=271,1036 Selected=0xE7039252 diff --git a/SHADE_Engine/src/Graphics/Instance/SHVkInstance.cpp b/SHADE_Engine/src/Graphics/Instance/SHVkInstance.cpp index 191bc563..edfe4b46 100644 --- a/SHADE_Engine/src/Graphics/Instance/SHVkInstance.cpp +++ b/SHADE_Engine/src/Graphics/Instance/SHVkInstance.cpp @@ -155,7 +155,7 @@ namespace SHADE SHVkDebugMessenger::GenMessengerType(SH_DEBUG_MSG_TYPE::T_GENERAL, SH_DEBUG_MSG_TYPE::T_VALIDATION, SH_DEBUG_MSG_TYPE::T_PERFORMANCE)); instanceDbgInfo.pfnUserCallback = SHVulkanDebugUtil::GenericDebugCallback; - instanceInfo.pNext = static_cast(&instanceDbgInfo); + //instanceInfo.pNext = static_cast(&instanceDbgInfo); } // Finally create the instance diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp index d8b1bad1..ed1d3100 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp @@ -49,7 +49,7 @@ namespace SHADE { .Type = vk::DescriptorType::eStorageBufferDynamic, .Stage = vk::ShaderStageFlagBits::eFragment, - .BindPoint = SHGraphicsConstants::DescriptorSetBindings::LIGHTS_DATA, + .BindPoint = SHGraphicsConstants::DescriptorSetBindings::DIRECTIONAL_LIGHT_DATA, .DescriptorCount = 1, }; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h index a0457b65..15f192c0 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h @@ -101,7 +101,7 @@ namespace SHADE */ /***************************************************************************/ - static constexpr uint32_t LIGHTS_DATA = 0; + static constexpr uint32_t DIRECTIONAL_LIGHT_DATA = 0; /***************************************************************************/ /*! diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.cpp new file mode 100644 index 00000000..e3bcec58 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.cpp @@ -0,0 +1,109 @@ +#include "SHpch.h" +#include "SHLightComponent.h" + +namespace SHADE +{ + + + void SHLightComponent::OnCreate(void) + { + lightData.Reset(); + SetType(SH_LIGHT_TYPE::DIRECTIONAL); + indexInBuffer = std::numeric_limits::max(); + Unbind(); + } + + + void SHLightComponent::OnDestroy(void) + { + + } + + void SHLightComponent::SetPosition(SHVec3 position) noexcept + { + lightData.position = position; + MakeDirty(); + } + + + void SHLightComponent::SetType(SH_LIGHT_TYPE type) noexcept + { + lightData.type = type; + MakeDirty(); + } + + + void SHLightComponent::SetDirection(SHVec3 direction) noexcept + { + lightData.direction = direction; + MakeDirty(); + } + + + void SHLightComponent::SetDiffuseColor(SHVec4 diffuseColor) noexcept + { + lightData.diffuseColor = diffuseColor; + MakeDirty(); + } + + void SHLightComponent::ModifyLayer(uint8_t layerIndex, bool value) noexcept + { + if (value) + lightData.cullingMask |= (1u << layerIndex); + else + lightData.cullingMask &= ~(1u << layerIndex); + + MakeDirty(); + } + + + void SHLightComponent::SetAllLayers(void) noexcept + { + lightData.cullingMask = std::numeric_limits::max(); + MakeDirty(); + } + + + void SHLightComponent::ClearAllLayers(void) noexcept + { + lightData.cullingMask = 0; + MakeDirty(); + } + + void SHLightComponent::MakeDirty(void) noexcept + { + dirty = true; + } + + void SHLightComponent::ClearDirtyFlag(void) noexcept + { + dirty = false; + } + + void SHLightComponent::Unbind(void) noexcept + { + bound = false; + MakeDirty(); + } + + void SHLightComponent::SetBound(void) noexcept + { + bound = true; + } + + SHLightData const& SHLightComponent::GetLightData(void) const noexcept + { + return lightData; + } + + bool SHLightComponent::IsDirty(void) const noexcept + { + return dirty; + } + + bool SHLightComponent::GetBound(void) const noexcept + { + return bound; + } + +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.h b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.h new file mode 100644 index 00000000..3b06a612 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.h @@ -0,0 +1,54 @@ +#pragma once + +#include "ECS_Base/Components/SHComponent.h" +#include "SHLightData.h" + +namespace SHADE +{ + + class SH_API SHLightComponent final : public SHComponent + { + private: + //! General data for the light. This will purely be CPU bound. Whatever gets sent to the + //! GPU depends on the type of the light. + SHLightData lightData; + + //! Since the lighting system is gonna be self contained and light weight, we store this + //! so that we only write this to the CPU buffer when this light component change, we don't + //! rewrite everything. However we still write to the GPU buffer when everything changes. + uint32_t indexInBuffer; + + //! If the light component changed some value we mark this true. + bool dirty; + + //! If the light's data is already in the buffers, this will be set to true. + bool bound; + + public: + /*-----------------------------------------------------------------------*/ + /* LIFECYCLE FUNCTIONS */ + /*-----------------------------------------------------------------------*/ + void OnCreate (void) override final; + void OnDestroy (void) override final; + + /*-----------------------------------------------------------------------*/ + /* SETTERS AND GETTERS */ + /*-----------------------------------------------------------------------*/ + void SetPosition (SHVec3 position) noexcept; + void SetType (SH_LIGHT_TYPE type) noexcept; + void SetDirection (SHVec3 direction) noexcept; + void SetDiffuseColor (SHVec4 diffuseColor) noexcept; + void ModifyLayer (uint8_t layerIndex, bool value) noexcept; + void SetAllLayers (void) noexcept; + void ClearAllLayers (void) noexcept; + void MakeDirty (void) noexcept; + void ClearDirtyFlag (void) noexcept; + void Unbind (void) noexcept; + void SetBound (void) noexcept; + + SHLightData const& GetLightData (void) const noexcept; + bool IsDirty (void) const noexcept; + bool GetBound (void) const noexcept; + + }; +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightData.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightData.cpp new file mode 100644 index 00000000..ba910408 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightData.cpp @@ -0,0 +1,21 @@ +#include "SHpch.h" +#include "SHLightData.h" + +namespace SHADE +{ + void SHLightData::Reset(void) noexcept + { + // no culling is done. + cullingMask = std::numeric_limits::max(); + + // reset position to 0 + position = SHVec3::Zero; + + // direction just point in positive z axis + direction = SHVec3::Forward; + + // Diffuse color set to 1 + diffuseColor = SHVec4::One; + } + +} \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightData.h b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightData.h new file mode 100644 index 00000000..607978a4 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightData.h @@ -0,0 +1,55 @@ +#pragma once + +#include "Math/Vector/SHVec3.h" +#include "Math/Vector/SHVec4.h" + +namespace SHADE +{ + enum class SH_LIGHT_TYPE : uint32_t + { + DIRECTIONAL = 0, + POINT, + SPOT, + NUM_TYPES + }; + + /***************************************************************************/ + /*! + + \class + Every light will essentially be using this struct. However, when passing + light data over to the GPU, the light data will be split according to + type for more optimal cache access. + + */ + /***************************************************************************/ + struct SHLightData + { + //! position of the light + SHVec3 position; + + //! Type of the light + SH_LIGHT_TYPE type; + + //! direction of the light + SHVec3 direction; + + //! Each bit in this 32 bit field will represent a layer. If the bit is set, + //! when a fragment is being evaluated, the shader will use the fragment's + //! layer value to AND with the light's. If result is 1, do lighting calculations. + uint32_t cullingMask; + + //! Diffuse color emitted by the light + SHVec4 diffuseColor; + + void Reset (void) noexcept; + //! TODO: + //! - Add cut off. (inner and outer). + //! - Add constant, linear and quadratic for attenuation + //! - Specular color if needed. see below. + + //! Specular color + //SHVec4 specularColor; + }; + +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp new file mode 100644 index 00000000..3d39ed89 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp @@ -0,0 +1,250 @@ +#include "SHpch.h" +#include "SHLightingSubSystem.h" +#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" +#include "Tools/SHUtilities.h" +#include "Graphics/Devices/SHVkLogicalDevice.h" +#include "Graphics/Buffers/SHVkBuffer.h" +#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" +#include "SHLightComponent.h" +#include "ECS_Base/Managers/SHComponentManager.h" + +namespace SHADE +{ + + /***************************************************************************/ + /*! + + \brief + Initializes type, intermediate data and buffer. dirty will be true. + + \param lightType + type of the light. + + */ + /***************************************************************************/ + void SHLightingSubSystem::PerTypeData::InitializeData(Handle logicalDevice, SH_LIGHT_TYPE type) noexcept + { + // initialize the type + lightType = type; + + // we want to write to GPU when system runs + dirty = true; + + // boilerplate + intermediateData = nullptr; + numLights = 0; + + // initialize alignment + lightDataAlignmentSize = logicalDevice->PadSSBOSize(GetLightTypeSize(type)); + + // So create some data! + Expand(logicalDevice); + } + + /***************************************************************************/ + /*! + + \brief + Expands both the CPU container and the GPU buffer when the number of + lights have exceeded + + */ + /***************************************************************************/ + void SHLightingSubSystem::PerTypeData::Expand(Handle logicalDevice) noexcept + { + // we want to wait for the command buffers to finish using the buffers first + logicalDevice->WaitIdle(); + + // this is for CPU buffer. + uint32_t structSize = GetLightTypeSize(lightType); + + // First time we are initializing lights + if (intermediateData == nullptr) + { + // num lights should start of at STARTING_NUM_LIGHTS lights + numLights = STARTING_NUM_LIGHTS; + + // Initialize the data for lights + intermediateData = std::make_unique(lightDataAlignmentSize * STARTING_NUM_LIGHTS); + + dataBuffer = logicalDevice->CreateBuffer(numLights * lightDataAlignmentSize, nullptr, numLights * lightDataAlignmentSize, vk::BufferUsageFlagBits::eStorageBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); + } + else + { + // save old number of lights + uint32_t const OLD_NUM_LIGHTS = numLights; + + // before we increase the number of lights, create space to store old data. + std::unique_ptr oldData = std::make_unique(lightDataAlignmentSize * OLD_NUM_LIGHTS); + + // copy data over. + std::memcpy (oldData.get(), intermediateData.get(), lightDataAlignmentSize * OLD_NUM_LIGHTS); + + // now we start to expand.... + + // double space for lights + numLights *= 2; + + // destroy old data and initialize container for double the amount of data. + intermediateData = std::make_unique(lightDataAlignmentSize * numLights); + + // copy old data to new container + std::memcpy(intermediateData.get(), oldData.get(), lightDataAlignmentSize * OLD_NUM_LIGHTS); + + // Resize the GPU buffer + dataBuffer->ResizeReplace(lightDataAlignmentSize * numLights, oldData.get(), lightDataAlignmentSize * OLD_NUM_LIGHTS); + + } + + } + + /***************************************************************************/ + /*! + + \brief + This function takes in a light comp in the event that its data has not + been placed in the buffer yet. It also checks if the size of the buffer + is big enough + + \param lightComp + + \return + + */ + /***************************************************************************/ + void SHLightingSubSystem::PerTypeData::AddLight(SHLightComponent* lightComp) noexcept + { + + } + + /***************************************************************************/ + /*! + + \brief + Gets the size required to store data for a light type. + + \param type + Type of a light. + + \return + Size required to store a light based on type. + + */ + /***************************************************************************/ + uint32_t SHLightingSubSystem::PerTypeData::GetLightTypeSize(SH_LIGHT_TYPE type) noexcept + { + switch (type) + { + case SH_LIGHT_TYPE::DIRECTIONAL: + // TOOD: Change after creating point light struct + return 0; + case SH_LIGHT_TYPE::POINT: + return sizeof (SHDirectionalLightData); + case SH_LIGHT_TYPE::SPOT: + // TOOD: Change after creating spot light struct + return 0; + case SH_LIGHT_TYPE::NUM_TYPES: + default: + return 0; + + } + } + + + Handle SHLightingSubSystem::PerTypeData::GetDataBuffer(void) const noexcept + { + return dataBuffer; + } + + + uint32_t SHLightingSubSystem::PerTypeData::GetAlignmentSize(void) const noexcept + { + return lightDataAlignmentSize; + } + + void SHLightingSubSystem::UpdateDescSet(uint32_t binding) noexcept + { + auto buffer = perTypeData[binding].GetDataBuffer(); + + // We bind the buffer with the correct desc set binding + lightingDataDescSet->ModifyWriteDescBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, + binding, + { &buffer, 1 }, + 0, + perTypeData[binding].GetAlignmentSize()); + + lightingDataDescSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, binding); + } + + /***************************************************************************/ + /*! + + \brief + Initializes per light type data. This includes buffers and descriptor + sets. + + + */ + /***************************************************************************/ + void SHLightingSubSystem::Init(Handle logicalDevice, Handle descPool) noexcept + { + std::vector variableSizes{ SHUtilities::ToUnderlying(SH_LIGHT_TYPE::NUM_TYPES) }; + std::fill (variableSizes.begin(), variableSizes.end(), 1); + + // Create the descriptor set + lightingDataDescSet = descPool->Allocate({SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS]}, variableSizes); + + // initialize all the data first. We add more lights here as we add more types. + perTypeData[SHUtilities::ToUnderlying(SH_LIGHT_TYPE::DIRECTIONAL)].InitializeData(logicalDevice, SH_LIGHT_TYPE::DIRECTIONAL); + UpdateDescSet(SHGraphicsConstants::DescriptorSetBindings::DIRECTIONAL_LIGHT_DATA); + } + + /***************************************************************************/ + /*! + + \brief + Loops through every single light component and checks for dirty light + data. If light data is dirty, rewrite to the CPU container and do a + copy to the GPU data. We also check if the per light type data is too small + to handle more lights, if it is, expand buffer (both CPU and GPU). + + */ + /***************************************************************************/ + void SHLightingSubSystem::Run(void) noexcept + { + auto& lightComps = SHComponentManager::GetDense(); + for (auto& light : lightComps) + { + // First we want to make sure the light is already bound to the system. if it + // isn't, we write it to the correct buffer. + if (!light.GetBound()) + { + + + light.SetBound(); + } + + // if there was modification to the light data + if (light.IsDirty()) + { + + } + } + + } + + /***************************************************************************/ + /*! + + \brief + Does nothing for now. + + */ + /***************************************************************************/ + void SHLightingSubSystem::Exit(void) noexcept + { + + } + + +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.h new file mode 100644 index 00000000..4c99354f --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.h @@ -0,0 +1,109 @@ +#pragma once + +#include "Resource/SHHandle.h" +#include "Math/Vector/SHVec3.h" +#include "Math/Vector/SHVec4.h" +#include "SHLightData.h" + +namespace SHADE +{ + class SHVkLogicalDevice; + class SHVkDescriptorPool; + class SHVkDescriptorSetGroup; + class SHVkDescriptorSetLayout; + class SHVkBuffer; + + // Represents how the data will be interpreted in GPU. we want to copy to a container of these before passing to GPU. + struct SHDirectionalLightData + { + //! Direction of the light + SHVec3 direction; + + //! Each bit in this 32 bit field will represent a layer. If the bit is set, + //! when a fragment is being evaluated, the shader will use the fragment's + //! layer value to AND with the light's. If result is 1, do lighting calculations. + uint32_t cullingMask; + + //! Diffuse color emitted by the light + SHVec4 diffuseColor; + + }; + + class SHLightingSubSystem + { + private: + + class PerTypeData + { + private: + /*-----------------------------------------------------------------------*/ + /* STATIC MEMBER VARIABLES */ + /*-----------------------------------------------------------------------*/ + static constexpr uint32_t STARTING_NUM_LIGHTS = 20; + + /*-----------------------------------------------------------------------*/ + /* PRIVATE MEMBER VARIABLES */ + /*-----------------------------------------------------------------------*/ + + //! SSBOs need to be aligned. This is to pad lighting structs + uint32_t lightDataAlignmentSize; + + //! type of the light. Will be used later when we want to expand + SH_LIGHT_TYPE lightType; + + //! number of lights currently alive. + uint32_t numLights; + + //! if intermediateData has been modified(i.e. any 1 light's data is changed), set to true. + bool dirty; + + //! GPU buffer required to store GPU data + Handle dataBuffer; + + //! Before data gets copied to the GPU, it goes into here first. Data here is aligned to whatever struct is + //! used to represent data in this container. + std::unique_ptr intermediateData; + + public: + /*-----------------------------------------------------------------------*/ + /* PUBLIC MEMBER FUNCTIONS */ + /*-----------------------------------------------------------------------*/ + void InitializeData (Handle logicalDevice, SH_LIGHT_TYPE type) noexcept; + void Expand (Handle logicalDevice) noexcept; + void AddLight (SHLightComponent* lightComp) noexcept; + + /*-----------------------------------------------------------------------*/ + /* GETTERS */ + /*-----------------------------------------------------------------------*/ + static uint32_t GetLightTypeSize (SH_LIGHT_TYPE type) noexcept; + Handle GetDataBuffer (void) const noexcept; + uint32_t GetAlignmentSize (void) const noexcept; + }; + + private: + + //! logical device used for creation + Handle logicalDevice; + + //! The descriptor set that will hold the lighting data. Each binding will hold a buffer, NUM_FRAMES times the size required. + Handle lightingDataDescSet; + + //! Each type will have some data associated with it for processing + std::array(SH_LIGHT_TYPE::NUM_TYPES)> perTypeData; + + /*-----------------------------------------------------------------------*/ + /* PRIVATE MEMBER FUNCTIONS */ + /*-----------------------------------------------------------------------*/ + void UpdateDescSet (uint32_t binding) noexcept; + + public: + + /*-----------------------------------------------------------------------*/ + /* PUBLIC MEMBER FUNCTIONS */ + /*-----------------------------------------------------------------------*/ + void Init (Handle logicalDevice, Handle descPool) noexcept; + void Run (void) noexcept; + void Exit (void) noexcept; + + }; +} diff --git a/SHADE_Engine/src/Tools/SHUtilities.h b/SHADE_Engine/src/Tools/SHUtilities.h index 543c771c..b3d840e7 100644 --- a/SHADE_Engine/src/Tools/SHUtilities.h +++ b/SHADE_Engine/src/Tools/SHUtilities.h @@ -42,6 +42,15 @@ namespace SHADE template static constexpr OutputType ConvertEnum(InputType enumClassMember) noexcept; + /** + * @brief Converts an enum class member from it's type to the underlying type. + * @tparam Enum Restricted to an enum class + * @param[in] value A member of the specified enum class. + * @returns The value of the enum class member in the output type. + */ + template + static constexpr typename std::underlying_type_t ToUnderlying (Enum value) noexcept; + }; } // namespace SHADE diff --git a/SHADE_Engine/src/Tools/SHUtilities.hpp b/SHADE_Engine/src/Tools/SHUtilities.hpp index 0e21a9d0..e0404ea1 100644 --- a/SHADE_Engine/src/Tools/SHUtilities.hpp +++ b/SHADE_Engine/src/Tools/SHUtilities.hpp @@ -25,4 +25,10 @@ namespace SHADE return static_cast(enumClassMember); } + template + constexpr typename std::underlying_type_t SHUtilities::ToUnderlying(Enum value) noexcept + { + return static_cast>(value); + } + } // namespace SHADE \ No newline at end of file From 869916cb2a94e64050acaadfdd8ae559fba47116 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Tue, 25 Oct 2022 13:47:27 +0800 Subject: [PATCH 29/50] Lights WIP --- .../MiddleEnd/Lights/SHLightComponent.cpp | 18 +- .../MiddleEnd/Lights/SHLightComponent.h | 14 +- .../MiddleEnd/Lights/SHLightingSubSystem.cpp | 267 ++++++++++++++---- .../MiddleEnd/Lights/SHLightingSubSystem.h | 39 ++- 4 files changed, 266 insertions(+), 72 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.cpp index e3bcec58..fd122334 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.cpp @@ -10,6 +10,7 @@ namespace SHADE lightData.Reset(); SetType(SH_LIGHT_TYPE::DIRECTIONAL); indexInBuffer = std::numeric_limits::max(); + active = true; Unbind(); } @@ -86,9 +87,17 @@ namespace SHADE MakeDirty(); } - void SHLightComponent::SetBound(void) noexcept - { + void SHLightComponent::SetBound(uint32_t inIndexInBuffer) noexcept +{ bound = true; + indexInBuffer = inIndexInBuffer; + } + + void SHLightComponent::SetActive(bool flag) noexcept + { + MakeDirty(); + active = flag; + } SHLightData const& SHLightComponent::GetLightData(void) const noexcept @@ -106,4 +115,9 @@ namespace SHADE return bound; } + uint32_t SHLightComponent::GetIndexInBuffer(void) const noexcept + { + return indexInBuffer; + } + } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.h b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.h index 3b06a612..20ae3892 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.h @@ -23,6 +23,9 @@ namespace SHADE //! If the light's data is already in the buffers, this will be set to true. bool bound; + + //! If the light is active, this is true. + bool active; public: /*-----------------------------------------------------------------------*/ @@ -44,11 +47,14 @@ namespace SHADE void MakeDirty (void) noexcept; void ClearDirtyFlag (void) noexcept; void Unbind (void) noexcept; - void SetBound (void) noexcept; + void SetBound (uint32_t inIndexInBuffer) noexcept; + void SetActive (bool flag) noexcept; + - SHLightData const& GetLightData (void) const noexcept; - bool IsDirty (void) const noexcept; - bool GetBound (void) const noexcept; + SHLightData const& GetLightData (void) const noexcept; + bool IsDirty (void) const noexcept; + bool GetBound (void) const noexcept; + uint32_t GetIndexInBuffer (void) const noexcept; }; } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp index 3d39ed89..613d50d3 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp @@ -7,9 +7,55 @@ #include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" #include "SHLightComponent.h" #include "ECS_Base/Managers/SHComponentManager.h" +#include "SHLightComponent.h" namespace SHADE { + /***************************************************************************/ + /*! + + \brief + This function takes an address in the CPU container and writes light + component data to it. What gets written depends on the light type. + + \param address + The address to write to. + + \param lightComp + The light component with the data to write from. + + \param lightType + The type of the light + + \return + + */ + /***************************************************************************/ + void SHLightingSubSystem::PerTypeData::WriteLightToAddress(void* address, SHLightComponent* lightComp) noexcept + { + auto const& lightData = lightComp->GetLightData(); + switch (lightData.type) + { + case SH_LIGHT_TYPE::DIRECTIONAL: + { + SHDirectionalLightData* lightPtr = reinterpret_cast(address); + + lightPtr->cullingMask = lightData.cullingMask; + lightPtr->direction = lightData.direction; + lightPtr->diffuseColor = lightData.diffuseColor; + break; + } + case SH_LIGHT_TYPE::POINT: + break; + case SH_LIGHT_TYPE::SPOT: + break; + case SH_LIGHT_TYPE::NUM_TYPES: + break; + default: + break; + + } + } /***************************************************************************/ /*! @@ -27,12 +73,8 @@ namespace SHADE // initialize the type lightType = type; - // we want to write to GPU when system runs - dirty = true; - // boilerplate intermediateData = nullptr; - numLights = 0; // initialize alignment lightDataAlignmentSize = logicalDevice->PadSSBOSize(GetLightTypeSize(type)); @@ -46,7 +88,7 @@ namespace SHADE \brief Expands both the CPU container and the GPU buffer when the number of - lights have exceeded + lights have exceeded the capacity. */ /***************************************************************************/ @@ -55,66 +97,46 @@ namespace SHADE // we want to wait for the command buffers to finish using the buffers first logicalDevice->WaitIdle(); - // this is for CPU buffer. - uint32_t structSize = GetLightTypeSize(lightType); - // First time we are initializing lights if (intermediateData == nullptr) { - // num lights should start of at STARTING_NUM_LIGHTS lights - numLights = STARTING_NUM_LIGHTS; + // max lights should start of at STARTING_NUM_LIGHTS lights + maxLights = STARTING_NUM_LIGHTS; + numLights = 0; // Initialize the data for lights - intermediateData = std::make_unique(lightDataAlignmentSize * STARTING_NUM_LIGHTS); + intermediateData = std::make_unique(lightDataAlignmentSize * maxLights); - dataBuffer = logicalDevice->CreateBuffer(numLights * lightDataAlignmentSize, nullptr, numLights * lightDataAlignmentSize, vk::BufferUsageFlagBits::eStorageBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); + // We want to initialize 3 times the amount of data required. + dataBuffer = logicalDevice->CreateBuffer(maxLights * lightDataAlignmentSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, nullptr, maxLights * lightDataAlignmentSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, vk::BufferUsageFlagBits::eStorageBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); } else { // save old number of lights - uint32_t const OLD_NUM_LIGHTS = numLights; + uint32_t const OLD_MAX_LIGHTS = maxLights; // before we increase the number of lights, create space to store old data. - std::unique_ptr oldData = std::make_unique(lightDataAlignmentSize * OLD_NUM_LIGHTS); + std::unique_ptr oldData = std::make_unique(lightDataAlignmentSize * OLD_MAX_LIGHTS); // copy data over. - std::memcpy (oldData.get(), intermediateData.get(), lightDataAlignmentSize * OLD_NUM_LIGHTS); + std::memcpy (oldData.get(), intermediateData.get(), lightDataAlignmentSize * OLD_MAX_LIGHTS); // now we start to expand.... // double space for lights - numLights *= 2; + maxLights *= 2; // destroy old data and initialize container for double the amount of data. - intermediateData = std::make_unique(lightDataAlignmentSize * numLights); + intermediateData = std::make_unique(lightDataAlignmentSize * maxLights); // copy old data to new container - std::memcpy(intermediateData.get(), oldData.get(), lightDataAlignmentSize * OLD_NUM_LIGHTS); - - // Resize the GPU buffer - dataBuffer->ResizeReplace(lightDataAlignmentSize * numLights, oldData.get(), lightDataAlignmentSize * OLD_NUM_LIGHTS); + std::memcpy(intermediateData.get(), oldData.get(), lightDataAlignmentSize * OLD_MAX_LIGHTS); + // Resize the GPU buffer. TODO: Replace with Resize no copy here + dataBuffer->ResizeReplace(maxLights * lightDataAlignmentSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, oldData.get(), lightDataAlignmentSize * OLD_MAX_LIGHTS); } - } - - /***************************************************************************/ - /*! - - \brief - This function takes in a light comp in the event that its data has not - been placed in the buffer yet. It also checks if the size of the buffer - is big enough - \param lightComp - - \return - - */ - /***************************************************************************/ - void SHLightingSubSystem::PerTypeData::AddLight(SHLightComponent* lightComp) noexcept - { - } /***************************************************************************/ @@ -162,20 +184,128 @@ namespace SHADE return lightDataAlignmentSize; } + uint32_t SHLightingSubSystem::PerTypeData::GetNumLights(void) const noexcept + { + return numLights; + } + + uint32_t SHLightingSubSystem::PerTypeData::GetMaxLights(void) const noexcept + { + return maxLights; + } + + + /***************************************************************************/ + /*! + + \brief + This function takes in a light comp in the event that its data has not + been placed in the buffer yet. It also checks if the size of the buffer + is big enough to hold the new light. If the buffer is too small, expand + it. + + \param lightComp + The light component to add. + + */ + /***************************************************************************/ + void SHLightingSubSystem::PerTypeData::AddLight(Handle logicalDevice, SHLightComponent* unboundLight, bool expanded) noexcept + { + if (unboundLight) + { + // capacity is full + if (numLights == maxLights) + { + // expand first + Expand(logicalDevice); + + expanded = true; + } + + // Now that the container is big enough, bind the new light + + // Get address of write location + void* writeLocation = reinterpret_cast(intermediateData.get()) + (lightDataAlignmentSize * numLights); + + // Write the light data to address + WriteLightToAddress(writeLocation, unboundLight); + + // Set the light component to be bound to that location + unboundLight->SetBound(numLights); + + // Increase light count + ++numLights; + } + } + + /***************************************************************************/ + /*! + + \brief + Modify the data at a specific light address. + + \param lightComp + The light component to write. + + */ + /***************************************************************************/ + void SHLightingSubSystem::PerTypeData::ModifyLight(SHLightComponent* lightComp) noexcept + { + void* writeLocation = reinterpret_cast(intermediateData.get()) + (lightDataAlignmentSize * lightComp->GetIndexInBuffer()); + WriteLightToAddress(writeLocation, lightComp); + } + + void SHLightingSubSystem::PerTypeData::WriteToGPU(uint32_t frameIndex) noexcept + { + // we want to write to the offset of the current frame + dataBuffer->WriteToMemory(intermediateData.get(), lightDataAlignmentSize * numLights, 0, lightDataAlignmentSize * maxLights * frameIndex); + } + + /***************************************************************************/ + /*! + + \brief + Update descriptor sets. We want to call this everytime we expand buffers. + + \param binding + The binding in the set we want to update. + + */ + /***************************************************************************/ void SHLightingSubSystem::UpdateDescSet(uint32_t binding) noexcept { auto buffer = perTypeData[binding].GetDataBuffer(); // We bind the buffer with the correct desc set binding lightingDataDescSet->ModifyWriteDescBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, - binding, - { &buffer, 1 }, - 0, - perTypeData[binding].GetAlignmentSize()); + binding, + { &buffer, 1 }, + 0, + perTypeData[binding].GetAlignmentSize()); lightingDataDescSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, binding); } + /***************************************************************************/ + /*! + + \brief + Computes dynamic offsets. + + */ + /***************************************************************************/ + void SHLightingSubSystem::ComputeDynamicOffsets(void) noexcept + { + for (uint32_t i = 0; i < dynamicOffsets.size(); ++i) + { + auto const& typeData = perTypeData[i]; + for (uint32_t j = 0; j < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++j) + { + dynamicOffsets[i][j] = j * typeData.GetAlignmentSize() * typeData.GetMaxLights(); + } + } + } + /***************************************************************************/ /*! @@ -186,8 +316,10 @@ namespace SHADE */ /***************************************************************************/ - void SHLightingSubSystem::Init(Handle logicalDevice, Handle descPool) noexcept + void SHLightingSubSystem::Init(Handle device, Handle descPool) noexcept { + logicalDevice = device; + std::vector variableSizes{ SHUtilities::ToUnderlying(SH_LIGHT_TYPE::NUM_TYPES) }; std::fill (variableSizes.begin(), variableSizes.end(), 1); @@ -197,6 +329,7 @@ namespace SHADE // initialize all the data first. We add more lights here as we add more types. perTypeData[SHUtilities::ToUnderlying(SH_LIGHT_TYPE::DIRECTIONAL)].InitializeData(logicalDevice, SH_LIGHT_TYPE::DIRECTIONAL); UpdateDescSet(SHGraphicsConstants::DescriptorSetBindings::DIRECTIONAL_LIGHT_DATA); + } /***************************************************************************/ @@ -204,33 +337,61 @@ namespace SHADE \brief Loops through every single light component and checks for dirty light - data. If light data is dirty, rewrite to the CPU container and do a - copy to the GPU data. We also check if the per light type data is too small - to handle more lights, if it is, expand buffer (both CPU and GPU). + data. If light data is dirty, rewrite to the CPU container. We also want + to bind the descriptor set for the light data. */ /***************************************************************************/ - void SHLightingSubSystem::Run(void) noexcept + void SHLightingSubSystem::Run(Handle cmdBuffer, uint32_t frameIndex) noexcept { auto& lightComps = SHComponentManager::GetDense(); + bool expanded = false; for (auto& light : lightComps) { + auto enumValue = SHUtilities::ToUnderlying(light.GetLightData().type); + // First we want to make sure the light is already bound to the system. if it // isn't, we write it to the correct buffer. if (!light.GetBound()) { - - - light.SetBound(); + perTypeData[enumValue].AddLight(logicalDevice, &light, expanded); } // if there was modification to the light data if (light.IsDirty()) { - + // Write the data to the CPU + perTypeData[enumValue].ModifyLight(&light); + + // Light is now updated in the container + light.ClearDirtyFlag(); } } + // Write data to GPU + for (auto& data : perTypeData) + { + data.WriteToGPU(frameIndex); + } + + // If any of the buffers got expanded, the descriptor set is invalid because the expanded buffer + // is a new buffer. If some expansion was detected, update descriptor sets. + if (expanded) + { + uint32_t numLightTyes = SHUtilities::ToUnderlying(SH_LIGHT_TYPE::NUM_TYPES); + for (uint32_t i = 0; i < numLightTyes; ++i) + { + UpdateDescSet(i); + } + } + + // compute dynamic offsets. We don't actually have to compute every frame but its pretty lightweight, + // so we do it anyway. #NoteToSelf: if at any point it affects performance, do a check before computing. + ComputeDynamicOffsets(); + + // Bind descriptor set (We bind at an offset because the buffer holds NUM_FRAME_BUFFERS sets of data). + cmdBuffer->BindDescriptorSet(lightingDataDescSet, SH_PIPELINE_TYPE::GRAPHICS, SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, {dynamicOffsets[frameIndex]}); + } /***************************************************************************/ @@ -245,6 +406,4 @@ namespace SHADE { } - - } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.h index 4c99354f..e5336b4e 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.h @@ -4,6 +4,7 @@ #include "Math/Vector/SHVec3.h" #include "Math/Vector/SHVec4.h" #include "SHLightData.h" +#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h" namespace SHADE { @@ -12,6 +13,8 @@ namespace SHADE class SHVkDescriptorSetGroup; class SHVkDescriptorSetLayout; class SHVkBuffer; + class SHLightComponent; + class SHVkCommandBuffer; // Represents how the data will be interpreted in GPU. we want to copy to a container of these before passing to GPU. struct SHDirectionalLightData @@ -19,6 +22,9 @@ namespace SHADE //! Direction of the light SHVec3 direction; + //! Represents if the light is active or not + uint32_t active; + //! Each bit in this 32 bit field will represent a layer. If the bit is set, //! when a fragment is being evaluated, the shader will use the fragment's //! layer value to AND with the light's. If result is 1, do lighting calculations. @@ -29,7 +35,7 @@ namespace SHADE }; - class SHLightingSubSystem + class SH_API SHLightingSubSystem { private: @@ -44,6 +50,8 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER VARIABLES */ /*-----------------------------------------------------------------------*/ + //! Capacity of the container. + uint32_t maxLights; //! SSBOs need to be aligned. This is to pad lighting structs uint32_t lightDataAlignmentSize; @@ -54,23 +62,24 @@ namespace SHADE //! number of lights currently alive. uint32_t numLights; - //! if intermediateData has been modified(i.e. any 1 light's data is changed), set to true. - bool dirty; - //! GPU buffer required to store GPU data Handle dataBuffer; //! Before data gets copied to the GPU, it goes into here first. Data here is aligned to whatever struct is - //! used to represent data in this container. + //! used to represent data in this container. Note this will store only 1 copy of all the lights, compared + //! to the GPU that stores NUM_FRAME_BUFFERS copies. std::unique_ptr intermediateData; + void WriteLightToAddress (void* address, SHLightComponent* lightComp) noexcept; public: /*-----------------------------------------------------------------------*/ /* PUBLIC MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ void InitializeData (Handle logicalDevice, SH_LIGHT_TYPE type) noexcept; void Expand (Handle logicalDevice) noexcept; - void AddLight (SHLightComponent* lightComp) noexcept; + void AddLight (Handle logicalDevice, SHLightComponent* unboundLight, bool expanded) noexcept; + void ModifyLight (SHLightComponent* lightComp) noexcept; + void WriteToGPU (uint32_t frameIndex) noexcept; /*-----------------------------------------------------------------------*/ /* GETTERS */ @@ -78,31 +87,37 @@ namespace SHADE static uint32_t GetLightTypeSize (SH_LIGHT_TYPE type) noexcept; Handle GetDataBuffer (void) const noexcept; uint32_t GetAlignmentSize (void) const noexcept; + uint32_t GetNumLights (void) const noexcept; + uint32_t GetMaxLights (void) const noexcept; }; private: //! logical device used for creation - Handle logicalDevice; + Handle logicalDevice; //! The descriptor set that will hold the lighting data. Each binding will hold a buffer, NUM_FRAMES times the size required. - Handle lightingDataDescSet; + Handle lightingDataDescSet; //! Each type will have some data associated with it for processing - std::array(SH_LIGHT_TYPE::NUM_TYPES)> perTypeData; + std::array(SH_LIGHT_TYPE::NUM_TYPES)> perTypeData; + + //! Container to store dynamic offsets for binding descriptor sets + std::array, static_cast(SHGraphicsConstants::NUM_FRAME_BUFFERS)> dynamicOffsets; /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ - void UpdateDescSet (uint32_t binding) noexcept; + void UpdateDescSet (uint32_t binding) noexcept; + void ComputeDynamicOffsets (void) noexcept; public: /*-----------------------------------------------------------------------*/ /* PUBLIC MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ - void Init (Handle logicalDevice, Handle descPool) noexcept; - void Run (void) noexcept; + void Init (Handle device, Handle descPool) noexcept; + void Run (Handle cmdBuffer, uint32_t frameIndex) noexcept; void Exit (void) noexcept; }; From c2e51dc603118eb025aa95b4fcf64f44cc5cfca9 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 25 Oct 2022 14:31:28 +0800 Subject: [PATCH 30/50] Fixed deletion crash caused by Renderables --- .../Graphics/MiddleEnd/Batching/SHBatch.cpp | 74 ++++++++++++------- .../src/Graphics/MiddleEnd/Batching/SHBatch.h | 2 +- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 4 +- .../MiddleEnd/Interface/SHRenderable.cpp | 24 +++--- .../MiddleEnd/Interface/SHRenderable.h | 4 +- 5 files changed, 67 insertions(+), 41 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index 40826047..24dd76c5 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -59,7 +59,7 @@ namespace SHADE } // Add renderable in - subBatch->Renderables.insert(renderable); + subBatch->Renderables.insert(renderable->GetEID()); // Also add material instance in referencedMatInstances.insert(renderable->GetMaterial()); @@ -80,27 +80,34 @@ namespace SHADE if (subBatch == subBatches.end()) return; - subBatch->Renderables.erase(renderable); + subBatch->Renderables.erase(renderable->GetEID()); // Check if other renderables in subBatches contain the same material instance bool matUnused = true; for (const auto& sb : subBatches) - for (const auto& rend : sb.Renderables) + for (const auto& rendId : sb.Renderables) { - if (rend->GetMaterial() == renderable->GetMaterial()) + auto rend = SHComponentManager::GetComponent(rendId); + if (rend) { - matUnused = false; - break; + if (rend->GetMaterial() == renderable->GetMaterial()) + { + matUnused = false; + break; + } + } + else + { + SHLOG_WARNING("[SHBatch] Entity with a missing SHRenderable found!"); } } // Material is no longer in this library, so we remove it if (matUnused) - referencedMatInstances.erase(renderable->GetMaterial()); + referencedMatInstances.erase(renderable->WasMaterialChanged() ? renderable->GetPrevMaterial() : renderable->GetMaterial()); // Mark all as dirty - for (bool& dirt : isDirty) - dirt = true; + setAllDirtyFlags(); } void SHBatch::Clear() @@ -162,9 +169,17 @@ namespace SHADE // Build CPU Buffer char* propsCurrPtr = matPropsData.get(); for (auto& subBatch : subBatches) - for (const SHRenderable* renderable : subBatch.Renderables) + for (auto rendId : subBatch.Renderables) { - renderable->GetMaterial()->ExportProperties(propsCurrPtr); + const SHRenderable* renderable = SHComponentManager::GetComponent(rendId); + if (renderable) + { + renderable->GetMaterial()->ExportProperties(propsCurrPtr); + } + else + { + SHLOG_WARNING("[SHBatch] Entity with a missing SHRenderable found!"); + } propsCurrPtr += singleMatPropAlignedSize; } @@ -188,18 +203,18 @@ namespace SHADE // Populate on the CPU for (auto& subBatch : subBatches) - for (const SHRenderable* renderable : subBatch.Renderables) + for (auto rendId : subBatch.Renderables) { // Transform - auto transform = SHComponentManager::GetComponent(renderable->GetEID()); - if (!transform) + auto transform = SHComponentManager::GetComponent(rendId); + if (transform) { - SHLOG_WARNING("[SHBatch] Entity contianing a SHRenderable with no SHTransformComponent found!"); - transformData.emplace_back(); + transformData.emplace_back(transform->GetTRS()); } else { - transformData.emplace_back(transform->GetTRS()); + SHLOG_WARNING("[SHBatch] Entity contianing a SHRenderable with no SHTransformComponent found!"); + transformData.emplace_back(); } } @@ -221,10 +236,10 @@ namespace SHADE // Populate on the CPU for (auto& subBatch : subBatches) - for (const SHRenderable* renderable : subBatch.Renderables) - { - eidData.emplace_back(renderable->GetEID()); - } + for (auto rendId : subBatch.Renderables) + { + eidData.emplace_back(rendId); + } // Transfer to GPU if (eidBuffer[frameIndex]) @@ -305,11 +320,10 @@ namespace SHADE }); // Fill in buffers (CPU) - for (const SHRenderable* renderable : subBatch.Renderables) + for (auto rendId : subBatch.Renderables) { // Transform - EntityID eid = renderable->GetEID(); - auto transform = SHComponentManager::GetComponent_s(eid); + auto transform = SHComponentManager::GetComponent_s(rendId); if (!transform) { SHLOG_WARNING("[SHBatch] Entity contianing a SHRenderable with no SHTransformComponent found!"); @@ -320,12 +334,20 @@ namespace SHADE transformData.emplace_back(transform->GetTRS()); } - eidData.emplace_back(eid); + eidData.emplace_back(rendId); // Material Properties if (!EMPTY_MAT_PROPS) { - renderable->GetMaterial()->ExportProperties(propsCurrPtr); + const SHRenderable* renderable = SHComponentManager::GetComponent(rendId); + if (renderable) + { + renderable->GetMaterial()->ExportProperties(propsCurrPtr); + } + else + { + SHLOG_WARNING("[SHBatch] Entity with a missing SHRenderable found!"); + } propsCurrPtr += singleMatPropAlignedSize; } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h index 193fff0d..fa18fad5 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h @@ -55,7 +55,7 @@ namespace SHADE /* Data Members */ /*-----------------------------------------------------------------------------*/ Handle Mesh; - std::unordered_set Renderables; + std::unordered_set Renderables; }; /***********************************************************************************/ /*! diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 7ecd92d2..4280cafd 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -677,10 +677,10 @@ namespace SHADE continue; // Remove from old material's SuperBatch - Handle prevMaterial = renderable.GetPrevMaterial(); + Handle prevMaterial = renderable.GetPrevMaterial(); if (prevMaterial) { - Handle oldSuperBatch = prevMaterial->GetPipeline()->GetPipelineState().GetSubpass()->GetSuperBatch(); + Handle oldSuperBatch = prevMaterial->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpass()->GetSuperBatch(); oldSuperBatch->Remove(&renderable); } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp index 0b1c1b66..9dcd391d 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp @@ -31,15 +31,16 @@ namespace SHADE void SHRenderable::OnDestroy() { + // Remove from SuperBatch + Handle superBatch = sharedMaterial->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpass()->GetSuperBatch(); + superBatch->Remove(this); + + // Free resources if (material) { material.Free(); material = {}; } - - // Remove from SuperBatch - Handle superBatch = sharedMaterial->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpass()->GetSuperBatch(); - superBatch->Remove(this); } /*-----------------------------------------------------------------------------------*/ @@ -51,20 +52,23 @@ namespace SHADE if (!material && sharedMaterial == materialInstance) return; + // Flag that material was changed + materialChanged = true; + // Free copies of materials if any if (material) { + oldMaterial = material; material.Free(); material = {}; } - - // Flag that material was changed - materialChanged = true; - if (sharedMaterial) - oldMaterial = sharedMaterial->GetBaseMaterial(); + else if (sharedMaterial) + { + oldMaterial = sharedMaterial; + } // Update the material - sharedMaterial = materialInstance; + sharedMaterial = materialInstance; } Handle SHRenderable::GetMaterial() const diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.h index bc885ca2..5312cf82 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.h @@ -55,7 +55,7 @@ namespace SHADE /* Getter Functions */ /*-------------------------------------------------------------------------------*/ bool WasMaterialChanged() const noexcept { return materialChanged; } - Handle GetPrevMaterial() const noexcept { return oldMaterial; } + Handle GetPrevMaterial() const noexcept { return oldMaterial; } /*-------------------------------------------------------------------------------*/ /* Batcher Dispatcher Functions */ @@ -74,7 +74,7 @@ namespace SHADE Handle sharedMaterial; Handle material; bool materialChanged = true; - Handle oldMaterial; + Handle oldMaterial; }; } From 9f98bed4d15b85bd8aae1a6909e4045030fc278e Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 25 Oct 2022 15:11:01 +0800 Subject: [PATCH 31/50] Fixed batching renedering the wrong number of instances --- SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index 24dd76c5..012d9526 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -310,14 +310,16 @@ namespace SHADE for (auto& subBatch : subBatches) { // Create command + const uint32_t CURR_INSTANCES = static_cast(subBatch.Renderables.size()); drawData.emplace_back(vk::DrawIndexedIndirectCommand { .indexCount = subBatch.Mesh->IndexCount, - .instanceCount = static_cast(subBatch.Renderables.size()), + .instanceCount = CURR_INSTANCES, .firstIndex = subBatch.Mesh->FirstIndex, .vertexOffset = subBatch.Mesh->FirstVertex, - .firstInstance = nextInstanceIndex++ + .firstInstance = nextInstanceIndex }); + nextInstanceIndex += CURR_INSTANCES; // Fill in buffers (CPU) for (auto rendId : subBatch.Renderables) From da167ec3a58acff2152dd633edd86e994e59851f Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 25 Oct 2022 15:39:18 +0800 Subject: [PATCH 32/50] Added .editorconfig to enforce 2-spacing indentation --- .editorconfig | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..29c5e400 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,5 @@ +root = true + +[*.{c,cpp,h,hpp}] +indent_style = space +indent_size = 2 \ No newline at end of file From 0acd6a99a43fd3a3e51cf2abc5fb7d13ed6af725 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Tue, 25 Oct 2022 17:08:15 +0800 Subject: [PATCH 33/50] Tweaks to editor widgets --- .../HierarchyPanel/SHHierarchyPanel.cpp | 3 +- .../Inspector/SHEditorComponentView.hpp | 21 +++-- SHADE_Engine/src/Editor/SHEditorWidgets.hpp | 84 ++++++++++++++++--- 3 files changed, 87 insertions(+), 21 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp index 972d4ae3..f2f8d927 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp @@ -93,8 +93,7 @@ namespace SHADE { if (ImGui::BeginMenuBar()) { - - ImGui::SetCursorPosX(ImGui::GetContentRegionAvail().x - 40.0f); + ImGui::SetCursorPosX(ImGui::GetContentRegionAvail().x * 0.75f); if(ImGui::SmallButton(ICON_MD_DESELECT)) { auto editor = SHSystemManager::GetSystem(); diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index 0bbbe0dd..7fa39d74 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -52,7 +52,7 @@ namespace SHADE if (!component) return; const auto componentType = rttr::type::get(*component); - SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }); + SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active"); ImGui::SameLine(); if (ImGui::CollapsingHeader(componentType.get_name().data())) { @@ -93,7 +93,7 @@ namespace SHADE auto metaMax = property.get_metadata(META::max); if (metaMin && metaMax) { - SHEditorWidgets::SliderInt(property.get_name().data(), metaMin.template get_value(), metaMin.template get_value(), [component, property] {return property.get_value(component).to_int(); }, [component, property](int const& result) {property.set_value(component, result); }); + SHEditorWidgets::SliderInt(property.get_name().data(), metaMin.template get_value(), metaMax.template get_value(), [component, property] {return property.get_value(component).to_int(); }, [component, property](int const& result) {property.set_value(component, result); }); } else { @@ -119,7 +119,7 @@ namespace SHADE auto metaMax = property.get_metadata(META::max); if (metaMin.is_valid() && metaMax.is_valid()) { - SHEditorWidgets::SliderScalar(property.get_name().data(), ImGuiDataType_U16, metaMin.template get_value(), metaMin.template get_value(), [component, property] {return property.get_value(component).to_uint16(); }, [component, property](uint16_t const& result) {property.set_value(component, result); }, "%zu"); + SHEditorWidgets::SliderScalar(property.get_name().data(), ImGuiDataType_U16, metaMin.template get_value(), metaMax.template get_value(), [component, property] {return property.get_value(component).to_uint16(); }, [component, property](uint16_t const& result) {property.set_value(component, result); }, "%zu"); } else { @@ -132,7 +132,7 @@ namespace SHADE auto metaMax = property.get_metadata(META::max); if (metaMin.is_valid() && metaMax.is_valid()) { - SHEditorWidgets::SliderScalar(property.get_name().data(), ImGuiDataType_U32, metaMin.template get_value(), metaMin.template get_value(), [component, property] { return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result) {property.set_value(component, result); }, "%zu"); + SHEditorWidgets::SliderScalar(property.get_name().data(), ImGuiDataType_U32, metaMin.template get_value(), metaMax.template get_value(), [component, property] { return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result) {property.set_value(component, result); }, "%zu"); } else { @@ -145,7 +145,7 @@ namespace SHADE auto metaMax = property.get_metadata(META::max); if (metaMin.is_valid() && metaMax.is_valid()) { - SHEditorWidgets::SliderScalar(property.get_name().data(), ImGuiDataType_U64, metaMin.template get_value(), metaMin.template get_value(), [component, property] {return property.get_value(component).to_uint64(); }, [component, property](uint64_t const& result) {property.set_value(component, result); }, "%zu"); + SHEditorWidgets::SliderScalar(property.get_name().data(), ImGuiDataType_U64, metaMin.template get_value(), metaMax.template get_value(), [component, property] {return property.get_value(component).to_uint64(); }, [component, property](uint64_t const& result) {property.set_value(component, result); }, "%zu"); } else { @@ -156,13 +156,18 @@ namespace SHADE { auto metaMin = property.get_metadata(META::min); auto metaMax = property.get_metadata(META::max); + float min{}, max{}; + if(metaMin.is_valid()) + min = std::max(metaMin.template get_value(), -FLT_MAX * 0.5f); + if(metaMax.is_valid()) + max = std::min(metaMax.template get_value(), FLT_MAX * 0.5f); if (metaMin.is_valid() && metaMax.is_valid()) { - SHEditorWidgets::SliderFloat(property.get_name().data(), metaMin.template get_value(), metaMin.template get_value(), [component, property] {return property.get_value(component).to_float(); }, [component, property](float const& result) {property.set_value(component, result); }); + SHEditorWidgets::SliderFloat(property.get_name().data(), min, max, [component, property] {return property.get_value(component).to_float(); }, [component, property](float const& result) {property.set_value(component, result); }); } else { - SHEditorWidgets::DragFloat(property.get_name().data(), [component, property] {return property.get_value(component).to_float(); }, [component, property](float const& result) {property.set_value(component, result); }); + SHEditorWidgets::DragFloat(property.get_name().data(), [component, property] {return property.get_value(component).to_float(); }, [component, property](float const& result) {property.set_value(component, result); }, "Test"); } } else if (type == rttr::type::get()) @@ -171,7 +176,7 @@ namespace SHADE auto metaMax = property.get_metadata(META::max); if (metaMin.is_valid() && metaMax.is_valid()) { - SHEditorWidgets::SliderScalar(property.get_name().data(), ImGuiDataType_Double, metaMin.template get_value(), metaMin.template get_value(), [component, property] {return property.get_value(component).to_double(); }, [component, property](double const& result) {property.set_value(component, result); }); + SHEditorWidgets::SliderScalar(property.get_name().data(), ImGuiDataType_Double, metaMin.template get_value(), metaMax.template get_value(), [component, property] {return property.get_value(component).to_double(); }, [component, property](double const& result) {property.set_value(component, result); }); } else { diff --git a/SHADE_Engine/src/Editor/SHEditorWidgets.hpp b/SHADE_Engine/src/Editor/SHEditorWidgets.hpp index dc65d6c2..4a299d25 100644 --- a/SHADE_Engine/src/Editor/SHEditorWidgets.hpp +++ b/SHADE_Engine/src/Editor/SHEditorWidgets.hpp @@ -203,7 +203,7 @@ namespace SHADE } static bool DragVec2(const std::string& fieldLabel, std::vectorconst& componentLabels, std::function get, - std::function set, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f, + std::function set, float speed = 0.1f, const char* displayFormat = "%.3f", std::string_view const& tooltip = {}, float valueMin = 0.0f, float valueMax = 0.0f, ImGuiSliderFlags flags = 0) { SHVec2 values = get(); @@ -217,12 +217,20 @@ namespace SHADE } if (startRecording && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) startRecording = false; - + if(!tooltip.empty()) + { + if(ImGui::IsItemHovered()) + { + ImGui::BeginTooltip(); + ImGui::Text(tooltip.data()); + ImGui::EndTooltip(); + } + } return changed; } static bool DragVec3(const std::string& fieldLabel, std::vectorconst& componentLabels, std::function get, - std::function set, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f, + std::function set, float speed = 0.1f, const char* displayFormat = "%.3f", std::string_view const& tooltip = {}, float valueMin = 0.0f, float valueMax = 0.0f, ImGuiSliderFlags flags = 0) { SHVec3 values = get(); @@ -241,12 +249,20 @@ namespace SHADE { startRecording = false; } - + if(!tooltip.empty()) + { + if(ImGui::IsItemHovered()) + { + ImGui::BeginTooltip(); + ImGui::Text(tooltip.data()); + ImGui::EndTooltip(); + } + } return changed; } static bool DragVec4(const std::string& fieldLabel, std::vectorconst& componentLabels, std::function get, - std::function set, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f, + std::function set, float speed = 0.1f, const char* displayFormat = "%.3f", std::string_view const& tooltip = {}, float valueMin = 0.0f, float valueMax = 0.0f, ImGuiSliderFlags flags = 0) { SHVec4 values = get(); @@ -262,7 +278,15 @@ namespace SHADE { startRecording = false; } - + if(!tooltip.empty()) + { + if(ImGui::IsItemHovered()) + { + ImGui::BeginTooltip(); + ImGui::Text(tooltip.data()); + ImGui::EndTooltip(); + } + } return changed; } @@ -270,14 +294,38 @@ namespace SHADE //|| Widget Extensions || //#==============================================================# - static bool CheckBox(std::string const& label, std::function get, std::function set) + static void TextLabel(std::string_view const& text, bool sameLine = true) + { + const ImVec2 textSize = ImGui::CalcTextSize(text.data(), NULL, true); + if(textSize.x > 0.0f) + { + ImGui::Text(text.data()); + ImGui::SameLine(); + } + } + + static bool CheckBox(std::string_view const& label, std::function get, std::function set, std::string_view const& tooltip = {}) { bool value = get(); - if (ImGui::Checkbox(label.c_str(), &value)) + ImGui::BeginGroup(); + ImGui::PushID(label.data()); + TextLabel(label); + if (ImGui::Checkbox("##", &value)) { SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); return true; } + ImGui::PopID(); + ImGui::EndGroup(); + if(!tooltip.empty()) + { + if(ImGui::IsItemHovered()) + { + ImGui::BeginTooltip(); + ImGui::Text(tooltip.data()); + ImGui::EndTooltip(); + } + } return false; } @@ -331,11 +379,14 @@ namespace SHADE return hasChange; } - static bool DragFloat(const std::string& fieldLabel, std::function get, std::function set, + static bool DragFloat(const std::string_view& label, std::function get, std::function set, std::string_view const& tooltip = {}, float speed = 0.1f, float p_min = float(), float p_max = float(), const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0) { float value = get(); - const bool hasChange = ImGui::DragFloat(fieldLabel.c_str(), &value, speed, p_min, p_max, displayFormat, flags); + ImGui::BeginGroup(); + ImGui::PushID(label.data()); + TextLabel(label); + const bool hasChange = ImGui::DragFloat("##", &value, speed, p_min, p_max, displayFormat, flags); static bool startRecording = false; if (hasChange) { @@ -347,6 +398,17 @@ namespace SHADE { startRecording = false; } + ImGui::PopID(); + ImGui::EndGroup(); + if(!tooltip.empty()) + { + if(ImGui::IsItemHovered()) + { + ImGui::BeginTooltip(); + ImGui::Text(tooltip.data()); + ImGui::EndTooltip(); + } + } return hasChange; } @@ -389,7 +451,7 @@ namespace SHADE return changed; } - static bool SliderFloat(const std::string& fieldLabel, float min, float max, std::function get, std::function set, + static bool SliderFloat(const std::string& fieldLabel, float const& min, float const& max, std::function get, std::function set, const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0) { float value = get(); From 416c571fd2259bb616a04648f249985ec6ee6f03 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 25 Oct 2022 17:40:13 +0800 Subject: [PATCH 34/50] Added proper deletion of VKSamplers --- SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp b/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp index 4300f2bd..7443b6e2 100644 --- a/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp +++ b/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp @@ -49,7 +49,7 @@ namespace SHADE SHVkSampler::~SHVkSampler() noexcept { if (vkSampler) - device->GetVkLogicalDevice().destroySampler(); + device->GetVkLogicalDevice().destroySampler(vkSampler); } /*-----------------------------------------------------------------------------------*/ From d1d64ec167ff76e727057d2e0725d36575ae459f Mon Sep 17 00:00:00 2001 From: Glence Date: Tue, 25 Oct 2022 18:48:45 +0800 Subject: [PATCH 35/50] added tooltips for the rest of the widgets --- SHADE_Engine/src/Editor/SHEditorWidgets.hpp | 178 ++++++++++++++++---- 1 file changed, 144 insertions(+), 34 deletions(-) diff --git a/SHADE_Engine/src/Editor/SHEditorWidgets.hpp b/SHADE_Engine/src/Editor/SHEditorWidgets.hpp index 4a299d25..b54a6799 100644 --- a/SHADE_Engine/src/Editor/SHEditorWidgets.hpp +++ b/SHADE_Engine/src/Editor/SHEditorWidgets.hpp @@ -157,7 +157,7 @@ namespace SHADE } template - static bool DragN(const std::string& fieldLabel, std::vectorconst& componentLabels, + static bool DragN(const std::string& label, std::vectorconst& componentLabels, std::vector values, float speed = 0.1f, const char* displayFormat = "", T valueMin = T(), T valueMax = T(), ImGuiSliderFlags flags = 0, bool* isHovered = nullptr) { @@ -168,11 +168,11 @@ namespace SHADE const ImGuiContext& g = *GImGui; bool valueChanged = false; ImGui::BeginGroup(); - ImGui::PushID(fieldLabel.c_str()); + ImGui::PushID(label.c_str()); PushMultiItemsWidthsAndLabels(componentLabels, 0.0f); ImGui::BeginColumns("DragVecCol", 2, ImGuiOldColumnFlags_NoBorder | ImGuiOldColumnFlags_NoResize); ImGui::SetColumnWidth(-1, 80.0f); - ImGui::Text(fieldLabel.c_str()); + ImGui::Text(label.c_str()); if (isHovered) *isHovered = ImGui::IsItemHovered(); ImGui::NextColumn(); @@ -202,12 +202,12 @@ namespace SHADE return valueChanged; } - static bool DragVec2(const std::string& fieldLabel, std::vectorconst& componentLabels, std::function get, + static bool DragVec2(const std::string& label, std::vectorconst& componentLabels, std::function get, std::function set, float speed = 0.1f, const char* displayFormat = "%.3f", std::string_view const& tooltip = {}, float valueMin = 0.0f, float valueMax = 0.0f, ImGuiSliderFlags flags = 0) { SHVec2 values = get(); - bool const changed = DragN(fieldLabel, componentLabels, { &values.x, &values.y }, speed, displayFormat, valueMin, valueMax, flags); + bool const changed = DragN(label, componentLabels, { &values.x, &values.y }, speed, displayFormat, valueMin, valueMax, flags); static bool startRecording = false; if (changed) { @@ -229,12 +229,12 @@ namespace SHADE return changed; } - static bool DragVec3(const std::string& fieldLabel, std::vectorconst& componentLabels, std::function get, + static bool DragVec3(const std::string& label, std::vectorconst& componentLabels, std::function get, std::function set, float speed = 0.1f, const char* displayFormat = "%.3f", std::string_view const& tooltip = {}, float valueMin = 0.0f, float valueMax = 0.0f, ImGuiSliderFlags flags = 0) { SHVec3 values = get(); - bool const changed = DragN(fieldLabel, componentLabels, { &values.x, &values.y, &values.z }, speed, displayFormat, valueMin, valueMax, flags); + bool const changed = DragN(label, componentLabels, { &values.x, &values.y, &values.z }, speed, displayFormat, valueMin, valueMax, flags); static bool startRecording = false; @@ -261,12 +261,12 @@ namespace SHADE return changed; } - static bool DragVec4(const std::string& fieldLabel, std::vectorconst& componentLabels, std::function get, + static bool DragVec4(const std::string& label, std::vectorconst& componentLabels, std::function get, std::function set, float speed = 0.1f, const char* displayFormat = "%.3f", std::string_view const& tooltip = {}, float valueMin = 0.0f, float valueMax = 0.0f, ImGuiSliderFlags flags = 0) { SHVec4 values = get(); - bool const changed = DragN(fieldLabel, componentLabels, { &values.x, &values.y, &values.z, &values.w }, speed, displayFormat, valueMin, valueMax, flags); + bool const changed = DragN(label, componentLabels, { &values.x, &values.y, &values.z, &values.w }, speed, displayFormat, valueMin, valueMax, flags); static bool startRecording = false; if (changed) { @@ -330,41 +330,72 @@ namespace SHADE } template - static bool RadioButton(std::vector const& listLabels, std::vector const& listTypes, std::function get, std::function set) + static bool RadioButton(std::vector const& label, std::vector const& listTypes, std::function get, std::function set ,std::string_view const& tooltip = {}) { T type = get(); + ImGui::BeginGroup(); + ImGui::PushID(label.data()); + TextLabel(label); for (size_t i = 0; i < listTypes.size(); i++) { - if (ImGui::RadioButton(listLabels[i].c_str(), type == listTypes[i])) + if (ImGui::RadioButton(label[i].c_str(), type == listTypes[i])) { SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), listTypes[i], set)), false); } ImGui::SameLine(); } + ImGui::PopID(); + ImGui::EndGroup(); + if (!tooltip.empty()) + { + if (ImGui::IsItemHovered()) + { + ImGui::BeginTooltip(); + ImGui::Text(tooltip.data()); + ImGui::EndTooltip(); + } + } return true; } static bool InputText(const std::string& label, const std::function get, - const std::function set, ImGuiInputTextFlags flag = 0, - ImGuiInputTextCallback callback = (ImGuiInputTextCallback)0, void* userData = (void*)0) + const std::function set, std::string_view const& tooltip = {}, + ImGuiInputTextFlags flag = 0, ImGuiInputTextCallback callback = (ImGuiInputTextCallback)0, void* userData = (void*)0) { std::string text = get(); - if (ImGui::InputText(label.c_str(), &text, flag, callback, userData)) + ImGui::BeginGroup(); + ImGui::PushID(label.data()); + TextLabel(label); + if (ImGui::InputText("##", &text, flag, callback, userData)) { if (ImGui::IsItemDeactivatedAfterEdit()) SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), text, set)), false); return true; } + ImGui::PopID(); + ImGui::EndGroup(); + if (!tooltip.empty()) + { + if (ImGui::IsItemHovered()) + { + ImGui::BeginTooltip(); + ImGui::Text(tooltip.data()); + ImGui::EndTooltip(); + } + } return false; } template - static bool DragScalar(const std::string& fieldLabel, ImGuiDataType data_type, std::function get, std::function set, - float speed = 1.0f, T p_min = T(), T p_max = T(), const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0) + static bool DragScalar(const std::string& label, ImGuiDataType data_type, std::function get, std::function set, + float speed = 1.0f, T p_min = T(), T p_max = T(), const char* displayFormat = "%.3f", std::string_view const& tooltip = {}, ImGuiSliderFlags flags = 0) { T value = get(); - const bool hasChange = ImGui::DragScalar(fieldLabel.c_str(), data_type, &value, speed, &p_min, &p_max, displayFormat, flags); + ImGui::BeginGroup(); + ImGui::PushID(label.data()); + TextLabel(label); + const bool hasChange = ImGui::DragScalar("##", data_type, &value, speed, &p_min, &p_max, displayFormat, flags); static bool startRecording = false; if (hasChange) { @@ -376,6 +407,17 @@ namespace SHADE { startRecording = false; } + ImGui::PopID(); + ImGui::EndGroup(); + if (!tooltip.empty()) + { + if (ImGui::IsItemHovered()) + { + ImGui::BeginTooltip(); + ImGui::Text(tooltip.data()); + ImGui::EndTooltip(); + } + } return hasChange; } @@ -412,11 +454,14 @@ namespace SHADE return hasChange; } - static bool DragInt(const std::string& fieldLabel, std::function get, std::function set, + static bool DragInt(const std::string& label, std::function get, std::function set, std::string_view const& tooltip = {}, float speed = 1.0f, int p_min = int(), int p_max = int(), const char* displayFormat = "%d", ImGuiSliderFlags flags = 0) { int value = get(); - const bool hasChange = ImGui::DragInt(fieldLabel.c_str(), &value, speed, p_min, p_max, displayFormat, flags); + ImGui::BeginGroup(); + ImGui::PushID(label.data()); + TextLabel(label); + const bool hasChange = ImGui::DragInt("##", &value, speed, p_min, p_max, displayFormat, flags); static bool startRecording = false; if (hasChange) { @@ -428,16 +473,30 @@ namespace SHADE { startRecording = false; } + ImGui::PopID(); + ImGui::EndGroup(); + if (!tooltip.empty()) + { + if (ImGui::IsItemHovered()) + { + ImGui::BeginTooltip(); + ImGui::Text(tooltip.data()); + ImGui::EndTooltip(); + } + } return hasChange; } template - static bool SliderScalar(const std::string& fieldLabel, ImGuiDataType data_type, T min, T max, std::function get, std::function set, + static bool SliderScalar(const std::string& label, ImGuiDataType data_type, T min, T max, std::function get, std::function set, std::string_view const& tooltip = {}, const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0) { T value = get(); - bool const changed = ImGui::SliderScalar(fieldLabel.c_str(), data_type, &value, &min, &max, displayFormat, flags); + ImGui::BeginGroup(); + ImGui::PushID(label.data()); + TextLabel(label); + bool const hasChange = ImGui::SliderScalar("##", data_type, &value, &min, &max, displayFormat, flags); static bool startRecording = false; - if (changed) + if (hasChange) { SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), startRecording); if (!startRecording) @@ -448,16 +507,30 @@ namespace SHADE { startRecording = false; } - return changed; + ImGui::PopID(); + ImGui::EndGroup(); + if (!tooltip.empty()) + { + if (ImGui::IsItemHovered()) + { + ImGui::BeginTooltip(); + ImGui::Text(tooltip.data()); + ImGui::EndTooltip(); + } + } + return hasChange; } - static bool SliderFloat(const std::string& fieldLabel, float const& min, float const& max, std::function get, std::function set, + static bool SliderFloat(const std::string& label, float const& min, float const& max, std::function get, std::function set, std::string_view const& tooltip = {}, const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0) { float value = get(); - bool const changed = ImGui::SliderFloat(fieldLabel.c_str(), &value, min, max, displayFormat, flags); + ImGui::BeginGroup(); + ImGui::PushID(label.data()); + TextLabel(label); + bool const hasChange = ImGui::SliderFloat("##", &value, min, max, displayFormat, flags); static bool startRecording = false; - if (changed) + if (hasChange) { SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), startRecording); if (!startRecording) @@ -468,16 +541,30 @@ namespace SHADE { startRecording = false; } - return changed; + ImGui::PopID(); + ImGui::EndGroup(); + if (!tooltip.empty()) + { + if (ImGui::IsItemHovered()) + { + ImGui::BeginTooltip(); + ImGui::Text(tooltip.data()); + ImGui::EndTooltip(); + } + } + return hasChange; } - static bool SliderInt(const std::string& fieldLabel, int min, int max, std::function get, std::function set, + static bool SliderInt(const std::string& label, int min, int max, std::function get, std::function set, std::string_view const& tooltip = {}, const char* displayFormat = "%d", ImGuiSliderFlags flags = 0) { int value = get(); - bool const changed = ImGui::SliderInt(fieldLabel.c_str(), &value, min, max, displayFormat, flags); + ImGui::BeginGroup(); + ImGui::PushID(label.data()); + TextLabel(label); + bool const hasChange = ImGui::SliderInt("##", &value, min, max, displayFormat, flags); static bool startRecording = false; - if (changed) + if (hasChange) { SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), startRecording); @@ -488,21 +575,44 @@ namespace SHADE { startRecording = false; } - return false; + ImGui::PopID(); + ImGui::EndGroup(); + if (!tooltip.empty()) + { + if (ImGui::IsItemHovered()) + { + ImGui::BeginTooltip(); + ImGui::Text(tooltip.data()); + ImGui::EndTooltip(); + } + } + return hasChange; } - static bool ComboBox(const std::string& fieldLabel, std::vector list, std::function get, std::function set) + static bool ComboBox(const std::string& label, std::vector list, std::function get, std::function set, std::string_view const& tooltip = {}) { bool edited = false; int selected = get(); - ImGui::PushID(fieldLabel.c_str()); - ImGui::Text(fieldLabel.c_str()); ImGui::SameLine(); + ImGui::BeginGroup(); + ImGui::PushID(label.c_str()); + TextLabel(label); + ImGui::SameLine(); if (edited = ImGui::Combo("##Combo", &selected, list.data(), static_cast(list.size()))) { SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), selected, set)), false); } ImGui::PopID(); + ImGui::EndGroup(); + if (!tooltip.empty()) + { + if (ImGui::IsItemHovered()) + { + ImGui::BeginTooltip(); + ImGui::Text(tooltip.data()); + ImGui::EndTooltip(); + } + } return edited; } }; From 0395df5c6305d8dcca38b49e48895158da644a73 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Tue, 25 Oct 2022 19:59:16 +0800 Subject: [PATCH 36/50] Lights WIP (bug fixes) --- .../GlobalData/SHGraphicsGlobalData.cpp | 35 ++++++++-- .../MiddleEnd/Interface/SHGraphicsConstants.h | 32 +++++++-- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 11 +++- .../MiddleEnd/Interface/SHGraphicsSystem.h | 2 + .../MiddleEnd/Lights/SHLightingSubSystem.cpp | 66 ++++++++++++------- 5 files changed, 108 insertions(+), 38 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp index ed1d3100..94d1d2c5 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp @@ -4,6 +4,8 @@ #include "Graphics/Pipeline/SHPipelineState.h" #include "Graphics/Pipeline/SHVkPipelineLayout.h" #include "Graphics/Descriptors/SHVkDescriptorSetLayout.h" +#include "Graphics/MiddleEnd/Lights/SHLightData.h" +#include "Tools/SHUtilities.h" namespace SHADE { @@ -45,16 +47,35 @@ namespace SHADE // For global data (generic data and textures) Handle staticGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS,{ genericDataBinding, texturesBinding }); - SHVkDescriptorSetLayout::Binding lightBinding + std::vector lightBindings{}; + for (uint32_t i = 0; i < SHUtilities::ToUnderlying(SH_LIGHT_TYPE::NUM_TYPES); ++i) { - .Type = vk::DescriptorType::eStorageBufferDynamic, - .Stage = vk::ShaderStageFlagBits::eFragment, - .BindPoint = SHGraphicsConstants::DescriptorSetBindings::DIRECTIONAL_LIGHT_DATA, - .DescriptorCount = 1, - }; + lightBindings.push_back (SHVkDescriptorSetLayout::Binding + { + .Type = vk::DescriptorType::eStorageBufferDynamic, + .Stage = vk::ShaderStageFlagBits::eFragment, + .BindPoint = i, + .DescriptorCount = 1, + }); + } + //SHVkDescriptorSetLayout::Binding pointLightBinding + //{ + // .Type = vk::DescriptorType::eStorageBufferDynamic, + // .Stage = vk::ShaderStageFlagBits::eFragment, + // .BindPoint = SHGraphicsConstants::DescriptorSetBindings::POINT_LIGHT_DATA, + // .DescriptorCount = 1, + //}; + + //SHVkDescriptorSetLayout::Binding spotLightBinding + //{ + // .Type = vk::DescriptorType::eStorageBufferDynamic, + // .Stage = vk::ShaderStageFlagBits::eFragment, + // .BindPoint = SHGraphicsConstants::DescriptorSetBindings::SPOT_LIGHT_DATA, + // .DescriptorCount = 1, + //}; // For Dynamic global data (lights) - Handle dynamicGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, { lightBinding }); + Handle dynamicGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, lightBindings); SHVkDescriptorSetLayout::Binding cameraDataBinding { diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h index 15f192c0..f31816ce 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h @@ -94,14 +94,32 @@ namespace SHADE /***************************************************************************/ static constexpr uint32_t IMAGE_AND_SAMPLERS_DATA = 1; - /***************************************************************************/ - /*! - \brief - DescriptorSet binding for lights. + ///***************************************************************************/ + ///*! + // \brief + // DescriptorSet binding for directional lights. - */ - /***************************************************************************/ - static constexpr uint32_t DIRECTIONAL_LIGHT_DATA = 0; + //*/ + ///***************************************************************************/ + //static constexpr uint32_t DIRECTIONAL_LIGHT_DATA = 0; + + ///***************************************************************************/ + ///*! + // \brief + // DescriptorSet binding for directional lights. + + //*/ + ///***************************************************************************/ + //static constexpr uint32_t POINT_LIGHT_DATA = 1; + + ///***************************************************************************/ + ///*! + // \brief + // DescriptorSet binding for directional lights. + + //*/ + ///***************************************************************************/ + //static constexpr uint32_t SPOT_LIGHT_DATA = 2; /***************************************************************************/ /*! diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 7ecd92d2..b7d4bd2f 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -36,6 +36,7 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/Images/SHVkSampler.h" #include "Assets/Asset Types/SHTextureAsset.h" #include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h" +#include "Graphics/MiddleEnd/Lights/SHLightingSubSystem.h" namespace SHADE { @@ -231,11 +232,15 @@ namespace SHADE for (uint32_t i = 0; i < swapchain->GetNumImages(); ++i) cmdPools.push_back(renderContext.GetFrameData(i).cmdPoolHdls[0]); + // Mouse picking system for the editor (Will still run with editor disabled) mousePickSystem->Init(device, cmdPools, worldRenderGraph->GetRenderGraphResource("Entity ID")); // Register the post offscreen render to the system postOffscreenRender = resourceManager.Create(); postOffscreenRender->Init(device, worldRenderGraph->GetRenderGraphResource("Scene"), descPool); + + lightingSubSystem = resourceManager.Create(); + lightingSubSystem->Init(device, descPool); } #ifdef SHEDITOR @@ -353,10 +358,12 @@ namespace SHADE // Begin recording the command buffer currentCmdBuffer->BeginRecording(); + // set viewport and scissor uint32_t w = static_cast(viewports[vpIndex]->GetWidth()); uint32_t h = static_cast(viewports[vpIndex]->GetHeight()); currentCmdBuffer->SetViewportScissor (static_cast(w), static_cast(h), w, h); + // Force set the pipeline layout currentCmdBuffer->ForceSetPipelineLayout(SHGraphicsGlobalData::GetDummyPipelineLayout(), SH_PIPELINE_TYPE::GRAPHICS); // Bind all the buffers required for meshes @@ -368,6 +375,8 @@ namespace SHADE currentCmdBuffer->BindIndexBuffer(buffer, 0); } + // Bind the descriptor set for lights + lightingSubSystem->Run(currentCmdBuffer, frameIndex); // Bind textures auto textureDescSet = texLibrary.GetTextureDescriptorSetGroup(); @@ -401,7 +410,7 @@ namespace SHADE renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex); #endif - // Draw first + // Draw the scene renderers[renIndex]->Draw(frameIndex, descPool); // End the command buffer recording diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index 870325ac..ae93bd78 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -32,6 +32,7 @@ of DigiPen Institute of Technology is prohibited. #include "../Textures/SHTextureLibrary.h" #include "../Textures/SHVkSamplerCache.h" #include "Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h" +#include "Graphics/MiddleEnd/Lights/SHLightingSubSystem.h" namespace SHADE { @@ -351,6 +352,7 @@ namespace SHADE // Sub systems Handle mousePickSystem; Handle postOffscreenRender; + Handle lightingSubSystem; uint32_t resizeWidth; uint32_t resizeHeight; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp index 613d50d3..30bbd363 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp @@ -94,6 +94,12 @@ namespace SHADE /***************************************************************************/ void SHLightingSubSystem::PerTypeData::Expand(Handle logicalDevice) noexcept { + if (lightDataAlignmentSize == 0) + { + SHLOG_ERROR ("One of the types of lights have not been accounted for. Make sure lightDataAlignmentSize is not nullptr."); + return; + } + // we want to wait for the command buffers to finish using the buffers first logicalDevice->WaitIdle(); @@ -159,15 +165,15 @@ namespace SHADE { case SH_LIGHT_TYPE::DIRECTIONAL: // TOOD: Change after creating point light struct - return 0; + return sizeof(SHDirectionalLightData); case SH_LIGHT_TYPE::POINT: - return sizeof (SHDirectionalLightData); + return 4; case SH_LIGHT_TYPE::SPOT: // TOOD: Change after creating spot light struct - return 0; + return 4; case SH_LIGHT_TYPE::NUM_TYPES: default: - return 0; + return 4; } } @@ -257,15 +263,18 @@ namespace SHADE void SHLightingSubSystem::PerTypeData::WriteToGPU(uint32_t frameIndex) noexcept { - // we want to write to the offset of the current frame - dataBuffer->WriteToMemory(intermediateData.get(), lightDataAlignmentSize * numLights, 0, lightDataAlignmentSize * maxLights * frameIndex); + if (intermediateData) + { + // we want to write to the offset of the current frame + dataBuffer->WriteToMemory(intermediateData.get(), lightDataAlignmentSize * numLights, 0, lightDataAlignmentSize * maxLights * frameIndex); + } } /***************************************************************************/ /*! \brief - Update descriptor sets. We want to call this everytime we expand buffers. + Update descriptor sets. We want to call this every time we expand buffers. \param binding The binding in the set we want to update. @@ -281,27 +290,29 @@ namespace SHADE binding, { &buffer, 1 }, 0, - perTypeData[binding].GetAlignmentSize()); + perTypeData[binding].GetAlignmentSize() * perTypeData[binding].GetMaxLights()); lightingDataDescSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, binding); } /***************************************************************************/ - /*! - + /*! + \brief - Computes dynamic offsets. - - */ + Computes dynamic offsets. + + */ /***************************************************************************/ void SHLightingSubSystem::ComputeDynamicOffsets(void) noexcept { - for (uint32_t i = 0; i < dynamicOffsets.size(); ++i) + for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i) { - auto const& typeData = perTypeData[i]; - for (uint32_t j = 0; j < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++j) + for (uint32_t j = 0; j < dynamicOffsets.size(); ++j) { - dynamicOffsets[i][j] = j * typeData.GetAlignmentSize() * typeData.GetMaxLights(); + auto const& typeData = perTypeData[j]; + { + dynamicOffsets[i][j] = j * typeData.GetAlignmentSize() * typeData.GetMaxLights(); + } } } } @@ -319,17 +330,26 @@ namespace SHADE void SHLightingSubSystem::Init(Handle device, Handle descPool) noexcept { logicalDevice = device; + uint32_t constexpr NUM_LIGHT_TYPES = SHUtilities::ToUnderlying(SH_LIGHT_TYPE::NUM_TYPES); - std::vector variableSizes{ SHUtilities::ToUnderlying(SH_LIGHT_TYPE::NUM_TYPES) }; + std::vector variableSizes{ NUM_LIGHT_TYPES }; std::fill (variableSizes.begin(), variableSizes.end(), 1); // Create the descriptor set lightingDataDescSet = descPool->Allocate({SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS]}, variableSizes); - // initialize all the data first. We add more lights here as we add more types. - perTypeData[SHUtilities::ToUnderlying(SH_LIGHT_TYPE::DIRECTIONAL)].InitializeData(logicalDevice, SH_LIGHT_TYPE::DIRECTIONAL); - UpdateDescSet(SHGraphicsConstants::DescriptorSetBindings::DIRECTIONAL_LIGHT_DATA); + for (uint32_t i = 0; i < NUM_LIGHT_TYPES; ++i) + { + // initialize all the data first. We add more lights here as we add more types. + perTypeData[i].InitializeData(logicalDevice, static_cast(i)); + UpdateDescSet(i); + } + + for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i) + { + dynamicOffsets[i].resize(NUM_LIGHT_TYPES); + } } /***************************************************************************/ @@ -378,8 +398,8 @@ namespace SHADE // is a new buffer. If some expansion was detected, update descriptor sets. if (expanded) { - uint32_t numLightTyes = SHUtilities::ToUnderlying(SH_LIGHT_TYPE::NUM_TYPES); - for (uint32_t i = 0; i < numLightTyes; ++i) + uint32_t constexpr NUM_LIGHT_TYPES = SHUtilities::ToUnderlying(SH_LIGHT_TYPE::NUM_TYPES); + for (uint32_t i = 0; i < NUM_LIGHT_TYPES; ++i) { UpdateDescSet(i); } From 6d9a8e484c4b08a9642a6f6ff998efd036cafc33 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Tue, 25 Oct 2022 20:55:46 +0800 Subject: [PATCH 37/50] Asset browser --- .../AssetBrowser/SHAssetBrowser.cpp | 84 +++++++++++++++++++ .../AssetBrowser/SHAssetBrowser.h | 24 ++++++ .../Inspector/SHEditorInspector.cpp | 4 +- .../EditorWindow/SHEditorWindowIncludes.h | 3 +- .../ViewportWindow/SHEditorViewport.cpp | 3 +- SHADE_Engine/src/Editor/SHEditor.cpp | 1 + 6 files changed, 115 insertions(+), 4 deletions(-) create mode 100644 SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp create mode 100644 SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h diff --git a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp new file mode 100644 index 00000000..caad9b10 --- /dev/null +++ b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp @@ -0,0 +1,84 @@ +#include "SHpch.h" +#include "SHAssetBrowser.h" + +#include "Editor/IconsMaterialDesign.h" +#include "Editor/SHImGuiHelpers.hpp" +#include + +#include "Assets/SHAssetManager.h" +#include "Editor/DragDrop/SHDragDrop.hpp" + +namespace SHADE +{ + SHAssetBrowser::SHAssetBrowser() + :SHEditorWindow("\xee\x8b\x87 Asset Browser", ImGuiWindowFlags_MenuBar) + { + } + + void SHAssetBrowser::Init() + { + SHEditorWindow::Init(); + } + + void SHAssetBrowser::Update() + { + SHEditorWindow::Update(); + if(Begin()) + { + DrawMenuBar(); + auto const& assets = SHAssetManager::GetAllAssets(); + if(ImGui::BeginTable("AssetBrowserTable", 3)) + { + ImGui::TableNextColumn(); + ImGui::TableHeader("Asset ID"); + ImGui::TableNextColumn(); + ImGui::TableHeader("Name"); + ImGui::TableNextColumn(); + ImGui::TableHeader("Type"); + for(SHAsset const& asset : assets) + { + DrawAsset(asset); + } + ImGui::EndTable(); + } + } + ImGui::End(); + } + + void SHAssetBrowser::DrawMenuBar() + { + if(ImGui::BeginMenuBar()) + { + + ImGui::EndMenuBar(); + } + } + + void SHAssetBrowser::DrawAsset(SHAsset const& asset) + { + ImGui::PushID(asset.id); + ImGui::BeginGroup(); + + ImGui::TableNextColumn(); + ImGui::Selectable(std::format("{}", asset.id).data(), false, ImGuiSelectableFlags_SpanAllColumns); + if(SHDragDrop::BeginSource()) + { + auto id = asset.id; + ImGui::Text("Moving Asset: %zu", id); + SHDragDrop::SetPayload(DRAG_RESOURCE, &id); + SHDragDrop::EndSource(); + } + + ImGui::TableNextColumn(); + ImGui::Text("%s", asset.name.c_str()); + + ImGui::TableNextColumn(); + ImGui::Text("%s", "Type"); + + ImGui::EndGroup(); + ImGui::PopID(); + + + + } +} diff --git a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h new file mode 100644 index 00000000..0e3053bc --- /dev/null +++ b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h @@ -0,0 +1,24 @@ +#pragma once + +#include "Assets/SHAsset.h" +#include "Editor/EditorWindow/SHEditorWindow.h" + +namespace SHADE +{ + class SHAssetBrowser final : public SHEditorWindow + { + public: + SHAssetBrowser(); + + void Init(); + void Update(); + + void Refresh(); + private: + void DrawMenuBar(); + void DrawAsset(SHAsset const& asset); + + float idColumnWidth, nameColumnWidth, typeColumnWidth; + + }; +} \ No newline at end of file diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp index b59ce9cc..ada5a35a 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp @@ -84,8 +84,8 @@ namespace SHADE } ImGui::Separator(); // Render Scripts - SHScriptEngine* scriptEngine = static_cast(SHSystemManager::GetSystem()); - scriptEngine->RenderScriptsInInspector(eid); + SHScriptEngine* scriptEngine = static_cast(SHSystemManager::GetSystem()); + scriptEngine->RenderScriptsInInspector(eid); ImGui::Separator(); if(ImGui::BeginMenu(std::format("{} Add Component", ICON_MD_LIBRARY_ADD).data())) { diff --git a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowIncludes.h b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowIncludes.h index f0267b06..5208c6d9 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowIncludes.h +++ b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowIncludes.h @@ -3,4 +3,5 @@ #include "HierarchyPanel/SHHierarchyPanel.h" //Hierarchy Panel #include "Inspector/SHEditorInspector.h" //Inspector #include "Profiling/SHEditorProfiler.h" //Profiler -#include "ViewportWindow/SHEditorViewport.h" //Editor Viewport \ No newline at end of file +#include "ViewportWindow/SHEditorViewport.h" //Editor Viewport +#include "AssetBrowser/SHAssetBrowser.h" //Asset Browser \ No newline at end of file diff --git a/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp index cb30fa81..f5170999 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp @@ -30,6 +30,7 @@ namespace SHADE void SHEditorViewport::Update() { SHEditorWindow::Update(); + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f,0.0f)); if(Begin()) { ImGuizmo::SetDrawlist(); @@ -55,7 +56,7 @@ namespace SHADE ImGuizmo::SetRect(beginCursorPos.x , beginCursorPos.y, beginContentRegionAvailable.x, beginContentRegionAvailable.y); transformGizmo.Draw(); ImGui::End(); - + ImGui::PopStyleVar(); } void SHEditorViewport::Exit() diff --git a/SHADE_Engine/src/Editor/SHEditor.cpp b/SHADE_Engine/src/Editor/SHEditor.cpp index 912f9d0f..06fadfee 100644 --- a/SHADE_Engine/src/Editor/SHEditor.cpp +++ b/SHADE_Engine/src/Editor/SHEditor.cpp @@ -92,6 +92,7 @@ namespace SHADE SHEditorWindowManager::CreateEditorWindow(); SHEditorWindowManager::CreateEditorWindow(); SHEditorWindowManager::CreateEditorWindow(); + SHEditorWindowManager::CreateEditorWindow(); SHEditorWindowManager::CreateEditorWindow(); io = &ImGui::GetIO(); From 534aeba06b4728e2f7a4e494e51b03ed903c34cb Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Tue, 25 Oct 2022 20:59:32 +0800 Subject: [PATCH 38/50] Latest Default Layout --- Assets/Editor/Layouts/Default.ini | 103 ++++++++++++++++++++++++------ 1 file changed, 85 insertions(+), 18 deletions(-) diff --git a/Assets/Editor/Layouts/Default.ini b/Assets/Editor/Layouts/Default.ini index 4ddc46c2..d7a7bf69 100644 --- a/Assets/Editor/Layouts/Default.ini +++ b/Assets/Editor/Layouts/Default.ini @@ -4,13 +4,13 @@ Size=1920,20 Collapsed=0 [Window][SHEditorMenuBar] -Pos=0,24 -Size=1920,1036 +Pos=0,48 +Size=1920,1012 Collapsed=0 [Window][Hierarchy Panel] -Pos=0,120 -Size=225,940 +Pos=0,197 +Size=308,863 Collapsed=0 DockId=0x00000004,0 @@ -20,29 +20,96 @@ Size=400,400 Collapsed=0 [Window][Inspector] -Pos=1686,24 -Size=234,1036 +Pos=1528,48 +Size=392,1012 Collapsed=0 DockId=0x00000006,0 [Window][Profiler] -Pos=0,24 -Size=225,94 +Pos=0,48 +Size=308,147 Collapsed=0 DockId=0x00000003,0 [Window][Viewport] -Pos=227,24 -Size=1457,1036 +Pos=227,48 +Size=1457,1012 Collapsed=0 -DockId=0x00000002,0 +DockId=0x0000000B,0 + +[Window][o] +Pos=60,60 +Size=32,64 +Collapsed=0 + +[Window][] +Pos=60,60 +Size=999,581 +Collapsed=0 + +[Window][o] +Pos=60,60 +Size=32,64 +Collapsed=0 + +[Window][] +Pos=60,60 +Size=553,422 +Collapsed=0 + +[Window][] +Pos=60,60 +Size=770,394 +Collapsed=0 + +[Window][ Viewport] +Pos=227,48 +Size=1457,1012 +Collapsed=0 +DockId=0x0000000B,0 + +[Window][ Viewport] +Pos=227,48 +Size=1457,1012 +Collapsed=0 +DockId=0x0000000B,0 + +[Window][ Viewport] +Pos=310,48 +Size=1216,715 +Collapsed=0 +DockId=0x0000000B,0 + +[Window][V] +Pos=310,722 +Size=1501,338 +Collapsed=0 +DockId=0x00000008,0 + +[Window][p] +Pos=310,750 +Size=1501,310 +Collapsed=0 +DockId=0x0000000A,0 + +[Window][ Asset Browser] +Pos=310,765 +Size=1216,295 +Collapsed=0 +DockId=0x0000000C,0 [Docking][Data] -DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,55 Size=1920,1036 Split=X - DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1684,1036 Split=X - DockNode ID=0x00000001 Parent=0x00000005 SizeRef=225,1036 Split=Y Selected=0x1E6EB881 - DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,94 Selected=0x1E6EB881 - DockNode ID=0x00000004 Parent=0x00000001 SizeRef=225,940 Selected=0xE096E5AE - DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1293,1036 CentralNode=1 Selected=0x13926F0B - DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=234,1036 Selected=0xE7039252 +DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,79 Size=1920,1012 Split=X + DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1526,1036 Split=X + DockNode ID=0x00000001 Parent=0x00000005 SizeRef=308,1036 Split=Y Selected=0x1E6EB881 + DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,147 Selected=0x1E6EB881 + DockNode ID=0x00000004 Parent=0x00000001 SizeRef=225,863 Selected=0xE096E5AE + DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1216,1036 Split=Y Selected=0xB41284E7 + DockNode ID=0x00000007 Parent=0x00000002 SizeRef=1501,672 Split=Y Selected=0xB41284E7 + DockNode ID=0x00000009 Parent=0x00000007 SizeRef=1501,700 Split=Y Selected=0xB41284E7 + DockNode ID=0x0000000B Parent=0x00000009 SizeRef=1501,715 CentralNode=1 Selected=0xB41284E7 + DockNode ID=0x0000000C Parent=0x00000009 SizeRef=1501,295 Selected=0xB128252A + DockNode ID=0x0000000A Parent=0x00000007 SizeRef=1501,310 Selected=0xD446F7B6 + DockNode ID=0x00000008 Parent=0x00000002 SizeRef=1501,338 Selected=0xD9F31532 + DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=392,1036 Selected=0xE7039252 From 388795a2db374eeb1b2c3bda8384dcd204f7020e Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Tue, 25 Oct 2022 22:13:27 +0800 Subject: [PATCH 39/50] Transform Components are Enforced through the editor for certain components --- .../Inspector/SHEditorInspector.cpp | 33 +++++-- SHADE_Engine/src/Events/SHEventManager.hpp | 3 +- .../src/Math/Transform/SHTransformSystem.cpp | 94 +++++++++---------- .../src/Math/Transform/SHTransformSystem.h | 9 +- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 6 +- SHADE_Engine/src/Physics/SHPhysicsSystem.h | 2 +- 6 files changed, 83 insertions(+), 64 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp index b59ce9cc..116ad8d6 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp @@ -35,6 +35,23 @@ namespace SHADE return selected; } + template , bool> = true, std::enable_if_t, bool> = true> + bool DrawAddComponentWithEnforcedComponentButton(EntityID const& eid) + { + bool selected = false; + if (!SHComponentManager::HasComponent(eid)) + { + if(selected = ImGui::Selectable(std::format("Add {}", rttr::type::get().get_name().data()).data()); selected) + { + if(SHComponentManager::GetComponent_s(eid) == nullptr) + SHComponentManager::AddComponent(eid); + + SHComponentManager::AddComponent(eid); + } + } + return selected; + } + SHEditorInspector::SHEditorInspector() :SHEditorWindow("Inspector", ImGuiWindowFlags_MenuBar) { @@ -90,15 +107,13 @@ namespace SHADE if(ImGui::BeginMenu(std::format("{} Add Component", ICON_MD_LIBRARY_ADD).data())) { DrawAddComponentButton(eid); - DrawAddComponentButton(eid); - DrawAddComponentButton(eid); - if(DrawAddComponentButton(eid)) - { - if(SHComponentManager::GetComponent_s(eid) == nullptr) - { - SHComponentManager::AddComponent(eid); - } - } + + // Components that require Transforms + + DrawAddComponentWithEnforcedComponentButton(eid); + DrawAddComponentWithEnforcedComponentButton(eid); + DrawAddComponentWithEnforcedComponentButton(eid); + ImGui::EndMenu(); } diff --git a/SHADE_Engine/src/Events/SHEventManager.hpp b/SHADE_Engine/src/Events/SHEventManager.hpp index f511518a..490c6b10 100644 --- a/SHADE_Engine/src/Events/SHEventManager.hpp +++ b/SHADE_Engine/src/Events/SHEventManager.hpp @@ -12,6 +12,7 @@ #include "SHpch.h" #include "SHEvent.h" #include "SHEventReceiver.h" +#include "SH_API.h" /****************************************************************************** INSTRUCTIONS FOR USE: @@ -67,7 +68,7 @@ namespace SHADE using EventManagerListener = std::function; - class SHEventManager + class SH_API SHEventManager { private: diff --git a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp index 5a540cd4..4ab6b909 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp +++ b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp @@ -61,9 +61,9 @@ namespace SHADE void SHTransformSystem::Init() { - std::shared_ptr thisReceiver { std::make_shared>(this, &SHTransformSystem::ChangeParent) }; - ReceiverPtr receiver = std::dynamic_pointer_cast(thisReceiver); - SHEventManager::SubscribeTo(SH_SCENEGRAPH_CHANGE_PARENT_EVENT, receiver); + std::shared_ptr thisChangeParentReceiver { std::make_shared>(this, &SHTransformSystem::ChangeParent) }; + ReceiverPtr changeParentReceiver = std::dynamic_pointer_cast(thisChangeParentReceiver); + SHEventManager::SubscribeTo(SH_SCENEGRAPH_CHANGE_PARENT_EVENT, changeParentReceiver); } void SHTransformSystem::Exit() @@ -75,50 +75,6 @@ namespace SHADE /* Private Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ - SHEventHandle SHTransformSystem::ChangeParent(SHEventPtr changeParentEvent) - { - const auto& eventData = reinterpret_cast*>(changeParentEvent.get()); - - auto* node = eventData->data->node; - auto* tf = SHComponentManager::GetComponent_s(node->GetEntityID()); - - // Recompute local transform and store localToWorld Matrix - SHMatrix localToWorld = SHMatrix::Identity; - SHMatrix worldToLocal = SHMatrix::Identity; - - auto* newParent = eventData->data->newParent; - const auto* PARENT_TF = SHComponentManager::GetComponent_s(newParent->GetEntityID()); - if (PARENT_TF != nullptr) // Not the root - { - localToWorld = PARENT_TF->GetTRS(); - worldToLocal = SHMatrix::Inverse(localToWorld); - } - - // Maintain World Transform and recompute Local Transform - - // Compute Local Position - tf->local.position = SHVec3::Transform(tf->world.position, worldToLocal); - - - tf->localRotation = tf->worldRotation; - tf->local.scale = tf->world.scale; - - if (PARENT_TF != nullptr) - { - // Compute Local Rotation - tf->localRotation -= PARENT_TF->GetLocalRotation(); - - // Compute Local Scale - tf->local.scale /= PARENT_TF->GetLocalScale(); - } - - tf->local.trs = localToWorld; - - // Propagate maintaining world transform down the branch - UpdateChildrenLocalTransforms(node); - return eventData->handle; - } - void SHTransformSystem::UpdateChildrenLocalTransforms(SHSceneNode* node) { // Structure is similar to update entity, albeit without a queue to do being a forced update @@ -300,4 +256,48 @@ namespace SHADE tf.world.ComputeTRS(); } + SHEventHandle SHTransformSystem::ChangeParent(SHEventPtr changeParentEvent) + { + const auto& eventData = reinterpret_cast*>(changeParentEvent.get()); + + auto* node = eventData->data->node; + auto* tf = SHComponentManager::GetComponent_s(node->GetEntityID()); + + // Recompute local transform and store localToWorld Matrix + SHMatrix localToWorld = SHMatrix::Identity; + SHMatrix worldToLocal = SHMatrix::Identity; + + auto* newParent = eventData->data->newParent; + const auto* PARENT_TF = SHComponentManager::GetComponent_s(newParent->GetEntityID()); + if (PARENT_TF != nullptr) // Not the root + { + localToWorld = PARENT_TF->GetTRS(); + worldToLocal = SHMatrix::Inverse(localToWorld); + } + + // Maintain World Transform and recompute Local Transform + + // Compute Local Position + tf->local.position = SHVec3::Transform(tf->world.position, worldToLocal); + + + tf->localRotation = tf->worldRotation; + tf->local.scale = tf->world.scale; + + if (PARENT_TF != nullptr) + { + // Compute Local Rotation + tf->localRotation -= PARENT_TF->GetLocalRotation(); + + // Compute Local Scale + tf->local.scale /= PARENT_TF->GetLocalScale(); + } + + tf->local.trs = localToWorld; + + // Propagate maintaining world transform down the branch + UpdateChildrenLocalTransforms(node); + return eventData->handle; + } + } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Math/Transform/SHTransformSystem.h b/SHADE_Engine/src/Math/Transform/SHTransformSystem.h index e63969ce..f09da3ea 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformSystem.h +++ b/SHADE_Engine/src/Math/Transform/SHTransformSystem.h @@ -11,9 +11,9 @@ #pragma once // Project Headers -#include "SHTransformComponent.h" -#include "Scene/SHSceneGraph.h" #include "ECS_Base/System/SHSystemRoutine.h" +#include "Scene/SHSceneGraph.h" +#include "SHTransformComponent.h" namespace SHADE { @@ -111,11 +111,14 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ - SHEventHandle ChangeParent (SHEventPtr changeParentEvent); static void UpdateChildrenLocalTransforms (SHSceneNode* node); static void UpdateEntity (const SHSceneNode* node, bool clearDirtyFlag); static void UpdateTransform (SHTransformComponent& tf, const SHTransformComponent* parent = nullptr); + + // Event Handlers + + SHEventHandle ChangeParent (SHEventPtr changeParentEvent); }; diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index a1994ad2..f989e41d 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -203,7 +203,7 @@ namespace SHADE // SHLOG_INFO("Adding a Rigidbody to the Physics World.") //#endif - auto* physicsObject = CreatePhysicsObject(entityID); + auto* physicsObject = EnsurePhysicsObject(entityID); physicsObject->CreateRigidBody ( @@ -219,7 +219,7 @@ namespace SHADE // SHLOG_INFO("Adding a Collider to the Physics World.") //#endif - auto* physicsObject = CreatePhysicsObject(entityID); + auto* physicsObject = EnsurePhysicsObject(entityID); physicsObject->CreateCollisionBody ( @@ -359,7 +359,7 @@ namespace SHADE /* Private Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ - SHPhysicsObject* SHPhysicsSystem::CreatePhysicsObject(EntityID entityID) noexcept + SHPhysicsObject* SHPhysicsSystem::EnsurePhysicsObject(EntityID entityID) noexcept { const auto it = map.find(entityID); if (it == map.end()) diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/SHPhysicsSystem.h index bc6a1ba2..37d98300 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.h @@ -186,7 +186,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Function Members */ /*---------------------------------------------------------------------------------*/ - SHPhysicsObject* CreatePhysicsObject (EntityID entityID) noexcept; + SHPhysicsObject* EnsurePhysicsObject (EntityID entityID) noexcept; SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept; void DestroyPhysicsObject (EntityID entityID) noexcept; From 3c5a1b73d6f1bde4c5980f694f34c040d76e49fb Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Tue, 25 Oct 2022 22:26:07 +0800 Subject: [PATCH 40/50] Fixed bug with destroying a rigidbody component --- .../Components/SHRigidBodyComponent.cpp | 72 +++---------------- SHADE_Engine/src/Physics/SHPhysicsObject.cpp | 7 +- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 44 ++---------- SHADE_Engine/src/Physics/SHPhysicsSystem.h | 18 +---- 4 files changed, 19 insertions(+), 122 deletions(-) diff --git a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp index e5938717..4c620ad0 100644 --- a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp +++ b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp @@ -289,98 +289,42 @@ namespace SHADE void SHRigidBodyComponent::AddForce(const SHVec3& force) const noexcept { - if (!system) - { - SHLOG_ERROR("Physics system does not exist, unable to Add Force to a body!") - return; - } - - // Notify Physics Systems - system->AddForce(GetEID(), force); + } void SHRigidBodyComponent::AddForceAtLocalPos(const SHVec3& force, const SHVec3& localPos) const noexcept { - if (!system) - { - SHLOG_ERROR("Physics system does not exist, unable to Add Force to a body!") - return; - } - - // Notify Physics Systems - system->AddForceAtLocalPos(GetEID(), force, localPos); + } void SHRigidBodyComponent::AddForceAtWorldPos(const SHVec3& force, const SHVec3& worldPos) const noexcept { - if (!system) - { - SHLOG_ERROR("Physics system does not exist, unable to Add Force to a body!") - return; - } - - // Notify Physics Systems - system->AddForceAtWorldPos(GetEID(), force, worldPos); + } void SHRigidBodyComponent::AddRelativeForce(const SHVec3& relativeForce) const noexcept { - if (!system) - { - SHLOG_ERROR("Physics system does not exist, unable to Add Force to a body!") - return; - } - - // Notify Physics Systems - system->AddRelativeForce(GetEID(), force); + } void SHRigidBodyComponent::AddRelativeForceAtLocalPos(const SHVec3& relativeForce, const SHVec3& localPos) const noexcept { - if (!system) - { - SHLOG_ERROR("Physics system does not exist, unable to Add Force to a body!") - return; - } - - // Notify Physics Systems - system->AddRelativeForceAtLocalPos(GetEID(), force, localPos); + } void SHRigidBodyComponent::AddRelativeForceAtWorldPos(const SHVec3& relativeForce, const SHVec3& worldPos) const noexcept { - if (!system) - { - SHLOG_ERROR("Physics system does not exist, unable to Add Force to a body!") - return; - } - - // Notify Physics Systems - system->AddRelativeForceAtWorldPos(GetEID(), force, worldPos); + } void SHRigidBodyComponent::AddTorque(const SHVec3& torque) const noexcept { - if (!system) - { - SHLOG_ERROR("Physics system does not exist, unable to Add Force to a body!") - return; - } - - // Notify Physics Systems - system->AddTorque(GetEID(), torque); + } void SHRigidBodyComponent::AddRelativeTorque(const SHVec3& relativeTorque) const noexcept { - if (!system) - { - SHLOG_ERROR("Physics system does not exist, unable to Add Force to a body!") - return; - } - - // Notify Physics Systems - system->AddRelativeTorque(GetEID(), relativeTorque); + } } // namespace SHADE diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp index f9b476ef..91e7a3dc 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp @@ -133,7 +133,7 @@ namespace SHADE void SHPhysicsObject::CreateRigidBody(const SHTransformComponent* tf, SHRigidBodyComponent* rb, SHColliderComponent* c) { // If collider already exists, recreate the collision body as a rigid body - if (hasColliders) + if (c != nullptr) world->destroyCollisionBody(rp3dBody); rp3dBody = world->createRigidBody(rp3d::Transform{ tf->GetWorldPosition(), tf->GetWorldRotation() }); @@ -142,7 +142,7 @@ namespace SHADE rb->position = tf->GetWorldPosition(); rb->orientation = SHQuaternion::FromEuler(tf->GetWorldRotation()); - if (hasColliders) + if (c != nullptr) { c->position = tf->GetWorldPosition(); c->orientation = SHQuaternion::FromEuler(tf->GetWorldRotation()); @@ -196,8 +196,9 @@ namespace SHADE void SHPhysicsObject::DestroyRigidBody(SHColliderComponent* c) noexcept { world->destroyRigidBody(reinterpret_cast(rp3dBody)); + rp3dBody = nullptr; - if (hasColliders) + if (c != nullptr) { // Preserve colliders as a collision body rp3dBody = world->createCollisionBody(rp3d::Transform{ c->position, c->orientation }); diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index f989e41d..334fc6c5 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -250,46 +250,6 @@ namespace SHADE #endif } - void SHPhysicsSystem::AddForce(EntityID entityID, const SHVec3& force) const noexcept - { - - } - - void SHPhysicsSystem::AddForceAtLocalPos(EntityID entityID, const SHVec3& force, const SHVec3& localPos) const noexcept - { - - } - - void SHPhysicsSystem::AddForceAtWorldPos(EntityID entityID, const SHVec3& force, const SHVec3& worldPos) const noexcept - { - - } - - void SHPhysicsSystem::AddRelativeForce(EntityID entityID, const SHVec3& relativeForce) const noexcept - { - - } - - void SHPhysicsSystem::AddRelativeForceAtLocalPos(EntityID entityID, const SHVec3& relativeForce, const SHVec3& localPos) const noexcept - { - - } - - void SHPhysicsSystem::AddRelativeForceAtWorldPos(EntityID entityID, const SHVec3& relativeForce, const SHVec3& worldPos) const noexcept - { - - } - - void SHPhysicsSystem::AddTorque(EntityID entityID, const SHVec3& torque) const noexcept - { - - } - - void SHPhysicsSystem::AddRelativeTorque(EntityID entityID, const SHVec3& relativeTorque) const noexcept - { - - } - void SHPhysicsSystem::AddCollisionShape(EntityID entityID, SHCollider* collider) { auto* physicsObject = GetPhysicsObject(entityID); @@ -312,6 +272,10 @@ namespace SHADE // Sync transforms for (auto& physicsObject : system->map | std::views::values) { + // Ensure a valid physics Object + if (physicsObject.rp3dBody == nullptr) + continue; + const auto* TF = SHComponentManager::GetComponent(physicsObject.entityID); if (TF->HasChanged()) { diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/SHPhysicsSystem.h index 37d98300..933b36af 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.h @@ -32,7 +32,7 @@ namespace SHADE /* Type Definitions */ /*-----------------------------------------------------------------------------------*/ - class SH_API SHPhysicsSystem : public SHSystem + class SH_API SHPhysicsSystem final : public SHSystem { public: /*---------------------------------------------------------------------------------*/ @@ -90,17 +90,6 @@ namespace SHADE void RemoveRigidBody (EntityID entityID) noexcept; void RemoveCollider (EntityID entityID) noexcept; - void AddForce (EntityID entityID, const SHVec3& force) const noexcept; - void AddForceAtLocalPos (EntityID entityID, const SHVec3& force, const SHVec3& localPos) const noexcept; - void AddForceAtWorldPos (EntityID entityID, const SHVec3& force, const SHVec3& worldPos) const noexcept; - - void AddRelativeForce (EntityID entityID, const SHVec3& relativeForce) const noexcept; - void AddRelativeForceAtLocalPos (EntityID entityID, const SHVec3& relativeForce, const SHVec3& localPos) const noexcept; - void AddRelativeForceAtWorldPos (EntityID entityID, const SHVec3& relativeForce, const SHVec3& worldPos) const noexcept; - - void AddTorque (EntityID entityID, const SHVec3& torque) const noexcept; - void AddRelativeTorque (EntityID entityID, const SHVec3& relativeTorque) const noexcept; - void AddCollisionShape (EntityID entityID, SHCollider* collider); void RemoveCollisionShape (EntityID entityID, int index); @@ -170,15 +159,14 @@ namespace SHADE /* Data Members */ /*---------------------------------------------------------------------------------*/ - // TODO(Diren): Store interpFactor - bool worldUpdated; double interpolationFactor; double fixedDT; - rp3d::PhysicsWorld* world; + rp3d::PhysicsWorld* world; rp3d::PhysicsCommon factory; + EntityObjectMap map; From 0defa58c77f6d700943fa3f0296758045fd0df4b Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Tue, 25 Oct 2022 23:09:46 +0800 Subject: [PATCH 41/50] Physics Component Synchronisation is now done through events --- .../src/Math/Transform/SHTransformSystem.cpp | 15 +- .../src/Math/Transform/SHTransformSystem.h | 22 --- .../Components/SHColliderComponent.cpp | 12 +- .../Components/SHRigidBodyComponent.cpp | 14 +- SHADE_Engine/src/Physics/SHPhysicsObject.cpp | 40 ----- SHADE_Engine/src/Physics/SHPhysicsObject.h | 6 +- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 155 ++++++++++++------ SHADE_Engine/src/Physics/SHPhysicsSystem.h | 26 ++- 8 files changed, 143 insertions(+), 147 deletions(-) diff --git a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp index 4ab6b909..a2ab6880 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp +++ b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp @@ -61,9 +61,9 @@ namespace SHADE void SHTransformSystem::Init() { - std::shared_ptr thisChangeParentReceiver { std::make_shared>(this, &SHTransformSystem::ChangeParent) }; - ReceiverPtr changeParentReceiver = std::dynamic_pointer_cast(thisChangeParentReceiver); - SHEventManager::SubscribeTo(SH_SCENEGRAPH_CHANGE_PARENT_EVENT, changeParentReceiver); + const std::shared_ptr CHANGE_PARENT_RECEIVER { std::make_shared>(this, &SHTransformSystem::ChangeParent) }; + const ReceiverPtr CHANGE_PARENT_RECEIVER_PTR = std::dynamic_pointer_cast(CHANGE_PARENT_RECEIVER); + SHEventManager::SubscribeTo(SH_SCENEGRAPH_CHANGE_PARENT_EVENT, CHANGE_PARENT_RECEIVER_PTR); } void SHTransformSystem::Exit() @@ -258,16 +258,16 @@ namespace SHADE SHEventHandle SHTransformSystem::ChangeParent(SHEventPtr changeParentEvent) { - const auto& eventData = reinterpret_cast*>(changeParentEvent.get()); + const auto& EVENT_DATA = reinterpret_cast*>(changeParentEvent.get()); - auto* node = eventData->data->node; + auto* node = EVENT_DATA->data->node; auto* tf = SHComponentManager::GetComponent_s(node->GetEntityID()); // Recompute local transform and store localToWorld Matrix SHMatrix localToWorld = SHMatrix::Identity; SHMatrix worldToLocal = SHMatrix::Identity; - auto* newParent = eventData->data->newParent; + auto* newParent = EVENT_DATA->data->newParent; const auto* PARENT_TF = SHComponentManager::GetComponent_s(newParent->GetEntityID()); if (PARENT_TF != nullptr) // Not the root { @@ -297,7 +297,8 @@ namespace SHADE // Propagate maintaining world transform down the branch UpdateChildrenLocalTransforms(node); - return eventData->handle; + + return EVENT_DATA->handle; } } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Math/Transform/SHTransformSystem.h b/SHADE_Engine/src/Math/Transform/SHTransformSystem.h index f09da3ea..bb373f3a 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformSystem.h +++ b/SHADE_Engine/src/Math/Transform/SHTransformSystem.h @@ -53,17 +53,6 @@ namespace SHADE /*-------------------------------------------------------------------------------*/ TransformPostLogicUpdate (); - ~TransformPostLogicUpdate () = default; - - TransformPostLogicUpdate (const TransformPostLogicUpdate&) = delete; - TransformPostLogicUpdate (TransformPostLogicUpdate&&) = delete; - - /*-------------------------------------------------------------------------------*/ - /* Operator Overloads */ - /*-------------------------------------------------------------------------------*/ - - TransformPostLogicUpdate& operator= (const TransformPostLogicUpdate&) = delete; - TransformPostLogicUpdate& operator= (TransformPostLogicUpdate&&) = delete; /*-------------------------------------------------------------------------------*/ /* Function Members */ @@ -80,17 +69,6 @@ namespace SHADE /*-------------------------------------------------------------------------------*/ TransformPostPhysicsUpdate (); - ~TransformPostPhysicsUpdate () = default; - - TransformPostPhysicsUpdate (const TransformPostPhysicsUpdate&) = delete; - TransformPostPhysicsUpdate (TransformPostPhysicsUpdate&&) = delete; - - /*-------------------------------------------------------------------------------*/ - /* Operator Overloads */ - /*-------------------------------------------------------------------------------*/ - - TransformPostPhysicsUpdate& operator= (const TransformPostPhysicsUpdate&) = delete; - TransformPostPhysicsUpdate& operator= (TransformPostPhysicsUpdate&&) = delete; /*-------------------------------------------------------------------------------*/ /* Function Members */ diff --git a/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp b/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp index 71183f00..242b8d8f 100644 --- a/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp +++ b/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp @@ -69,13 +69,13 @@ namespace SHADE void SHColliderComponent::OnCreate() { system = SHSystemManager::GetSystem(); - if (!system) - { - SHLOG_ERROR("Physics system does not exist, Collider Component not added!") - return; - } + //if (!system) + //{ + // SHLOG_ERROR("Physics system does not exist, Collider Component not added!") + // return; + //} - system->AddCollider(GetEID()); + //system->AddCollider(GetEID()); } void SHColliderComponent::OnDestroy() diff --git a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp index 4c620ad0..934b67f6 100644 --- a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp +++ b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp @@ -265,14 +265,14 @@ namespace SHADE void SHRigidBodyComponent::OnCreate() { system = SHSystemManager::GetSystem(); - if (!system) - { - SHLOG_ERROR("Physics system does not exist, Rigid Body Component not added!") - return; - } + //if (!system) + //{ + // SHLOG_ERROR("Physics system does not exist, Rigid Body Component not added!") + // return; + //} - // Notify Physics System - system->AddRigidBody(GetEID()); + //// Notify Physics System + //system->AddRigidBody(GetEID()); } void SHRigidBodyComponent::OnDestroy() diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp index 91e7a3dc..8c067482 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp @@ -26,8 +26,6 @@ namespace SHADE SHPhysicsObject::SHPhysicsObject(EntityID eid, rp3d::PhysicsCommon* physicsFactory, rp3d::PhysicsWorld* physicsWorld) noexcept : entityID { eid } - , isRigidBody { false } - , hasColliders{ false } , factory { physicsFactory } , world { physicsWorld } , rp3dBody { nullptr } @@ -130,42 +128,6 @@ namespace SHADE /* Public Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ - void SHPhysicsObject::CreateRigidBody(const SHTransformComponent* tf, SHRigidBodyComponent* rb, SHColliderComponent* c) - { - // If collider already exists, recreate the collision body as a rigid body - if (c != nullptr) - world->destroyCollisionBody(rp3dBody); - - rp3dBody = world->createRigidBody(rp3d::Transform{ tf->GetWorldPosition(), tf->GetWorldRotation() }); - isRigidBody = true; - - rb->position = tf->GetWorldPosition(); - rb->orientation = SHQuaternion::FromEuler(tf->GetWorldRotation()); - - if (c != nullptr) - { - c->position = tf->GetWorldPosition(); - c->orientation = SHQuaternion::FromEuler(tf->GetWorldRotation()); - // Get array of colliders and add them back into the rigidbody - for (auto& collider : c->colliders | std::views::keys) - AddCollider(&collider); - } - } - - void SHPhysicsObject::CreateCollisionBody(const SHTransformComponent* tf, SHColliderComponent* c) - { - if (rp3dBody == nullptr) - rp3dBody = world->createCollisionBody(rp3d::Transform{ tf->GetWorldPosition(), tf->GetWorldRotation() }); - - hasColliders = true; - - c->position = tf->GetWorldPosition(); - c->orientation = SHQuaternion::FromEuler(tf->GetWorldRotation()); - - for (auto& collider : c->colliders | std::views::keys) - AddCollider(&collider); - } - int SHPhysicsObject::AddCollider(SHCollider* collider) { switch (collider->GetType()) @@ -205,8 +167,6 @@ namespace SHADE for (auto& collider : c->colliders | std::views::keys) AddCollider(&collider); } - - isRigidBody = false; } void SHPhysicsObject::DestroyCollisionBody() noexcept diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.h b/SHADE_Engine/src/Physics/SHPhysicsObject.h index 39a85421..11e41ad1 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.h +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.h @@ -69,8 +69,8 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ - void CreateRigidBody (const SHTransformComponent* tf, SHRigidBodyComponent* rb, SHColliderComponent* c); - void CreateCollisionBody (const SHTransformComponent* tf, SHColliderComponent* c); + void CreateRigidBody (const SHVec3& pos, const SHQuaternion& orientation); + void CreateCollisionBody (const SHVec3& pos, const SHQuaternion& orientation); int AddCollider (SHCollider* collider); void DestroyRigidBody (SHColliderComponent* c) noexcept; @@ -86,8 +86,6 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ EntityID entityID; - bool isRigidBody; - bool hasColliders; rp3d::PhysicsCommon* factory; rp3d::PhysicsWorld* world; diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index 334fc6c5..76e54b09 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -175,11 +175,9 @@ namespace SHADE void SHPhysicsSystem::Init() { - using namespace rp3d; - // Create a physics world with the default settings - PhysicsWorld::WorldSettings settings; - settings.gravity = Vector3{ 0.0f, -9.81f, 0.0f }; + rp3d::PhysicsWorld::WorldSettings settings; + settings.gravity = SHVec3{ 0.0f, -9.81f, 0.0f }; settings.isSleepingEnabled = true; settings.defaultVelocitySolverNbIterations = 8; settings.defaultPositionSolverNbIterations = 3; @@ -190,6 +188,12 @@ namespace SHADE // Set up solvers world->setContactsPositionCorrectionTechnique(rp3d::ContactsPositionCorrectionTechnique::SPLIT_IMPULSES); + + // Subscribe to component events + + const std::shared_ptr ADD_COMPONENT_RECEIVER { std::make_shared>(this, &SHPhysicsSystem::AddPhysicsComponent) }; + const ReceiverPtr ADD_COMPONENT_RECEIVER_PTR = std::dynamic_pointer_cast(ADD_COMPONENT_RECEIVER); + SHEventManager::SubscribeTo(SH_COMPONENT_ADDED_EVENT, ADD_COMPONENT_RECEIVER_PTR); } void SHPhysicsSystem::Exit() @@ -197,36 +201,29 @@ namespace SHADE factory.destroyPhysicsWorld(world); } - void SHPhysicsSystem::AddRigidBody(EntityID entityID) noexcept - { - //#ifdef _DEBUG - // SHLOG_INFO("Adding a Rigidbody to the Physics World.") - //#endif + //void SHPhysicsSystem::AddRigidBody(EntityID entityID) noexcept + //{ + // //#ifdef _DEBUG + // // SHLOG_INFO("Adding a Rigidbody to the Physics World.") + // //#endif - auto* physicsObject = EnsurePhysicsObject(entityID); + // + //} - physicsObject->CreateRigidBody - ( - EnsureTransform(entityID), - SHComponentManager::GetComponent(entityID), - SHComponentManager::GetComponent_s(entityID) - ); - } + //void SHPhysicsSystem::AddCollider(EntityID entityID) noexcept + //{ + // //#ifdef _DEBUG + // // SHLOG_INFO("Adding a Collider to the Physics World.") + // //#endif - void SHPhysicsSystem::AddCollider(EntityID entityID) noexcept - { - //#ifdef _DEBUG - // SHLOG_INFO("Adding a Collider to the Physics World.") - //#endif + // auto* physicsObject = EnsurePhysicsObject(entityID); - auto* physicsObject = EnsurePhysicsObject(entityID); - - physicsObject->CreateCollisionBody - ( - EnsureTransform(entityID), - SHComponentManager::GetComponent(entityID) - ); - } + // physicsObject->CreateCollisionBody + // ( + // SHComponentManager::GetComponent(entityID), + // SHComponentManager::GetComponent(entityID) + // ); + //} void SHPhysicsSystem::RemoveRigidBody(EntityID entityID) noexcept { @@ -415,15 +412,18 @@ namespace SHADE const rp3d::Transform CURRENT_TF = physicsObject.rp3dBody->getTransform(); + auto* rigidBodyComponent = SHComponentManager::GetComponent_s(entityID); + auto* colliderComponent = SHComponentManager::GetComponent_s(entityID); + // Check if transform should be interpolated - if (physicsObject.isRigidBody) + if (rigidBodyComponent != nullptr) { - auto* rbComponent = SHComponentManager::GetComponent(entityID); - if (rbComponent->GetType() == SHRigidBodyComponent::Type::STATIC) + + if (rigidBodyComponent->GetType() == SHRigidBodyComponent::Type::STATIC) continue; - if (rbComponent->IsInterpolating()) + if (rigidBodyComponent->IsInterpolating()) { const rp3d::Transform PREV_TF = physicsObject.prevTransform; const rp3d::Transform INTERPOLATED_TF = rp3d::Transform::interpolateTransforms(PREV_TF, CURRENT_TF, static_cast(interpolationFactor)); @@ -438,12 +438,12 @@ namespace SHADE rp3dRot = CURRENT_TF.getOrientation(); } - rbComponent->position = CURRENT_TF.getPosition(); - rbComponent->orientation = CURRENT_TF.getOrientation(); + rigidBodyComponent->position = CURRENT_TF.getPosition(); + rigidBodyComponent->orientation = CURRENT_TF.getOrientation(); - if (physicsObject.hasColliders) + if (colliderComponent != nullptr) { - auto* colliderComponent = SHComponentManager::GetComponent(entityID); + colliderComponent->position = CURRENT_TF.getPosition(); colliderComponent->orientation = CURRENT_TF.getOrientation(); } @@ -457,26 +457,89 @@ namespace SHADE // Convert RP3D Transform to SHADE auto* tfComponent = SHComponentManager::GetComponent(entityID); tfComponent->SetWorldPosition(rp3dPos); - tfComponent->SetWorldOrientation(SHQuaternion{ rp3dRot }); + tfComponent->SetWorldOrientation(rp3dRot); // Cache transforms physicsObject.prevTransform = CURRENT_TF; } } - SHTransformComponent* SHPhysicsSystem::EnsureTransform(EntityID entityID) + SHEventHandle SHPhysicsSystem::AddPhysicsComponent(SHEventPtr addComponentEvent) { - auto* tf = SHComponentManager::GetComponent_s(entityID); + const auto& EVENT_DATA = reinterpret_cast*>(addComponentEvent.get()); - // Possibly redundant - if (!tf) + static const auto RIGID_BODY_ID = ComponentFamily::GetID(); + static const auto COLLIDER_ID = ComponentFamily::GetID(); + + const auto COMPONENT_ADDED_ID = EVENT_DATA->data->addedComponentType; + const bool IS_PHYSICS_COMPONENT = COMPONENT_ADDED_ID == RIGID_BODY_ID || COMPONENT_ADDED_ID == COLLIDER_ID; + if (IS_PHYSICS_COMPONENT) { - SHComponentManager::AddComponent(entityID); - tf = SHComponentManager::GetComponent(entityID); + const EntityID ENTITY_ID = EVENT_DATA->data->eid; + auto* physicsObject = EnsurePhysicsObject(ENTITY_ID); + + auto* transformComponent = SHComponentManager::GetComponent_s(ENTITY_ID); + if (transformComponent == nullptr) + { + SHLOG_ERROR("Entity {} cannot add a Physics Component without a Transform! Component not created!", ENTITY_ID) + return EVENT_DATA->handle; + } + + auto* rigidBodyComponent = SHComponentManager::GetComponent_s(ENTITY_ID); + auto* colliderComponent = SHComponentManager::GetComponent_s(ENTITY_ID); + + if (COMPONENT_ADDED_ID == RIGID_BODY_ID) + { + if (colliderComponent != nullptr) + { + world->destroyCollisionBody(physicsObject->rp3dBody); + physicsObject->rp3dBody = nullptr; + } + + rigidBodyComponent->position = transformComponent->GetWorldPosition(); + rigidBodyComponent->orientation = transformComponent->GetWorldOrientation(); + + physicsObject->rp3dBody = world->createRigidBody + ( + rp3d::Transform{ rigidBodyComponent->position, rigidBodyComponent->orientation } + ); + + + // Add collision shapes back into the body + if (colliderComponent != nullptr) + { + for (auto& collider : colliderComponent->colliders | std::views::keys) + physicsObject->AddCollider(&collider); + } + } + + if (COMPONENT_ADDED_ID == COLLIDER_ID) + { + colliderComponent->position = transformComponent->GetWorldPosition(); + colliderComponent->orientation = transformComponent->GetWorldOrientation(); + + if (physicsObject->rp3dBody == nullptr) + { + physicsObject->rp3dBody = world->createCollisionBody + ( + rp3d::Transform{ colliderComponent->position, colliderComponent->orientation } + ); + } + + // Add Collision Shapes + for (auto& collider : colliderComponent->colliders | std::views::keys) + physicsObject->AddCollider(&collider); + } } - return tf; + return EVENT_DATA->handle; } + SHEventHandle SHPhysicsSystem::RemovePhysicsComponent(SHEventPtr removeComponentEvent) + { + const auto& EVENT_DATA = reinterpret_cast*>(removeComponentEvent.get()); + + return EVENT_DATA->handle; + } } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/SHPhysicsSystem.h index 933b36af..d88f8c06 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.h @@ -16,14 +16,14 @@ #include // Project Headers -#include "SHPhysicsObject.h" #include "Components/SHRigidBodyComponent.h" #include "Components/SHColliderComponent.h" -#include "Math/Transform/SHTransformComponent.h" - -#include "Scene/SHSceneGraph.h" #include "ECS_Base/System/SHSystemRoutine.h" #include "ECS_Base/System/SHFixedSystemRoutine.h" +#include "Math/Transform/SHTransformComponent.h" +#include "Scene/SHSceneGraph.h" +#include "SHPhysicsObject.h" + namespace SHADE @@ -85,8 +85,8 @@ namespace SHADE void Init () override; void Exit () override; - void AddRigidBody (EntityID entityID) noexcept; - void AddCollider (EntityID entityID) noexcept; + //void AddRigidBody (EntityID entityID) noexcept; + //void AddCollider (EntityID entityID) noexcept; void RemoveRigidBody (EntityID entityID) noexcept; void RemoveCollider (EntityID entityID) noexcept; @@ -97,10 +97,7 @@ namespace SHADE /* System Routines */ /*---------------------------------------------------------------------------------*/ - /** - * @brief Synchronises RP3D with SHADE - */ - class SH_API PhysicsPreUpdate : public SHSystemRoutine + class SH_API PhysicsPreUpdate final : public SHSystemRoutine { public: /*-------------------------------------------------------------------------------*/ @@ -116,7 +113,7 @@ namespace SHADE void Execute(double dt) noexcept override; }; - class SH_API PhysicsFixedUpdate : public SHFixedSystemRoutine + class SH_API PhysicsFixedUpdate final : public SHFixedSystemRoutine { public: /*-------------------------------------------------------------------------------*/ @@ -132,7 +129,7 @@ namespace SHADE void Execute (double dt) noexcept override; }; - class SH_API PhysicsPostUpdate : public SHSystemRoutine + class SH_API PhysicsPostUpdate final : public SHSystemRoutine { public: /*-------------------------------------------------------------------------------*/ @@ -182,10 +179,9 @@ namespace SHADE void SyncRigidBodyComponents (std::vector& denseArray) noexcept; void SyncColliderComponents (std::vector& denseArray) noexcept; void SyncTransforms () noexcept; - // TODO(Diren): Trigger handling - // TODO(Diren): Remove when responsibility shifted to editor - SHTransformComponent* EnsureTransform (EntityID entityID); + SHEventHandle AddPhysicsComponent (SHEventPtr addComponentEvent); + SHEventHandle RemovePhysicsComponent (SHEventPtr removeComponentEvent); }; From 5016600397d70845eb509f5b90c6a7596eb22283 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Tue, 25 Oct 2022 23:39:35 +0800 Subject: [PATCH 42/50] Lights WIP --- Assets/Editor/Layouts/UserLayout.ini | 12 ++++++------ .../Graphics/MiddleEnd/Interface/SHRenderable.cpp | 7 +++++++ .../src/Graphics/MiddleEnd/Interface/SHRenderable.h | 2 ++ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/Assets/Editor/Layouts/UserLayout.ini b/Assets/Editor/Layouts/UserLayout.ini index 9add170c..4d608401 100644 --- a/Assets/Editor/Layouts/UserLayout.ini +++ b/Assets/Editor/Layouts/UserLayout.ini @@ -10,7 +10,7 @@ Collapsed=0 [Window][Hierarchy Panel] Pos=0,142 -Size=768,918 +Size=494,918 Collapsed=0 DockId=0x00000004,0 @@ -27,7 +27,7 @@ DockId=0x00000006,0 [Window][Profiler] Pos=0,48 -Size=768,92 +Size=494,92 Collapsed=0 DockId=0x00000003,0 @@ -38,17 +38,17 @@ Collapsed=0 DockId=0x00000002,0 [Window][ Viewport] -Pos=770,48 -Size=877,1012 +Pos=496,48 +Size=1151,1012 Collapsed=0 DockId=0x00000002,0 [Docking][Data] DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,79 Size=1920,1012 Split=X DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1992,1036 Split=X - DockNode ID=0x00000001 Parent=0x00000005 SizeRef=768,1036 Split=Y Selected=0x1E6EB881 + DockNode ID=0x00000001 Parent=0x00000005 SizeRef=494,1036 Split=Y Selected=0x1E6EB881 DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,94 Selected=0x1E6EB881 DockNode ID=0x00000004 Parent=0x00000001 SizeRef=225,940 Selected=0xE096E5AE - DockNode ID=0x00000002 Parent=0x00000005 SizeRef=877,1036 CentralNode=1 Selected=0xB41284E7 + DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1151,1036 CentralNode=1 Selected=0xB41284E7 DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=271,1036 Selected=0xE7039252 diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp index 0b1c1b66..523722e4 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp @@ -27,6 +27,8 @@ namespace SHADE sharedMaterial = {}; material = {}; oldMaterial = {}; + + lightLayer = 0; } void SHRenderable::OnDestroy() @@ -87,6 +89,11 @@ namespace SHADE return material; } + uint8_t SHRenderable::GetLightLayer(void) const noexcept + { + return lightLayer; + } + void SHRenderable::ResetChangedFlag() { materialChanged = false; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.h index bc885ca2..95b53b9e 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.h @@ -56,6 +56,7 @@ namespace SHADE /*-------------------------------------------------------------------------------*/ bool WasMaterialChanged() const noexcept { return materialChanged; } Handle GetPrevMaterial() const noexcept { return oldMaterial; } + uint8_t GetLightLayer (void) const noexcept; /*-------------------------------------------------------------------------------*/ /* Batcher Dispatcher Functions */ @@ -75,6 +76,7 @@ namespace SHADE Handle material; bool materialChanged = true; Handle oldMaterial; + uint8_t lightLayer; }; } From 4b7a8374698a161caa1cb4310c4bb6ef93e145f5 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Wed, 26 Oct 2022 01:08:02 +0800 Subject: [PATCH 43/50] Fixed some bugs in render graph - Changed the eid buffer for instanced rendering to a vec2 (potentially vec3 or 4), to pass other types of data like light layer index. - Renamed some render graph nodes and subpasses. Added a dummy render pass to transition the scene to read only optimal. - offscreen buffer resource now transitions to eShaderReadOnlyOptimal instead of eGeneral --- .../Graphics/MiddleEnd/Batching/SHBatch.cpp | 40 +++++++++++------- .../src/Graphics/MiddleEnd/Batching/SHBatch.h | 7 +-- .../MiddleEnd/Batching/SHSuperBatch.cpp | 2 +- .../GlobalData/SHGraphicsGlobalData.cpp | 2 +- .../MiddleEnd/Interface/SHGraphicsConstants.h | 2 +- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 23 +++++----- .../Interface/SHInstancedIntegerData.h | 12 ++++++ .../Interface/SHPostOffscreenRenderSystem.cpp | 2 +- .../src/Graphics/Pipeline/SHPipelineState.cpp | 6 +++ .../Graphics/RenderGraph/SHRenderGraph.cpp | 3 ++ SHADE_Engine/src/Graphics/SHVkUtil.cpp | 12 ++++++ .../VertexDescriptors/SHVertexAttribute.h | 3 ++ TempShaderFolder/TestCubeVs.glsl | 5 ++- TempShaderFolder/TestCubeVs.spv | Bin 2300 -> 2376 bytes 14 files changed, 85 insertions(+), 34 deletions(-) create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHInstancedIntegerData.h diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index 40826047..476351c9 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -110,7 +110,7 @@ namespace SHADE // Clear CPU buffers drawData.clear(); transformData.clear(); - eidData.clear(); + instancedIntegerData.clear(); matPropsData.reset(); matPropsDataSize = 0; @@ -120,7 +120,7 @@ namespace SHADE { drawDataBuffer[i].Free(); transformDataBuffer[i].Free(); - eidBuffer[i].Free(); + instancedIntegerBuffer[i].Free(); matPropsBuffer[i].Free(); } } @@ -208,7 +208,7 @@ namespace SHADE transformDataBuffer[frameIndex]->WriteToMemory(transformData.data(), static_cast(transformData.size() * sizeof(SHMatrix)), 0, 0); } - void SHBatch::UpdateEIDBuffer(uint32_t frameIndex) + void SHBatch::UpdateInstancedIntegerBuffer(uint32_t frameIndex) { if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS) { @@ -217,18 +217,23 @@ namespace SHADE } // Reset Transform Data - eidData.clear(); + instancedIntegerData.clear(); // Populate on the CPU for (auto& subBatch : subBatches) for (const SHRenderable* renderable : subBatch.Renderables) { - eidData.emplace_back(renderable->GetEID()); + instancedIntegerData.emplace_back(SHInstancedIntegerData + { + renderable->GetEID(), + renderable->GetLightLayer() + } + ); } // Transfer to GPU - if (eidBuffer[frameIndex]) - eidBuffer[frameIndex]->WriteToMemory(eidData.data(), static_cast(eidData.size() * sizeof(EntityID)), 0, 0); + if (instancedIntegerBuffer[frameIndex]) + instancedIntegerBuffer[frameIndex]->WriteToMemory(instancedIntegerData.data(), static_cast(instancedIntegerData.size() * sizeof(SHInstancedIntegerData)), 0, 0); } @@ -264,8 +269,8 @@ namespace SHADE transformData.reserve(numTotalElements); transformData.clear(); // - EID data - eidData.reserve(numTotalElements); - eidData.clear(); + instancedIntegerData.reserve(numTotalElements); + instancedIntegerData.clear(); // - Material Properties Data @@ -320,8 +325,13 @@ namespace SHADE transformData.emplace_back(transform->GetTRS()); } - eidData.emplace_back(eid); - + instancedIntegerData.emplace_back(SHInstancedIntegerData + { + eid, + renderable->GetLightLayer() + } + ); + // Material Properties if (!EMPTY_MAT_PROPS) { @@ -351,10 +361,10 @@ namespace SHADE device, transformDataBuffer[frameIndex], transformData.data(), TF_DATA_BYTES, BuffUsage::eVertexBuffer ); - const uint32_t EID_DATA_BYTES = static_cast(eidData.size() * sizeof(EntityID)); + const uint32_t EID_DATA_BYTES = static_cast(instancedIntegerData.size() * sizeof(SHInstancedIntegerData)); SHVkUtil::EnsureBufferAndCopyHostVisibleData ( - device, eidBuffer[frameIndex], eidData.data(), EID_DATA_BYTES, + device, instancedIntegerBuffer[frameIndex], instancedIntegerData.data(), EID_DATA_BYTES, BuffUsage::eVertexBuffer ); // - Material Properties Buffer @@ -378,8 +388,8 @@ namespace SHADE // Bind all required objects before drawing static std::array dynamicOffset { 0 }; cmdBuffer->BindPipeline(pipeline); - cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0); - cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::EID, eidBuffer[frameIndex], 0); + cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0); + cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::INTEGER_DATA, instancedIntegerBuffer[frameIndex], 0); if (matPropsDescSet[frameIndex]) { cmdBuffer->BindDescriptorSet diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h index 193fff0d..a7124e05 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h @@ -23,6 +23,7 @@ of DigiPen Institute of Technology is prohibited. #include "Math/SHMatrix.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h" #include "ECS_Base/SHECSMacros.h" +#include "Graphics/MiddleEnd/Interface/SHInstancedIntegerData.h" namespace SHADE { @@ -79,7 +80,7 @@ namespace SHADE void Clear(); void UpdateMaterialBuffer(uint32_t frameIndex, Handle descPool); void UpdateTransformBuffer(uint32_t frameIndex); - void UpdateEIDBuffer(uint32_t frameIndex); + void UpdateInstancedIntegerBuffer(uint32_t frameIndex); void Build(Handle device, Handle descPool, uint32_t frameIndex) ; void Draw(Handle cmdBuffer, uint32_t frameIndex); @@ -111,7 +112,7 @@ namespace SHADE // CPU Buffers std::vector drawData; std::vector transformData; - std::vector eidData; + std::vector instancedIntegerData; std::unique_ptr matPropsData; Byte matPropsDataSize = 0; Byte singleMatPropAlignedSize = 0; @@ -120,7 +121,7 @@ namespace SHADE // GPU Buffers TripleBuffer drawDataBuffer; TripleBuffer transformDataBuffer; - TripleBuffer eidBuffer; + TripleBuffer instancedIntegerBuffer; TripleBuffer matPropsBuffer; TripleDescSet matPropsDescSet; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp index 14f2aa76..434e7163 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp @@ -85,7 +85,7 @@ namespace SHADE { batch.UpdateMaterialBuffer(frameIndex, descPool); batch.UpdateTransformBuffer(frameIndex); - batch.UpdateEIDBuffer(frameIndex); + batch.UpdateInstancedIntegerBuffer(frameIndex); } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp index 94d1d2c5..0f1658f3 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp @@ -115,7 +115,7 @@ namespace SHADE defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // Normals at binding 2 defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // Tangents at binding 3 defaultVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::MAT_4D) }); // Transform at binding 4 - 7 (4 slots) - defaultVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::UINT32_1D) }); // EID at binding 8 + defaultVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::UINT32_2D) }); // Instanced integer data at index 8 } void SHGraphicsGlobalData::Init(Handle logicalDevice) noexcept diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h index f31816ce..4c3ba7f9 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h @@ -182,7 +182,7 @@ namespace SHADE Vertex buffer bindings for the eid buffer. */ /***************************************************************************/ - static constexpr uint32_t EID = 5; + static constexpr uint32_t INTEGER_DATA = 5; }; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index b7d4bd2f..252d4af6 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -176,18 +176,21 @@ namespace SHADE worldRenderGraph->AddResource("Scene Pre-Process", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second); worldRenderGraph->AddResource("Scene", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second); worldRenderGraph->AddResource("Depth Buffer", { SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); - worldRenderGraph->AddResource("Entity ID", { SH_ATT_DESC_TYPE_FLAGS::COLOR }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); + worldRenderGraph->AddResource("Entity ID", { SH_ATT_DESC_TYPE_FLAGS::COLOR }, windowDims.first, windowDims.second, vk::Format::eR32G32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); - auto node = worldRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Scene", "Scene Pre-Process"}, {}); // no predecessors + auto gBufferNode = worldRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Scene", "Scene Pre-Process"}, {}); // no predecessors + auto gBufferSubpass = gBufferNode->AddSubpass("G-Buffer Write"); + gBufferSubpass->AddColorOutput("Scene Pre-Process"); + gBufferSubpass->AddColorOutput("Entity ID"); + gBufferSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL); - //First subpass to write to G-Buffer - auto gBufferWriteSubpass = node->AddSubpass("G-Buffer Write"); - gBufferWriteSubpass->AddColorOutput("Scene Pre-Process"); - gBufferWriteSubpass->AddColorOutput("Entity ID"); - gBufferWriteSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL); + auto kirschShader = shaderModuleLibrary.GetShaderModule("KirschCs.glsl"); + gBufferNode->AddNodeCompute (kirschShader, {"Scene Pre-Process", "Scene"}); + + auto dummyNode = worldRenderGraph->AddNode("Dummy Pass", { "Scene" }, {"G-Buffer"}); // no predecessors + auto dummySubpass = dummyNode->AddSubpass("Dummy Subpass"); + dummySubpass->AddInput("Scene"); - auto greyscale = shaderModuleLibrary.GetShaderModule("KirschCs.glsl"); - node->AddNodeCompute (greyscale, {"Scene Pre-Process", "Scene"}); // Generate world render graph worldRenderGraph->Generate(); @@ -201,7 +204,7 @@ namespace SHADE auto cubeVS = shaderModuleLibrary.GetShaderModule("TestCubeVs.glsl"); auto cubeFS = shaderModuleLibrary.GetShaderModule("TestCubeFs.glsl"); - defaultMaterial = AddMaterial(cubeVS, cubeFS, gBufferWriteSubpass); + defaultMaterial = AddMaterial(cubeVS, cubeFS, gBufferSubpass); } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHInstancedIntegerData.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHInstancedIntegerData.h new file mode 100644 index 00000000..8ba5adf8 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHInstancedIntegerData.h @@ -0,0 +1,12 @@ +#pragma once + +#include "ECS_Base/SHECSMacros.h" + +namespace SHADE +{ + struct SHInstancedIntegerData + { + EntityID eid; + uint32_t lightLayer; + }; +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp index ebce5c9e..8b41a979 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp @@ -68,7 +68,7 @@ namespace SHADE { std::vector combinedImageSampler { - std::make_tuple(offscreenRender->GetImageView(), offscreenRenderSampler, vk::ImageLayout::eGeneral), + std::make_tuple(offscreenRender->GetImageView(), offscreenRenderSampler, vk::ImageLayout::eShaderReadOnlyOptimal), }; // Register the image view and sampler with the descriptor set. Now whenever rendering to the offscreen image is done, the descriptor set will see the change diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.cpp b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.cpp index f8934bf6..c7ada11f 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.cpp +++ b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.cpp @@ -142,6 +142,12 @@ namespace SHADE case SHAttribFormat::UINT32_1D: return std::make_tuple(1, 4, vk::Format::eR32Uint); + case SHAttribFormat::UINT32_2D: + return std::make_tuple(1, 8, vk::Format::eR32G32Uint); + case SHAttribFormat::UINT32_3D: + return std::make_tuple(1, 12, vk::Format::eR32G32B32Uint); + case SHAttribFormat::UINT32_4D: + return std::make_tuple(1, 16, vk::Format::eR32G32B32A32Uint); } return std::make_tuple(0, 0, vk::Format::eR32Sfloat); } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index 4684419a..93be2413 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -142,6 +142,9 @@ namespace SHADE attDesc.loadOp = vk::AttachmentLoadOp::eLoad; predAttDesc.storeOp = vk::AttachmentStoreOp::eStore; + attDesc.stencilLoadOp = vk::AttachmentLoadOp::eLoad; + attDesc.stencilStoreOp = vk::AttachmentStoreOp::eStore; + // TODO: Stencil load and store // When an image is done being used in a renderpass, the image layout will end up being the finalLayout diff --git a/SHADE_Engine/src/Graphics/SHVkUtil.cpp b/SHADE_Engine/src/Graphics/SHVkUtil.cpp index cf486a7a..8b21e7d1 100644 --- a/SHADE_Engine/src/Graphics/SHVkUtil.cpp +++ b/SHADE_Engine/src/Graphics/SHVkUtil.cpp @@ -51,6 +51,18 @@ namespace SHADE case vk::Format::eR32Uint: case vk::Format::eR32Sfloat: return 4; + case vk::Format::eR32G32Sint: + case vk::Format::eR32G32Uint: + case vk::Format::eR32G32Sfloat: + return 8; + case vk::Format::eR32G32B32Sint: + case vk::Format::eR32G32B32Uint: + case vk::Format::eR32G32B32Sfloat: + return 12; + case vk::Format::eR32G32B32A32Sint: + case vk::Format::eR32G32B32A32Uint: + case vk::Format::eR32G32B32A32Sfloat: + return 16; } return 0; } diff --git a/SHADE_Engine/src/Graphics/VertexDescriptors/SHVertexAttribute.h b/SHADE_Engine/src/Graphics/VertexDescriptors/SHVertexAttribute.h index b216f5f4..b7191c21 100644 --- a/SHADE_Engine/src/Graphics/VertexDescriptors/SHVertexAttribute.h +++ b/SHADE_Engine/src/Graphics/VertexDescriptors/SHVertexAttribute.h @@ -22,6 +22,9 @@ namespace SHADE // integer formats UINT32_1D, + UINT32_2D, + UINT32_3D, + UINT32_4D, }; struct SHVertexAttribute diff --git a/TempShaderFolder/TestCubeVs.glsl b/TempShaderFolder/TestCubeVs.glsl index b7453f13..c6b4071f 100644 --- a/TempShaderFolder/TestCubeVs.glsl +++ b/TempShaderFolder/TestCubeVs.glsl @@ -3,12 +3,13 @@ //#include "ShaderDescriptorDefinitions.glsl" + layout(location = 0) in vec3 aVertexPos; layout(location = 1) in vec2 aUV; layout(location = 2) in vec3 aNormal; layout(location = 3) in vec3 aTangent; layout(location = 4) in mat4 worldTransform; -layout(location = 8) in uint eid; +layout(location = 8) in uvec2 integerData; layout(location = 0) out struct @@ -36,7 +37,7 @@ void main() { Out.uv = aUV; Out2.materialIndex = gl_InstanceIndex; - Out2.eid = eid; + Out2.eid = integerData[0]; gl_Position = cameraData.vpMat * worldTransform * vec4 (aVertexPos, 1.0f); Out.vertColor = vec4 (aVertexPos, 1.0f); } \ No newline at end of file diff --git a/TempShaderFolder/TestCubeVs.spv b/TempShaderFolder/TestCubeVs.spv index 1662cfbd308b1bd28ec466201103f91aaa761084..904062a69b13a76b244a967674fc08ed38bbca58 100644 GIT binary patch literal 2376 zcmZ9N+fEcg5QbZrT@VCC6i^Wt@PLAN;2??!2)K(u!GPRuCc7hgpQk?3nB_=7Q-ledfK%)_~~{Voa|o+P%E9zcbrP>$CF< zPhs?%PD_MySwEI1IrhUCy;lM{B)K8EBY7m5lPpOpl5I(+ejVEXD3PZM$~)Ea?rwQ! zt6FO|tF82V6jY-y4yyGq32JG08o=vrfFWud}#G+(pg2*Wt@KOr$G|>(RN%9zFD7VedG(my5c=uuVDKX#%XXAB%6Nf3n`kZjK3EohpOBjWA6jbQm(y5 zD@?;iY-Qa>*70!qB9>o;SE{TIHP^TKMoS# zmS}4MV>MkN(u+BlT27lE{8T&fv)XHI@!XO5_}WOK`a$BytuKw_IO8%ies*o$5zMnQ z!k8D2X$v^Ppqafx8Qx=Ce9K+DU<{h!A1)KTArWe?}2{F^T&D`SemQ-|#>opvf z!^j85?l5wK(MyM+gE60FdE7hTcfFgGk5v&1jGP5)XB=!eSI%Mjh%H85;@q9+^TauO zTsDh4({t{a)#Tal6Pty`RuH^<_G@`-IUK;`?)*e8gk(?#@3To&5O8H>kZNVNnm? zG-qVECr-u(Cm%L*Lk@TTuyhvZk7(yCa=^!CuH5;zq!Wvue%#j1S@eT=dJ7kvcx>hn zjPu&-g+HGAT)lT?lONmh@8_IR@gGR1|6pU%rnI{^!iSLep?31%rw(ksf3OkR)7pvS zUFq9QZi5s5SUYzDCmx$wboYFc>yFPK#_Wz6AA2sx=+mNf>gIg%zsP;y{sjpfa5(h$rG(yo5{EZf&M|Fg*y|jlpN_YZWAt)Qou~J2 zB*eqV&l~+xUVN((&WFPt*6g0mo$J%OFnF%Ex6<2d+mH>$a&>G<2WziwE5|ytyV~AK YCmue2YIAjzrSrb74s7`Ulyyn+A89?W<^TWy literal 2300 zcmZ9NYflqF6oyCG7QCT&!8;aEyr6gk#0!G9T1cv3P`@^tb|sr^x6O8omrwo${Ym~R zznJ(wGdrYlnv3)p&uiVb;3AheN+ZJCA%P-md(rV$(Cd_*=yOTej}QHD^Z{d>WyZ7d%NCv z-E8%G&3^tZiJD2AM$LAdMXfyEkI;<|>Eg7N4BEqjk`%+Wl(ffT?ZGJP=hypDmRGw; zH?w?TdCoJ~H-;F_usz7_nzMu-KiTyetr=xAX8gJn=1~@h$yVBqzFJ>kedLScw&DWY z3*~!AY)P^7WiM%NrTsiiTagd7d(bZzS2ow2ZYRnDzSn3No+BR|v**YO zM=w3c8ZMC4@;9BC;#L0@mh|&#Q8JP=h^@8j4*>U({s+~ zY6|Rk31;B0X$Jdz^cl=qPK$+~5dyQG(yFYvB0Hye>H?D=OfSJ`r-k_r(ZE-Pk7yFJeYg;{zfu{v561`6I6XZ1 zz`PrB`2Ejm&0zoYn%RpS=)t@zzyBqziFM})%$35&e(1sU*Xt`E#_6{l!lX`gm6c?=k;`>FF=U;C~=P1CNGYF3afSduiz5 zz4E#z1xMd@)MfhoR7N~{{M^S+<#l)9_D91RxSur{Z_M`u{LJ#Mwij9t s*S0PU$MAJ*Xbm@9+slF*uI-gL;x}aYsm<3>)tbBXb%4?TRn}G6KNk$B#sB~S From fbb613b859a202308991120ad7dca9fff2c628a3 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Wed, 26 Oct 2022 01:16:49 +0800 Subject: [PATCH 44/50] m dumb. it work. --- .../Components/SHColliderComponent.cpp | 13 --- .../Components/SHRigidBodyComponent.cpp | 26 ----- .../Physics/Components/SHRigidBodyComponent.h | 8 +- SHADE_Engine/src/Physics/SHPhysicsObject.cpp | 24 ---- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 106 ++++++++++-------- SHADE_Engine/src/Physics/SHPhysicsSystem.h | 4 +- 6 files changed, 66 insertions(+), 115 deletions(-) diff --git a/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp b/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp index 242b8d8f..c216bb83 100644 --- a/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp +++ b/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp @@ -69,24 +69,11 @@ namespace SHADE void SHColliderComponent::OnCreate() { system = SHSystemManager::GetSystem(); - //if (!system) - //{ - // SHLOG_ERROR("Physics system does not exist, Collider Component not added!") - // return; - //} - - //system->AddCollider(GetEID()); } void SHColliderComponent::OnDestroy() { - if (!system) - { - SHLOG_ERROR("Physics system does not exist, unable to remove Collider component!") - return; - } - system->RemoveCollider(GetEID()); } SHBoundingBox* SHColliderComponent::AddBoundingBox(const SHVec3& halfExtents, const SHVec3& posOffset) noexcept diff --git a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp index 934b67f6..1c671d23 100644 --- a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp +++ b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp @@ -32,7 +32,6 @@ namespace SHADE , mass { 1.0f } , drag { 0.01f } , angularDrag { 0.01f } - { // Set default flags: Gravity & Sleeping enabled flags |= 1U << 0; @@ -262,31 +261,6 @@ namespace SHADE /* Public Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ - void SHRigidBodyComponent::OnCreate() - { - system = SHSystemManager::GetSystem(); - //if (!system) - //{ - // SHLOG_ERROR("Physics system does not exist, Rigid Body Component not added!") - // return; - //} - - //// Notify Physics System - //system->AddRigidBody(GetEID()); - } - - void SHRigidBodyComponent::OnDestroy() - { - // Notify Physics System - if (!system) - { - SHLOG_ERROR("Physics system does not exist, unable to remove Rigid Body Component!") - return; - } - - system->RemoveRigidBody(GetEID()); - } - void SHRigidBodyComponent::AddForce(const SHVec3& force) const noexcept { diff --git a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h index 03b350e1..78de84e7 100644 --- a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h +++ b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h @@ -10,6 +10,7 @@ #pragma once +#include #include // Project Headers @@ -125,9 +126,6 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ - void OnCreate () override; - void OnDestroy () override; - void AddForce (const SHVec3& force) const noexcept; void AddForceAtLocalPos (const SHVec3& force, const SHVec3& localPos) const noexcept; void AddForceAtWorldPos (const SHVec3& force, const SHVec3& worldPos) const noexcept; @@ -155,7 +153,7 @@ namespace SHADE uint16_t dirtyFlags; bool interpolate; - SHPhysicsSystem* system; + rp3d::RigidBody* rp3dBody; float mass; float drag; @@ -167,8 +165,6 @@ namespace SHADE SHVec3 torque; SHVec3 angularVelocity; - // TODO(Diren): Once quaternions have replaced euler angles in transforms, store it for the rigidbody. - SHVec3 position; SHQuaternion orientation; diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp index 8c067482..986ce503 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp @@ -155,30 +155,6 @@ namespace SHADE return static_cast(rp3dBody->getNbColliders()) - 1; } - void SHPhysicsObject::DestroyRigidBody(SHColliderComponent* c) noexcept - { - world->destroyRigidBody(reinterpret_cast(rp3dBody)); - rp3dBody = nullptr; - - if (c != nullptr) - { - // Preserve colliders as a collision body - rp3dBody = world->createCollisionBody(rp3d::Transform{ c->position, c->orientation }); - for (auto& collider : c->colliders | std::views::keys) - AddCollider(&collider); - } - } - - void SHPhysicsObject::DestroyCollisionBody() noexcept - { - // Remove all colliders - for (uint32_t i = 0; i < rp3dBody->getNbColliders(); ++i) - { - auto* collider = rp3dBody->getCollider(i); - rp3dBody->removeCollider(collider); - } - } - void SHPhysicsObject::RemoveCollider(int index) { const int NUM_COLLIDERS = static_cast(rp3dBody->getNbColliders()); diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index 76e54b09..d4da329b 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -194,6 +194,10 @@ namespace SHADE const std::shared_ptr ADD_COMPONENT_RECEIVER { std::make_shared>(this, &SHPhysicsSystem::AddPhysicsComponent) }; const ReceiverPtr ADD_COMPONENT_RECEIVER_PTR = std::dynamic_pointer_cast(ADD_COMPONENT_RECEIVER); SHEventManager::SubscribeTo(SH_COMPONENT_ADDED_EVENT, ADD_COMPONENT_RECEIVER_PTR); + + const std::shared_ptr REMOVE_COMPONENT_RECEIVER { std::make_shared>(this, &SHPhysicsSystem::RemovePhysicsComponent) }; + const ReceiverPtr REMOVE_COMPONENT_RECEIVER_PTR = std::dynamic_pointer_cast(REMOVE_COMPONENT_RECEIVER); + SHEventManager::SubscribeTo(SH_COMPONENT_REMOVED_EVENT, REMOVE_COMPONENT_RECEIVER_PTR); } void SHPhysicsSystem::Exit() @@ -201,52 +205,23 @@ namespace SHADE factory.destroyPhysicsWorld(world); } - //void SHPhysicsSystem::AddRigidBody(EntityID entityID) noexcept + //void SHPhysicsSystem::RemoveRigidBody(EntityID entityID) noexcept //{ - // //#ifdef _DEBUG - // // SHLOG_INFO("Adding a Rigidbody to the Physics World.") - // //#endif + // #ifdef _DEBUG + // SHLOG_INFO("Removing a Rigidbody from the Physics World.") + // #endif - // + // auto* physicsObject = GetPhysicsObject(entityID); + // SHASSERT(physicsObject != nullptr, "Physics object has been lost from the world!") //} - //void SHPhysicsSystem::AddCollider(EntityID entityID) noexcept + //void SHPhysicsSystem::RemoveCollider(EntityID entityID) noexcept //{ - // //#ifdef _DEBUG - // // SHLOG_INFO("Adding a Collider to the Physics World.") - // //#endif - - // auto* physicsObject = EnsurePhysicsObject(entityID); - - // physicsObject->CreateCollisionBody - // ( - // SHComponentManager::GetComponent(entityID), - // SHComponentManager::GetComponent(entityID) - // ); + // #ifdef _DEBUG + // SHLOG_INFO("Removing a Collider from the Physics World.") + // #endif //} - void SHPhysicsSystem::RemoveRigidBody(EntityID entityID) noexcept - { - #ifdef _DEBUG - SHLOG_INFO("Removing a Rigidbody from the Physics World.") - #endif - - auto* physicsObject = GetPhysicsObject(entityID); - SHASSERT(physicsObject != nullptr, "Physics object has been lost from the world!") - - physicsObject->DestroyRigidBody(SHComponentManager::GetComponent_s(entityID)); - - if (physicsObject->rp3dBody == nullptr) - DestroyPhysicsObject(entityID); - } - - void SHPhysicsSystem::RemoveCollider(EntityID entityID) noexcept - { - #ifdef _DEBUG - SHLOG_INFO("Removing a Collider from the Physics World.") - #endif - } - void SHPhysicsSystem::AddCollisionShape(EntityID entityID, SHCollider* collider) { auto* physicsObject = GetPhysicsObject(entityID); @@ -255,7 +230,8 @@ namespace SHADE void SHPhysicsSystem::RemoveCollisionShape(EntityID entityID, int index) { - + auto* physicsObject = GetPhysicsObject(entityID); + physicsObject->RemoveCollider(index); } void SHPhysicsSystem::PhysicsPreUpdate::Execute(double) noexcept @@ -471,8 +447,8 @@ namespace SHADE static const auto RIGID_BODY_ID = ComponentFamily::GetID(); static const auto COLLIDER_ID = ComponentFamily::GetID(); - const auto COMPONENT_ADDED_ID = EVENT_DATA->data->addedComponentType; - const bool IS_PHYSICS_COMPONENT = COMPONENT_ADDED_ID == RIGID_BODY_ID || COMPONENT_ADDED_ID == COLLIDER_ID; + const auto ADDED_ID = EVENT_DATA->data->addedComponentType; + const bool IS_PHYSICS_COMPONENT = ADDED_ID == RIGID_BODY_ID || ADDED_ID == COLLIDER_ID; if (IS_PHYSICS_COMPONENT) { const EntityID ENTITY_ID = EVENT_DATA->data->eid; @@ -488,7 +464,7 @@ namespace SHADE auto* rigidBodyComponent = SHComponentManager::GetComponent_s(ENTITY_ID); auto* colliderComponent = SHComponentManager::GetComponent_s(ENTITY_ID); - if (COMPONENT_ADDED_ID == RIGID_BODY_ID) + if (ADDED_ID == RIGID_BODY_ID) { if (colliderComponent != nullptr) { @@ -513,7 +489,7 @@ namespace SHADE } } - if (COMPONENT_ADDED_ID == COLLIDER_ID) + if (ADDED_ID == COLLIDER_ID) { colliderComponent->position = transformComponent->GetWorldPosition(); colliderComponent->orientation = transformComponent->GetWorldOrientation(); @@ -539,6 +515,48 @@ namespace SHADE { const auto& EVENT_DATA = reinterpret_cast*>(removeComponentEvent.get()); + static const auto RIGID_BODY_ID = ComponentFamily::GetID(); + static const auto COLLIDER_ID = ComponentFamily::GetID(); + + const auto REMOVED_ID = EVENT_DATA->data->removedComponentType; + const bool IS_PHYSICS_COMPONENT = REMOVED_ID == RIGID_BODY_ID || REMOVED_ID == COLLIDER_ID; + if (IS_PHYSICS_COMPONENT) + { + const EntityID ENTITY_ID = EVENT_DATA->data->eid; + auto* physicsObject = GetPhysicsObject(ENTITY_ID); + + SHASSERT(physicsObject != nullptr, "Physics object has been lost from the world!") + + if (REMOVED_ID == RIGID_BODY_ID) + { + world->destroyRigidBody(reinterpret_cast(physicsObject->rp3dBody)); + physicsObject->rp3dBody = nullptr; + + auto* colliderComponent = SHComponentManager::GetComponent_s(ENTITY_ID); + if (colliderComponent != nullptr) + { + // Preserve colliders as a collision body + physicsObject->rp3dBody = world->createCollisionBody + ( + rp3d::Transform{ colliderComponent->position, colliderComponent->orientation } + ); + + for (auto& collider : colliderComponent->colliders | std::views::keys) + physicsObject->AddCollider(&collider); + } + } + + if (REMOVED_ID == COLLIDER_ID) + { + // Remove all colliders + for (uint32_t i = 0; i < physicsObject->rp3dBody->getNbColliders(); ++i) + physicsObject->rp3dBody->removeCollider(physicsObject->rp3dBody->getCollider(i)); + } + + if (physicsObject->rp3dBody == nullptr) + DestroyPhysicsObject(ENTITY_ID); + } + return EVENT_DATA->handle; } diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/SHPhysicsSystem.h index d88f8c06..0af22e7a 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.h @@ -87,8 +87,8 @@ namespace SHADE //void AddRigidBody (EntityID entityID) noexcept; //void AddCollider (EntityID entityID) noexcept; - void RemoveRigidBody (EntityID entityID) noexcept; - void RemoveCollider (EntityID entityID) noexcept; + //void RemoveRigidBody (EntityID entityID) noexcept; + //void RemoveCollider (EntityID entityID) noexcept; void AddCollisionShape (EntityID entityID, SHCollider* collider); void RemoveCollisionShape (EntityID entityID, int index); From 7ba02aeb0fb7fd5f1e2292078b32ed7c98933287 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Wed, 26 Oct 2022 01:46:13 +0800 Subject: [PATCH 45/50] Removed unused functions, fixed RigidBody --- SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp | 1 - SHADE_Engine/src/Physics/SHPhysicsObject.h | 5 ----- 2 files changed, 6 deletions(-) diff --git a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp index 1c671d23..8327c3ec 100644 --- a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp +++ b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp @@ -28,7 +28,6 @@ namespace SHADE , flags { 0 } , dirtyFlags { 0 } , interpolate { true } - , system { nullptr } , mass { 1.0f } , drag { 0.01f } , angularDrag { 0.01f } diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.h b/SHADE_Engine/src/Physics/SHPhysicsObject.h index 11e41ad1..67e5ec64 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.h +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.h @@ -69,13 +69,8 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ - void CreateRigidBody (const SHVec3& pos, const SHQuaternion& orientation); - void CreateCollisionBody (const SHVec3& pos, const SHQuaternion& orientation); int AddCollider (SHCollider* collider); - - void DestroyRigidBody (SHColliderComponent* c) noexcept; void RemoveCollider (int index); - void DestroyCollisionBody () noexcept; void SyncRigidBody (SHRigidBodyComponent* rb) const noexcept; void SyncColliders (SHColliderComponent* c) const noexcept; From 5637fb707f7f24e905c43516c399019af1f8ec31 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Wed, 26 Oct 2022 02:14:43 +0800 Subject: [PATCH 46/50] Tested light component. Values reflected in renderdoc correctly - Added pure copy compute shader (used instead of kirsch) - Created sparse set for lights - Note that while the instanced attribute contains both EID and layer light index and in the future potentially more, the objects still write to a uint framebuffer. - Light layer index is in a different frame buffer than the eid one. - Updated shaders to accommodate light layer index. --- SHADE_Application/src/Scenes/SBTestScene.cpp | 2 + .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 25 +++++-- .../MiddleEnd/Interface/SHMousePickSystem.cpp | 3 +- .../MiddleEnd/Lights/SHLightingSubSystem.cpp | 2 + TempShaderFolder/PureCopyCs.glsl | 67 ++++++++++++++++++ TempShaderFolder/PureCopyCs.spv | Bin 0 -> 1264 bytes TempShaderFolder/TestCubeFs.glsl | 3 + TempShaderFolder/TestCubeFs.spv | Bin 2156 -> 2300 bytes TempShaderFolder/TestCubeVs.glsl | 4 +- TempShaderFolder/TestCubeVs.spv | Bin 2376 -> 2492 bytes 10 files changed, 97 insertions(+), 9 deletions(-) create mode 100644 TempShaderFolder/PureCopyCs.glsl create mode 100644 TempShaderFolder/PureCopyCs.spv diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index b414ecaf..9c178429 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -12,6 +12,7 @@ #include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h" #include "Physics/Components/SHRigidBodyComponent.h" #include "Physics/Components/SHColliderComponent.h" +#include "Graphics/MiddleEnd/Lights/SHLightComponent.h" #include "Assets/SHAssetManager.h" #include "Camera/SHCameraComponent.h" @@ -158,6 +159,7 @@ namespace Sandbox scriptEngine->AddScript(raccoonShowcase, "RaccoonShowcase"); SHComponentManager::AddComponent(0); + SHComponentManager::AddComponent(0); SHComponentManager::RemoveComponent (0); SHComponentManager::RemoveComponent (0); } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 252d4af6..7b8b9e45 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -125,14 +125,17 @@ namespace SHADE shaderSourceLibrary.LoadShader(1, "TestCubeFs.glsl", SH_SHADER_TYPE::FRAGMENT, true); shaderSourceLibrary.LoadShader(2, "KirschCs.glsl", SH_SHADER_TYPE::COMPUTE, true); + shaderSourceLibrary.LoadShader(3, "PureCopyCs.glsl", SH_SHADER_TYPE::COMPUTE, true); shaderModuleLibrary.ImportFromSourceLibrary(device, shaderSourceLibrary); auto cubeVS = shaderModuleLibrary.GetShaderModule("TestCubeVs.glsl"); auto cubeFS = shaderModuleLibrary.GetShaderModule("TestCubeFs.glsl"); auto greyscale = shaderModuleLibrary.GetShaderModule("KirschCs.glsl"); + auto pureCopy = shaderModuleLibrary.GetShaderModule("PureCopyCs.glsl"); cubeVS->Reflect(); cubeFS->Reflect(); greyscale->Reflect(); + pureCopy->Reflect(); } void SHGraphicsSystem::InitSceneRenderGraph(void) noexcept @@ -173,19 +176,27 @@ namespace SHADE // Initialize world render graph worldRenderGraph->Init(device, swapchain); - worldRenderGraph->AddResource("Scene Pre-Process", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second); - worldRenderGraph->AddResource("Scene", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second); - worldRenderGraph->AddResource("Depth Buffer", { SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); - worldRenderGraph->AddResource("Entity ID", { SH_ATT_DESC_TYPE_FLAGS::COLOR }, windowDims.first, windowDims.second, vk::Format::eR32G32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); + worldRenderGraph->AddResource("Scene Pre-Process", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second); + worldRenderGraph->AddResource("Scene", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second); + worldRenderGraph->AddResource("Depth Buffer", { SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); + worldRenderGraph->AddResource("Entity ID", { SH_ATT_DESC_TYPE_FLAGS::COLOR }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); + worldRenderGraph->AddResource("Light Layer Indices", { SH_ATT_DESC_TYPE_FLAGS::COLOR }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); - auto gBufferNode = worldRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Scene", "Scene Pre-Process"}, {}); // no predecessors + auto gBufferNode = worldRenderGraph->AddNode("G-Buffer", { "Light Layer Indices", "Entity ID", "Depth Buffer", "Scene", "Scene Pre-Process"}, {}); // no predecessors auto gBufferSubpass = gBufferNode->AddSubpass("G-Buffer Write"); gBufferSubpass->AddColorOutput("Scene Pre-Process"); gBufferSubpass->AddColorOutput("Entity ID"); + gBufferSubpass->AddColorOutput("Light Layer Indices"); gBufferSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL); - auto kirschShader = shaderModuleLibrary.GetShaderModule("KirschCs.glsl"); - gBufferNode->AddNodeCompute (kirschShader, {"Scene Pre-Process", "Scene"}); + //// kirsch + //auto kirschShader = shaderModuleLibrary.GetShaderModule("KirschCs.glsl"); + //gBufferNode->AddNodeCompute(kirschShader, { "Scene Pre-Process", "Scene" }); + + // copy + auto pureCopyShader = shaderModuleLibrary.GetShaderModule("PureCopyCs.glsl"); + gBufferNode->AddNodeCompute(pureCopyShader, { "Scene Pre-Process", "Scene" }); + auto dummyNode = worldRenderGraph->AddNode("Dummy Pass", { "Scene" }, {"G-Buffer"}); // no predecessors auto dummySubpass = dummyNode->AddSubpass("Dummy Subpass"); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp index 57a08d47..46126ae1 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp @@ -7,6 +7,7 @@ #include "Graphics/Buffers/SHVkBuffer.h" #include "Graphics/SHVkUtil.h" #include "Graphics/MiddleEnd/Interface/SHViewport.h" +//#include "Graphics/MiddleEnd/Interface/SHInstancedIntegerData.h" namespace SHADE { @@ -53,7 +54,7 @@ namespace SHADE // wait for the copy to be done afterCopyFence->Wait(true, std::numeric_limits::max()); - pickedEID = imageDataDstBuffer->GetDataFromMappedPointer(static_cast(viewportMousePos.y) * entityIDAttachment->GetWidth() + static_cast(viewportMousePos.x)); + pickedEID = imageDataDstBuffer->GetDataFromMappedPointer(static_cast(viewportMousePos.y) * entityIDAttachment->GetWidth() + static_cast(viewportMousePos.x)); } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp index 30bbd363..8d9efe54 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp @@ -329,6 +329,8 @@ namespace SHADE /***************************************************************************/ void SHLightingSubSystem::Init(Handle device, Handle descPool) noexcept { + SHComponentManager::CreateComponentSparseSet(); + logicalDevice = device; uint32_t constexpr NUM_LIGHT_TYPES = SHUtilities::ToUnderlying(SH_LIGHT_TYPE::NUM_TYPES); diff --git a/TempShaderFolder/PureCopyCs.glsl b/TempShaderFolder/PureCopyCs.glsl new file mode 100644 index 00000000..89da6dd9 --- /dev/null +++ b/TempShaderFolder/PureCopyCs.glsl @@ -0,0 +1,67 @@ +//#version 450 +// +//layout(local_size_x = 16, local_size_y = 16) in; +//layout(set = 4, binding = 0, rgba8) uniform image2D targetImage; +// +// +//void main() +//{ +// ivec2 imageSize = imageSize (targetImage); +// +// if (gl_GlobalInvocationID.x >= imageSize.x && gl_GlobalInvocationID.y >= imageSize.y) +// return; +// +// // load the image +// vec4 color = imageLoad (targetImage, ivec2 (gl_GlobalInvocationID)); +// +// // get the average +// float average = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b; +// +// // store result into result image +// imageStore(targetImage, ivec2(gl_GlobalInvocationID), vec4(average, average, average, 1.0f)); +// +//} +// +// +// +// + +/* Start Header *****************************************************************/ + +/*! \file (e.g. kirsch.comp) + + \author William Zheng, william.zheng, 60001906. Brandon Mak, brandon.hao 390003920. + + \par william.zheng\@digipen.edu. brandon.hao\@digipen.edu. + + \date Sept 20, 2022 + + \brief Copyright (C) 20xx 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. */ + + /* End Header *******************************************************************/ + +#version 450 + + +layout(local_size_x = 16, local_size_y = 16) in; +layout(set = 4, binding = 0, rgba8) uniform image2D inputImage; +layout(set = 4, binding = 1, rgba8) uniform image2D targetImage; + + +void main() +{ + // convenient variables + ivec2 globalThread = ivec2(gl_GlobalInvocationID); + + vec3 color = imageLoad (inputImage, globalThread).rgb; + + // store result into result image + imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), vec4(color, 1.0f)); + +} + + + + diff --git a/TempShaderFolder/PureCopyCs.spv b/TempShaderFolder/PureCopyCs.spv new file mode 100644 index 0000000000000000000000000000000000000000..bf967bbf80b801df07d30879ae29890b7e7b147b GIT binary patch literal 1264 zcmYk5TTj$b6oog;6bBFx5%6wDR8(;EL5+z~Uo_1mlMF`Ro6>2G_QEbd(~Td);dvzK;pHf>Ri*{Ur$8;!n=2B-C8@cPXw6zkS; zLNpuF1hQS>B*{wxYr-}0aGUOqPZiUX9c4HBBd4pX(I}3_<7o6HPG__DwEkISagmo< zJjv%-TIc5(x?W3{muYb}X$t}=+Vum~URI51Q5`46_aE~tnaEY2J=fc`h$9yomgiNP z)Ol47Kf8F>c4gD5sOHWO?6z!P&d%!LNitP0f&M~qbuyo34H>CAGp`DF1$>@+DA1Sp z`?_=RL)ms5pZJ16d>~7{Tf&w$#?Ja~d*<%j(kzJ!1)kZJuNUb!w4wZ-EF3_;;&}bj zK~H`--X{91vgCq)-}ubs^Ka-*P4qkZe?vAD$h9qt?{n?weo>bhmhEN}Cs+H>D?6e- zvvSZ|j!;#19o;Msl9w{?( X9SA&+p7_3yst)~9m-s(*^G^5=Amdbt literal 0 HcmV?d00001 diff --git a/TempShaderFolder/TestCubeFs.glsl b/TempShaderFolder/TestCubeFs.glsl index 18890c92..4dc6deca 100644 --- a/TempShaderFolder/TestCubeFs.glsl +++ b/TempShaderFolder/TestCubeFs.glsl @@ -23,6 +23,7 @@ layout(location = 2) flat in struct { int materialIndex; uint eid; + uint lightLayerIndex; } In2; //layout (set = 0, binding = ) @@ -35,6 +36,7 @@ layout (set = 3, binding = 0) buffer MaterialProperties // For materials layout(location = 0) out vec4 outColor; layout(location = 1) out uint outEntityID; +layout(location = 2) out uint lightLayerIndices; void main() { @@ -42,5 +44,6 @@ void main() MatProp.data[In2.materialIndex].color / MatProp.data[In2.materialIndex].alpha; outEntityID = In2.eid; + lightLayerIndices = In2.lightLayerIndex; //outColor = vec4 (1.0f); } \ No newline at end of file diff --git a/TempShaderFolder/TestCubeFs.spv b/TempShaderFolder/TestCubeFs.spv index bde6213644b38cb5e844a04ac20ad1ca3e43b62c..9955abe53ff6b413215a81ed14c71a2cae54e69d 100644 GIT binary patch delta 209 zcmaDO@JEoBnMs+Qfq{{Mi-DKHWg>4bBiF=gMMlSsGoLd`voWwUNH8!kFadE+W_m`6 zPhw?ik!M~?YQ^MwrbKC0pu8ixTxN1=F$2Tq`%H$6yzUGvUlUf`^{+K$iT{A2jn^du@n%S0#cgLy1J`o2M4Byo!jAdyHWSn6>Gm6kj1$XR}Xum`Jp-6&pWeox39w( zbAy2hXRm&&nqk-K@$!W=~iU_!5oP&8H|b`< zUJG{av%cXRG2CHgJr6o}@t-~i{g8B4-3>d_*L)sju}_xMPV_zaYQaaoDDG@=xoZ-y ze$AVHGs+4!_3}!voHF&y4(HEAuU{oJSR$kNI;6y7pU^Jq277Jcqzsk%Bp%(bm7VJv)A^xG4E$)PmI^|nP;@)Ch)UXvt=kcv4$(E1z zqQ5L^WJnhLT9o-vVyGnyj_f@vM0&mCQp-l~jnB0c&qK5;@!XNw`PR*n&d1EB{V&~Y zt>7|GzPPsTh^-dp%fA)HCm|oR=0Ey$HA*?cHN>I6696qRJqA+?n4W-n3ovs`%uI=y zY5Y4SOFD&jW5HpWjeOYH%|=dayrtRDu`#<1d8`lk?d_)JV=ak=jhsUP7aTC0ecNpM zz=Msv#MzyA=QG>zlrW1s^XA;KsHqmdT`&uOQ+xG|cxNzoIjB=OXG#c+eneVb`=sQk z;;9QvelTwdhC3n5w+aXQr0{O-mT=rL(AETs!BH2R@kDvKmfECl)_% za!NaA@g~IczHqS<4`vpzabC4%_*13N>OCt=ez4VdUOM?L{(^M!omBjcc6x$sLfRGW z);D|z=UmlJUi{Pr=05@3xbQXY#L;Vd%N&BS6MsWHHDD(m%zWCtZPyPqm@nMG#=D!0Q_lEme;@r`X8m%W+XUIW9;n$0h05Eyrc)f`s$oa0mMSLc;9YTZ7?QZ7-!)YikH&V_6+b(y>)*TP|(Y+Fr>gpQk?3nB_=7Q-ledfK%)_~~{Voa|o+P%E9zcbrP>$CF< zPhs?%PD_MySwEI1IrhUCy;lM{B)K8EBY7m5lPpOpl5I(+ejVEXD3PZM$~)Ea?rwQ! zt6FO|tF82V6jY-y4yyGq32JG08o=vrfFWud}#G+(pg2*Wt@KOr$G|>(RN%9zFD7VedG(my5c=uuVDKX#%XXAB%6Nf3n`kZjK3EohpOBjWA6jbQm(y5 zD@?;iY-Qa>*70!qB9>o;SE{TIHP^TKMoS# zmS}4MV>MkN(u+BlT27lE{8T&fv)XHI@!XO5_}WOK`a$BytuKw_IO8%ies*o$5zMnQ z!k8D2X$v^Ppqafx8Qx=Ce9K+DU<{h!A1)KTArWe?}2{F^T&D`SemQ-|#>opvf z!^j85?l5wK(MyM+gE60FdE7hTcfFgGk5v&1jGP5)XB=!eSI%Mjh%H85;@q9+^TauO zTsDh4({t{a)#Tal6Pty`RuH^<_G@`-IUK;`?)*e8gk(?#@3To&5O8H>kZNVNnm? zG-qVECr-u(Cm%L*Lk@TTuyhvZk7(yCa=^!CuH5;zq!Wvue%#j1S@eT=dJ7kvcx>hn zjPu&-g+HGAT)lT?lONmh@8_IR@gGR1|6pU%rnI{^!iSLep?31%rw(ksf3OkR)7pvS zUFq9QZi5s5SUYzDCmx$wboYFc>yFPK#_Wz6AA2sx=+mNf>gIg%zsP;y{sjpfa5(h$rG(yo5{EZf&M|Fg*y|jlpN_YZWAt)Qou~J2 zB*eqV&l~+xUVN((&WFPt*6g0mo$J%OFnF%Ex6<2d+mH>$a&>G<2WziwE5|ytyV~AK YCmue2YIAjzrSrb74s7`Ulyyn+A89?W<^TWy From 7c0bcd8a3e2f839ae4792123ce2ed0babfd55961 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Wed, 26 Oct 2022 16:09:54 +0800 Subject: [PATCH 47/50] Delete UserLayout.ini @Xenosas1337 stop pushing this please --- Assets/Editor/Layouts/UserLayout.ini | 62 ---------------------------- 1 file changed, 62 deletions(-) delete mode 100644 Assets/Editor/Layouts/UserLayout.ini diff --git a/Assets/Editor/Layouts/UserLayout.ini b/Assets/Editor/Layouts/UserLayout.ini deleted file mode 100644 index e27f5cca..00000000 --- a/Assets/Editor/Layouts/UserLayout.ini +++ /dev/null @@ -1,62 +0,0 @@ -[Window][MainStatusBar] -Pos=0,1060 -Size=1920,20 -Collapsed=0 - -[Window][SHEditorMenuBar] -Pos=0,48 -Size=1920,1012 -Collapsed=0 - -[Window][Hierarchy Panel] -Pos=0,142 -Size=494,690 -Collapsed=0 -DockId=0x00000007,0 - -[Window][Debug##Default] -Pos=60,60 -Size=400,400 -Collapsed=0 - -[Window][Inspector] -Pos=1649,48 -Size=271,1012 -Collapsed=0 -DockId=0x00000006,0 - -[Window][Profiler] -Pos=0,48 -Size=494,92 -Collapsed=0 -DockId=0x00000003,0 - -[Window][Viewport] -Pos=648,48 -Size=2519,1319 -Collapsed=0 -DockId=0x00000002,0 - -[Window][ Viewport] -Pos=496,48 -Size=1151,1012 -Collapsed=0 -DockId=0x00000002,0 - -[Window][ Asset Browser] -Pos=0,834 -Size=494,226 -Collapsed=0 -DockId=0x00000008,0 - -[Docking][Data] -DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,79 Size=1920,1012 Split=X - DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1992,1036 Split=X - DockNode ID=0x00000001 Parent=0x00000005 SizeRef=494,1036 Split=Y Selected=0x1E6EB881 - DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,94 Selected=0x1E6EB881 - DockNode ID=0x00000004 Parent=0x00000001 SizeRef=225,940 Split=Y Selected=0xE096E5AE - DockNode ID=0x00000007 Parent=0x00000004 SizeRef=494,690 Selected=0xE096E5AE - DockNode ID=0x00000008 Parent=0x00000004 SizeRef=494,226 Selected=0xB128252A - DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1151,1036 CentralNode=1 Selected=0xB41284E7 - DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=271,1036 Selected=0xE7039252 - From 58491fcbffa9800095c32b03f9c3e8cc4d4304be Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Wed, 26 Oct 2022 16:17:22 +0800 Subject: [PATCH 48/50] Fixed physics bugs 1. Colliders are now properly deleted along with its component. 2. Forces and velocities are reset on stop. --- .../Components/SHColliderComponent.cpp | 33 ++-- .../Physics/Components/SHColliderComponent.h | 8 +- .../Components/SHRigidBodyComponent.cpp | 159 ++++++++++++++++-- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 91 ++++++---- 4 files changed, 223 insertions(+), 68 deletions(-) diff --git a/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp b/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp index c216bb83..75a00491 100644 --- a/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp +++ b/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp @@ -26,7 +26,6 @@ namespace SHADE SHColliderComponent::SHColliderComponent() noexcept : system { nullptr } - , colliders {} {} /*-----------------------------------------------------------------------------------*/ @@ -78,9 +77,15 @@ namespace SHADE SHBoundingBox* SHColliderComponent::AddBoundingBox(const SHVec3& halfExtents, const SHVec3& posOffset) noexcept { - const auto TYPE = SHCollider::Type::BOX; + if (!system) + { + SHLOG_ERROR("Physics system does not exist, unable to add Box Collider!") + return nullptr; + } - auto boxPair = std::make_pair(SHCollider{TYPE}, true); + static constexpr auto TYPE = SHCollider::Type::BOX; + + auto boxPair = std::make_pair(SHCollider{ TYPE }, true); auto& collider = colliders.emplace_back(boxPair).first; const auto* tf = SHComponentManager::GetComponent(GetEID()); @@ -88,12 +93,6 @@ namespace SHADE collider.SetPositionOffset(posOffset); collider.SetAsBoundingBox(tf->GetWorldScale() * halfExtents); - if (!system) - { - SHLOG_ERROR("Physics system does not exist, unable to add Box Collider!") - return nullptr; - } - // Notify Physics System system->AddCollisionShape(GetEID(), &collider); @@ -102,7 +101,13 @@ namespace SHADE SHBoundingSphere* SHColliderComponent::AddBoundingSphere(float radius, const SHVec3& posOffset) noexcept { - const auto TYPE = SHCollider::Type::SPHERE; + if (!system) + { + SHLOG_ERROR("Physics system does not exist, unable to add Sphere Collider!") + return nullptr; + } + + static constexpr auto TYPE = SHCollider::Type::SPHERE; auto spherePair = std::make_pair(SHCollider{ TYPE }, true); auto& collider = colliders.emplace_back(spherePair).first; @@ -113,13 +118,7 @@ namespace SHADE const SHVec3 TF_WORLD_SCALE = tf->GetWorldScale(); const float MAX_SCALE = SHMath::Max({ TF_WORLD_SCALE.x, TF_WORLD_SCALE.y, TF_WORLD_SCALE.z }); - collider.SetAsBoundingSphere(MAX_SCALE * 0.5f); - - if (!system) - { - SHLOG_ERROR("Physics system does not exist, unable to add Sphere Collider!") - return nullptr; - } + collider.SetAsBoundingSphere(MAX_SCALE * 0.5f * radius); // Notify Physics System system->AddCollisionShape(GetEID(), &collider); diff --git a/SHADE_Engine/src/Physics/Components/SHColliderComponent.h b/SHADE_Engine/src/Physics/Components/SHColliderComponent.h index 22d5ceee..4ecd0e93 100644 --- a/SHADE_Engine/src/Physics/Components/SHColliderComponent.h +++ b/SHADE_Engine/src/Physics/Components/SHColliderComponent.h @@ -44,7 +44,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ using ColliderDirtyPair = std::pair; - using Colliders = std::vector; + using Colliders = std::vector; public: @@ -81,10 +81,10 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ - void OnCreate () override; - void OnDestroy () override; + void OnCreate () override; + void OnDestroy () override; - void RemoveCollider (int index); + void RemoveCollider (int index); 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; diff --git a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp index 8327c3ec..b0172f64 100644 --- a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp +++ b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp @@ -28,6 +28,7 @@ namespace SHADE , flags { 0 } , dirtyFlags { 0 } , interpolate { true } + , rp3dBody { nullptr } , mass { 1.0f } , drag { 0.01f } , angularDrag { 0.01f } @@ -159,7 +160,13 @@ namespace SHADE void SHRigidBodyComponent::SetGravityEnabled(bool enableGravity) noexcept { - constexpr int FLAG_POS = 0; + static constexpr int FLAG_POS = 0; + + if (type != Type::DYNAMIC) + { + SHLOG_WARNING("Cannot enable gravity of a non-dynamic object {}", GetEID()) + return; + } dirtyFlags |= 1U << FLAG_POS; enableGravity ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); @@ -167,7 +174,13 @@ namespace SHADE void SHRigidBodyComponent::SetIsAllowedToSleep(bool isAllowedToSleep) noexcept { - constexpr int FLAG_POS = 1; + static constexpr int FLAG_POS = 1; + + if (type != Type::DYNAMIC) + { + SHLOG_WARNING("Cannot enable sleeping of a non-dynamic object {}", GetEID()) + return; + } dirtyFlags |= 1U << 1; isAllowedToSleep ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); @@ -175,7 +188,13 @@ namespace SHADE void SHRigidBodyComponent::SetFreezePositionX(bool freezePositionX) noexcept { - constexpr int FLAG_POS = 2; + static constexpr int FLAG_POS = 2; + + if (type == Type::STATIC) + { + SHLOG_WARNING("Cannot set linear constraints of a static object {}", GetEID()) + return; + } dirtyFlags |= 1U << 2; freezePositionX ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); @@ -183,7 +202,13 @@ namespace SHADE void SHRigidBodyComponent::SetFreezePositionY(bool freezePositionY) noexcept { - constexpr int FLAG_POS = 3; + static constexpr int FLAG_POS = 3; + + if (type == Type::STATIC) + { + SHLOG_WARNING("Cannot set linear constraints of a static object {}", GetEID()) + return; + } dirtyFlags |= 1U << 2; freezePositionY ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); @@ -191,7 +216,13 @@ namespace SHADE void SHRigidBodyComponent::SetFreezePositionZ(bool freezePositionZ) noexcept { - constexpr int FLAG_POS = 4; + static constexpr int FLAG_POS = 4; + + if (type == Type::STATIC) + { + SHLOG_WARNING("Cannot set linear constraints of a static object {}", GetEID()) + return; + } dirtyFlags |= 1U << 2; freezePositionZ ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); @@ -199,7 +230,13 @@ namespace SHADE void SHRigidBodyComponent::SetFreezeRotationX(bool freezeRotationX) noexcept { - constexpr int FLAG_POS = 5; + static constexpr int FLAG_POS = 5; + + if (type == Type::STATIC) + { + SHLOG_WARNING("Cannot set angular constraints of a static object {}", GetEID()) + return; + } dirtyFlags |= 1U << 3; freezeRotationX ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); @@ -207,7 +244,13 @@ namespace SHADE void SHRigidBodyComponent::SetFreezeRotationY(bool freezeRotationY) noexcept { - constexpr int FLAG_POS = 6; + static constexpr int FLAG_POS = 6; + + if (type == Type::STATIC) + { + SHLOG_WARNING("Cannot set angular constraints of a static object {}", GetEID()) + return; + } dirtyFlags |= 1U << 3; freezeRotationY ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); @@ -215,7 +258,13 @@ namespace SHADE void SHRigidBodyComponent::SetFreezeRotationZ(bool freezeRotationZ) noexcept { - constexpr int FLAG_POS = 7; + static constexpr int FLAG_POS = 7; + + if (type == Type::STATIC) + { + SHLOG_WARNING("Cannot set angular constraints of a static object {}", GetEID()) + return; + } dirtyFlags |= 1U << 3; freezeRotationZ ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); @@ -228,30 +277,60 @@ namespace SHADE void SHRigidBodyComponent::SetMass(float newMass) noexcept { + if (type != Type::DYNAMIC) + { + SHLOG_WARNING("Cannot set mass of a non-dynamic object {}", GetEID()) + return; + } + dirtyFlags |= 1U << 5; mass = newMass; } void SHRigidBodyComponent::SetDrag(float newDrag) noexcept { + if (type != Type::DYNAMIC) + { + SHLOG_WARNING("Cannot set drag of a non-dynamic object {}", GetEID()) + return; + } + dirtyFlags |= 1U << 6; drag = newDrag; } void SHRigidBodyComponent::SetAngularDrag(float newAngularDrag) noexcept { + if (type != Type::DYNAMIC) + { + SHLOG_WARNING("Cannot set angular drag of a non-dynamic object {}", GetEID()) + return; + } + dirtyFlags |= 1U << 7; angularDrag = newAngularDrag; } void SHRigidBodyComponent::SetLinearVelocity(const SHVec3& newLinearVelocity) noexcept { + if (type == Type::STATIC) + { + SHLOG_WARNING("Cannot set linear velocity of a static object {}", GetEID()) + return; + } + dirtyFlags |= 1U << 8; linearVelocity = newLinearVelocity; } void SHRigidBodyComponent::SetAngularVelocity(const SHVec3& newAngularVelocity) noexcept { + if (type == Type::STATIC) + { + SHLOG_WARNING("Cannot set angular velocity of a static object {}", GetEID()) + return; + } + dirtyFlags |= 1U << 9; angularVelocity = newAngularVelocity; } @@ -262,42 +341,90 @@ namespace SHADE void SHRigidBodyComponent::AddForce(const SHVec3& force) const noexcept { - + if (rp3dBody == nullptr) + { + SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID()) + return; + } + + rp3dBody->applyWorldForceAtCenterOfMass(force); } void SHRigidBodyComponent::AddForceAtLocalPos(const SHVec3& force, const SHVec3& localPos) const noexcept { - + if (rp3dBody == nullptr) + { + SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID()) + return; + } + + rp3dBody->applyWorldForceAtLocalPosition(force, localPos); } void SHRigidBodyComponent::AddForceAtWorldPos(const SHVec3& force, const SHVec3& worldPos) const noexcept { - + if (rp3dBody == nullptr) + { + SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID()) + return; + } + + rp3dBody->applyWorldForceAtWorldPosition(force, worldPos); } void SHRigidBodyComponent::AddRelativeForce(const SHVec3& relativeForce) const noexcept { - + if (rp3dBody == nullptr) + { + SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID()) + return; + } + + rp3dBody->applyLocalForceAtCenterOfMass(relativeForce); } void SHRigidBodyComponent::AddRelativeForceAtLocalPos(const SHVec3& relativeForce, const SHVec3& localPos) const noexcept { - + if (rp3dBody == nullptr) + { + SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID()) + return; + } + + rp3dBody->applyLocalForceAtLocalPosition(relativeForce, localPos); } void SHRigidBodyComponent::AddRelativeForceAtWorldPos(const SHVec3& relativeForce, const SHVec3& worldPos) const noexcept { - + if (rp3dBody == nullptr) + { + SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID()) + return; + } + + rp3dBody->applyLocalForceAtWorldPosition(relativeForce, worldPos); } void SHRigidBodyComponent::AddTorque(const SHVec3& torque) const noexcept { - + if (rp3dBody == nullptr) + { + SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID()) + return; + } + + rp3dBody->applyWorldTorque(torque); } void SHRigidBodyComponent::AddRelativeTorque(const SHVec3& relativeTorque) const noexcept { - + if (rp3dBody == nullptr) + { + SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID()) + return; + } + + rp3dBody->applyLocalTorque(relativeTorque); } } // namespace SHADE diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index d4da329b..389e518f 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -16,6 +16,8 @@ // Project Headers #include "ECS_Base/Managers/SHComponentManager.h" #include "ECS_Base/Managers/SHEntityManager.h" +#include "ECS_Base/Managers/SHSystemManager.h" +#include "Editor/SHEditor.hpp" #include "Math/SHMathHelpers.h" #include "Scene/SHSceneManager.h" #include "Math/Transform/SHTransformComponent.h" @@ -205,23 +207,6 @@ namespace SHADE factory.destroyPhysicsWorld(world); } - //void SHPhysicsSystem::RemoveRigidBody(EntityID entityID) noexcept - //{ - // #ifdef _DEBUG - // SHLOG_INFO("Removing a Rigidbody from the Physics World.") - // #endif - - // auto* physicsObject = GetPhysicsObject(entityID); - // SHASSERT(physicsObject != nullptr, "Physics object has been lost from the world!") - //} - - //void SHPhysicsSystem::RemoveCollider(EntityID entityID) noexcept - //{ - // #ifdef _DEBUG - // SHLOG_INFO("Removing a Collider from the Physics World.") - // #endif - //} - void SHPhysicsSystem::AddCollisionShape(EntityID entityID, SHCollider* collider) { auto* physicsObject = GetPhysicsObject(entityID); @@ -238,24 +223,55 @@ namespace SHADE { auto* system = reinterpret_cast(GetSystem()); - // Update bodies and colliders if component is dirty - system->SyncRigidBodyComponents(SHComponentManager::GetDense()); - system->SyncColliderComponents(SHComponentManager::GetDense()); - // Sync transforms - for (auto& physicsObject : system->map | std::views::values) + for (auto& [entityID, physicsObject] : system->map) { // Ensure a valid physics Object if (physicsObject.rp3dBody == nullptr) continue; - const auto* TF = SHComponentManager::GetComponent(physicsObject.entityID); - if (TF->HasChanged()) + auto* rigidBodyComponent = SHComponentManager::GetComponent_s(entityID); + + // Clear all forces and velocities if editor is not in play + if (SHSystemManager::GetSystem()->editorState == SHEditor::State::STOP) { - physicsObject.SetPosition(TF->GetWorldPosition()); - physicsObject.SetOrientation(TF->GetWorldOrientation()); + if (rigidBodyComponent) + { + auto* rp3dRigidBody = reinterpret_cast(physicsObject.rp3dBody); + rp3dRigidBody->resetForce(); + rp3dRigidBody->resetTorque(); + rp3dRigidBody->setLinearVelocity(SHVec3::Zero); + rp3dRigidBody->setAngularVelocity(SHVec3::Zero); + } + } + + const auto* transformComponent = SHComponentManager::GetComponent_s(entityID); + if (transformComponent && transformComponent->HasChanged()) + { + const auto WORLD_POS = transformComponent->GetWorldPosition(); + const auto WORLD_ROT = transformComponent->GetWorldOrientation(); + + physicsObject.SetPosition(WORLD_POS); + physicsObject.SetOrientation(WORLD_ROT); + + if (rigidBodyComponent) + { + rigidBodyComponent->position = WORLD_POS; + rigidBodyComponent->orientation = WORLD_ROT; + } + + auto* colliderComponent = SHComponentManager::GetComponent_s(entityID); + if (colliderComponent) + { + colliderComponent->position = WORLD_POS; + colliderComponent->orientation = WORLD_ROT; + } } } + + // Update bodies and colliders if component is dirty + system->SyncRigidBodyComponents(SHComponentManager::GetDense()); + system->SyncColliderComponents(SHComponentManager::GetDense()); } void SHPhysicsSystem::PhysicsFixedUpdate::Execute(double dt) noexcept @@ -431,9 +447,9 @@ namespace SHADE } // Convert RP3D Transform to SHADE - auto* tfComponent = SHComponentManager::GetComponent(entityID); - tfComponent->SetWorldPosition(rp3dPos); - tfComponent->SetWorldOrientation(rp3dRot); + auto* transformComponent = SHComponentManager::GetComponent(entityID); + transformComponent->SetWorldPosition(rp3dPos); + transformComponent->SetWorldOrientation(rp3dRot); // Cache transforms physicsObject.prevTransform = CURRENT_TF; @@ -480,6 +496,7 @@ namespace SHADE rp3d::Transform{ rigidBodyComponent->position, rigidBodyComponent->orientation } ); + rigidBodyComponent->rp3dBody = reinterpret_cast(physicsObject->rp3dBody); // Add collision shapes back into the body if (colliderComponent != nullptr) @@ -491,6 +508,8 @@ namespace SHADE if (ADDED_ID == COLLIDER_ID) { + SHASSERT(colliderComponent != nullptr, "Collider Component was not added to Entity " + std::to_string(ENTITY_ID) + "!"); + colliderComponent->position = transformComponent->GetWorldPosition(); colliderComponent->orientation = transformComponent->GetWorldOrientation(); @@ -530,7 +549,7 @@ namespace SHADE if (REMOVED_ID == RIGID_BODY_ID) { world->destroyRigidBody(reinterpret_cast(physicsObject->rp3dBody)); - physicsObject->rp3dBody = nullptr; + physicsObject->rp3dBody = nullptr; auto* colliderComponent = SHComponentManager::GetComponent_s(ENTITY_ID); if (colliderComponent != nullptr) @@ -544,13 +563,23 @@ namespace SHADE for (auto& collider : colliderComponent->colliders | std::views::keys) physicsObject->AddCollider(&collider); } + + // Wake up all physics objects + for (auto& [entityID, object] : map) + { + if (SHComponentManager::HasComponent(entityID)) + reinterpret_cast(object.rp3dBody)->setIsSleeping(false); + } } if (REMOVED_ID == COLLIDER_ID) { // Remove all colliders for (uint32_t i = 0; i < physicsObject->rp3dBody->getNbColliders(); ++i) - physicsObject->rp3dBody->removeCollider(physicsObject->rp3dBody->getCollider(i)); + { + auto* collider = physicsObject->rp3dBody->getCollider(i); + physicsObject->rp3dBody->removeCollider(collider); + } } if (physicsObject->rp3dBody == nullptr) From 12758878c5c5f9ddad6e79448dc1c7f0bbf56905 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Wed, 26 Oct 2022 16:55:28 +0800 Subject: [PATCH 49/50] Fixed bug with multiple collider removals --- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index 389e518f..832f9688 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -575,7 +575,9 @@ namespace SHADE if (REMOVED_ID == COLLIDER_ID) { // Remove all colliders - for (uint32_t i = 0; i < physicsObject->rp3dBody->getNbColliders(); ++i) + const int NUM_COLLIDERS = static_cast(physicsObject->rp3dBody->getNbColliders()); + + for (int i = NUM_COLLIDERS - 1; i >= 0; --i) { auto* collider = physicsObject->rp3dBody->getCollider(i); physicsObject->rp3dBody->removeCollider(collider); From 19ceab84dfd169b7d2b8382533db426e8a2c785e Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Wed, 26 Oct 2022 18:35:41 +0800 Subject: [PATCH 50/50] Added events for adding and removing colliders --- SHADE_Engine/src/Events/SHEventDefines.h | 3 +++ SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 18 +++++++++++++++++- SHADE_Engine/src/Physics/SHPhysicsSystem.h | 16 ++++++++++++++++ SHADE_Engine/src/Scene/SHSceneGraph.h | 6 +++++- 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/SHADE_Engine/src/Events/SHEventDefines.h b/SHADE_Engine/src/Events/SHEventDefines.h index fc9f41e1..804fbfec 100644 --- a/SHADE_Engine/src/Events/SHEventDefines.h +++ b/SHADE_Engine/src/Events/SHEventDefines.h @@ -11,3 +11,6 @@ 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 }; + diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index 832f9688..1c6e79d7 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -210,13 +210,29 @@ namespace SHADE void SHPhysicsSystem::AddCollisionShape(EntityID entityID, SHCollider* collider) { auto* physicsObject = GetPhysicsObject(entityID); - physicsObject->AddCollider(collider); + + const SHPhysicsColliderAddedEvent COLLIDER_ADDED_EVENT_DATA + { + .entityID = entityID + , .colliderType = collider->GetType() + , .colliderIndex = physicsObject->AddCollider(collider) + }; + + SHEventManager::BroadcastEvent(COLLIDER_ADDED_EVENT_DATA, SH_PHYSICS_COLLIDER_ADDED_EVENT); } void SHPhysicsSystem::RemoveCollisionShape(EntityID entityID, int index) { auto* physicsObject = GetPhysicsObject(entityID); physicsObject->RemoveCollider(index); + + const SHPhysicsColliderRemovedEvent COLLIDER_REMOVED_EVENT_DATA + { + .entityID = entityID + , .colliderIndex = index + }; + + SHEventManager::BroadcastEvent(COLLIDER_REMOVED_EVENT_DATA, SH_PHYSICS_COLLIDER_REMOVED_EVENT); } void SHPhysicsSystem::PhysicsPreUpdate::Execute(double) noexcept diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/SHPhysicsSystem.h index 0af22e7a..a3c3bea1 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.h @@ -184,5 +184,21 @@ namespace SHADE SHEventHandle RemovePhysicsComponent (SHEventPtr removeComponentEvent); }; + /*-----------------------------------------------------------------------------------*/ + /* Event Data Definitions */ + /*-----------------------------------------------------------------------------------*/ + + struct SHPhysicsColliderAddedEvent + { + EntityID entityID; + SHCollider::Type colliderType; + int colliderIndex; + }; + + struct SHPhysicsColliderRemovedEvent + { + EntityID entityID; + int colliderIndex; + }; } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Scene/SHSceneGraph.h b/SHADE_Engine/src/Scene/SHSceneGraph.h index a4cf45eb..b52fd1ff 100644 --- a/SHADE_Engine/src/Scene/SHSceneGraph.h +++ b/SHADE_Engine/src/Scene/SHSceneGraph.h @@ -158,9 +158,13 @@ namespace SHADE SHSceneNode* AllocateNode (EntityID entityID); void ReleaseNode (SHSceneNode* node) noexcept; - static void TraverseAndInvokePredicate (const SHSceneNode* node, const UnaryFunction& predicate); + static void TraverseAndInvokeFunction (const SHSceneNode* node, const UnaryFunction& function); }; + /*-----------------------------------------------------------------------------------*/ + /* Event Data Definitions */ + /*-----------------------------------------------------------------------------------*/ + struct SHSceneGraphChangeParentEvent { SHSceneNode* node;