diff --git a/Assets/Materials/AnimatedBag.shmat b/Assets/Materials/AnimatedBag.shmat new file mode 100644 index 00000000..3f0d9707 --- /dev/null +++ b/Assets/Materials/AnimatedBag.shmat @@ -0,0 +1,8 @@ +- VertexShader: 47911992 + FragmentShader: 46377769 + SubPass: G-Buffer Write + Properties: + data.color: {x: 1, y: 1, z: 1, w: 1} + data.textureIndex: 58303057 + data.alpha: 0 + data.beta: {x: 1, y: 1, z: 1} \ No newline at end of file diff --git a/Assets/Materials/AnimatedBag.shmat.shmeta b/Assets/Materials/AnimatedBag.shmat.shmeta new file mode 100644 index 00000000..6457c1c3 --- /dev/null +++ b/Assets/Materials/AnimatedBag.shmat.shmeta @@ -0,0 +1,3 @@ +Name: AnimatedBag +ID: 117923942 +Type: 7 diff --git a/Assets/Models/ExteriorMeshs.shmodel b/Assets/Models/ExteriorMeshs.shmodel index 90def744..75d092b5 100644 Binary files a/Assets/Models/ExteriorMeshs.shmodel and b/Assets/Models/ExteriorMeshs.shmodel differ diff --git a/Assets/Models/HouseModular.shmodel b/Assets/Models/HouseModular.shmodel index 4e280293..644f41ab 100644 Binary files a/Assets/Models/HouseModular.shmodel and b/Assets/Models/HouseModular.shmodel differ diff --git a/Assets/Models/KitchenAddOns1.shmodel b/Assets/Models/KitchenAddOns1.shmodel index f43ea993..5b916be0 100644 Binary files a/Assets/Models/KitchenAddOns1.shmodel and b/Assets/Models/KitchenAddOns1.shmodel differ diff --git a/Assets/Models/KitchenCounterEmpty.shmodel b/Assets/Models/KitchenCounterEmpty.shmodel index fcffa6b7..88212a89 100644 Binary files a/Assets/Models/KitchenCounterEmpty.shmodel and b/Assets/Models/KitchenCounterEmpty.shmodel differ diff --git a/Assets/Models/KitchenCounterMeshs.shmodel b/Assets/Models/KitchenCounterMeshs.shmodel index 243f69b0..3fd27900 100644 Binary files a/Assets/Models/KitchenCounterMeshs.shmodel and b/Assets/Models/KitchenCounterMeshs.shmodel differ diff --git a/Assets/Models/KitchenShelves1.shmodel b/Assets/Models/KitchenShelves1.shmodel index 8c31fff3..7ba536c9 100644 Binary files a/Assets/Models/KitchenShelves1.shmodel and b/Assets/Models/KitchenShelves1.shmodel differ diff --git a/Assets/Models/MD_BreakableObjects1.shmodel b/Assets/Models/MD_BreakableObjects1.shmodel index 6d83f9fd..3212f450 100644 Binary files a/Assets/Models/MD_BreakableObjects1.shmodel and b/Assets/Models/MD_BreakableObjects1.shmodel differ diff --git a/Assets/Models/MD_FoodItems.shmodel b/Assets/Models/MD_FoodItems.shmodel index 4466830e..597ce285 100644 Binary files a/Assets/Models/MD_FoodItems.shmodel and b/Assets/Models/MD_FoodItems.shmodel differ diff --git a/Assets/Models/MD_Homeowner-NoRig.shmodel b/Assets/Models/MD_Homeowner-NoRig.shmodel index 639d4981..b359254d 100644 Binary files a/Assets/Models/MD_Homeowner-NoRig.shmodel and b/Assets/Models/MD_Homeowner-NoRig.shmodel differ diff --git a/Assets/Models/MD_SkyDome01.shmodel b/Assets/Models/MD_SkyDome01.shmodel index a6b1f487..dbfd004a 100644 Binary files a/Assets/Models/MD_SkyDome01.shmodel and b/Assets/Models/MD_SkyDome01.shmodel differ diff --git a/Assets/Models/Quad.shmodel b/Assets/Models/Quad.shmodel index da121412..73c7a41b 100644 Binary files a/Assets/Models/Quad.shmodel and b/Assets/Models/Quad.shmodel differ diff --git a/Assets/Models/racoon.shmodel b/Assets/Models/racoon.shmodel index b25e8223..e15051b6 100644 Binary files a/Assets/Models/racoon.shmodel and b/Assets/Models/racoon.shmodel differ diff --git a/SHADE_Engine/src/Animation/SHAnimationClip.h b/SHADE_Engine/src/Animation/SHAnimationClip.h index 8a10ce3a..58b5681a 100644 --- a/SHADE_Engine/src/Animation/SHAnimationClip.h +++ b/SHADE_Engine/src/Animation/SHAnimationClip.h @@ -67,7 +67,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ const std::vector& GetChannels() const noexcept { return channels; } int GetTicksPerSecond() const noexcept { return ticksPerSecond; } - float GetTotalTime() const noexcept { return totalTime; } + float GetTotalTime() const noexcept { return totalTime/(float)ticksPerSecond; } private: /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Assets/Asset Types/Models/SHRigAsset.cpp b/SHADE_Engine/src/Assets/Asset Types/Models/SHRigAsset.cpp index 6e1ef2b3..f5186a0c 100644 --- a/SHADE_Engine/src/Assets/Asset Types/Models/SHRigAsset.cpp +++ b/SHADE_Engine/src/Assets/Asset Types/Models/SHRigAsset.cpp @@ -7,25 +7,7 @@ namespace SHADE { SHRigAsset::~SHRigAsset() { - if (root == nullptr) - { - return; - } - - std::queue nodeQueue; - nodeQueue.push(root); - - while(!nodeQueue.empty()) - { - auto curr = nodeQueue.front(); - nodeQueue.pop(); - - for (auto child : curr->children) - { - nodeQueue.push(child); - } - - delete curr; - } + if (root != nullptr) + delete[] root; } } diff --git a/SHADE_Engine/src/Assets/Libraries/Loaders/SHModelLoader.cpp b/SHADE_Engine/src/Assets/Libraries/Loaders/SHModelLoader.cpp index 6773fb28..aea46add 100644 --- a/SHADE_Engine/src/Assets/Libraries/Loaders/SHModelLoader.cpp +++ b/SHADE_Engine/src/Assets/Libraries/Loaders/SHModelLoader.cpp @@ -176,8 +176,8 @@ namespace SHADE std::queue> nodeQueue; nodeQueue.emplace(std::make_pair(nodePool, dst)); - auto depthPtr = nodePool + 1; - auto depthTempPtr = dst + 1; + SHRigNode* depthPtr = nodePool + 1; + NodeTemp* depthTempPtr = dst + 1; while(!nodeQueue.empty()) { @@ -239,16 +239,19 @@ namespace SHADE bone.name.resize(info.charCount); file.read(bone.name.data(), info.charCount); file.read(reinterpret_cast(&bone.offset), sizeof(SHMatrix)); - - uint32_t weightCount; - file.read(reinterpret_cast(&weightCount), sizeof(uint32_t)); - bone.weights.resize(weightCount); - file.read(reinterpret_cast(bone.weights.data()), sizeof(BoneWeight) * weightCount); + + bone.weights.resize(info.weightCount); + file.read(reinterpret_cast(bone.weights.data()), sizeof(BoneWeight) * info.weightCount); } data.VertexBoneIndices.resize(header.vertexCount); data.VertexBoneWeights.resize(header.vertexCount); + //for (auto& weight : data.VertexBoneWeights) + //{ + // weight = { -0.1f }; + //} + for (uint32_t boneIndex{0}; boneIndex < bones.size(); ++boneIndex) { auto const& bone = bones[boneIndex]; @@ -263,6 +266,7 @@ namespace SHADE { boneIndices[j] = boneIndex; boneWeight[j] = weight.weight; + break; } } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index fdbbad24..9bd5437d 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -37,40 +37,50 @@ namespace SHADE /* SHBatch - Constructors/Destructors */ /*-----------------------------------------------------------------------------------*/ SHBatch::SHBatch(Handle pipeline) - : pipeline{ pipeline } + : pipeline{ pipeline } { if (!pipeline) throw std::invalid_argument("Attempted to create a SHBatch with an invalid SHPipeline!"); + // Check the pipeline and flag it depending on whether or not it is animated + isAnimated = checkIfIsAnimatedPipeline(pipeline); + // Mark all as dirty setAllDirtyFlags(); } SHBatch::SHBatch(SHBatch&& rhs) - : device { rhs.device } - , pipeline { rhs.pipeline } - , referencedMatInstances { std::move(rhs.referencedMatInstances) } - , matBufferDirty { std::move(rhs.matBufferDirty) } - , subBatches { std::move(rhs.subBatches) } - , isDirty { std::move(rhs.isDirty) } - , drawData { std::move(rhs.drawData) } - , transformData { std::move(rhs.transformData) } - , instancedIntegerData { std::move(rhs.instancedIntegerData) } - , matPropsData { std::move(rhs.matPropsData) } - , matPropsDataSize { rhs.matPropsDataSize } - , singleMatPropAlignedSize { rhs.singleMatPropAlignedSize } - , singleMatPropSize { rhs.singleMatPropSize } - , isCPUBuffersDirty { rhs.isCPUBuffersDirty } - , drawDataBuffer { rhs.drawDataBuffer } - , transformDataBuffer { rhs.transformDataBuffer } - , instancedIntegerBuffer { rhs.instancedIntegerBuffer } - , matPropsBuffer { rhs.matPropsBuffer } - , instanceDataDescSet { rhs.instanceDataDescSet } + : device { rhs.device } + , isAnimated { rhs.isAnimated } + , pipeline { rhs.pipeline } + , referencedMatInstances { std::move(rhs.referencedMatInstances) } + , matBufferDirty { std::move(rhs.matBufferDirty) } + , subBatches { std::move(rhs.subBatches) } + , isDirty { std::move(rhs.isDirty) } + , drawData { std::move(rhs.drawData) } + , transformData { std::move(rhs.transformData) } + , instancedIntegerData { std::move(rhs.instancedIntegerData) } + , matPropsData { std::move(rhs.matPropsData) } + , matPropsDataSize { rhs.matPropsDataSize } + , singleMatPropAlignedSize { rhs.singleMatPropAlignedSize } + , singleMatPropSize { rhs.singleMatPropSize } + , boneMatrixData { std::move(rhs.boneMatrixData) } + , boneMatrixIndices { std::move(rhs.boneMatrixIndices) } + , isCPUBuffersDirty { rhs.isCPUBuffersDirty } + , drawDataBuffer { rhs.drawDataBuffer } + , transformDataBuffer { rhs.transformDataBuffer } + , instancedIntegerBuffer { rhs.instancedIntegerBuffer } + , matPropsBuffer { rhs.matPropsBuffer } + , boneMatrixBuffer { rhs.boneMatrixBuffer } + , boneMatrixFirstIndexBuffer { rhs.boneMatrixFirstIndexBuffer } + , instanceDataDescSet { rhs.instanceDataDescSet } { - rhs.drawDataBuffer = {}; - rhs.transformDataBuffer = {}; - rhs.instancedIntegerBuffer = {}; - rhs.matPropsBuffer = {}; + rhs.drawDataBuffer = {}; + rhs.transformDataBuffer = {}; + rhs.instancedIntegerBuffer = {}; + rhs.matPropsBuffer = {}; + rhs.boneMatrixBuffer = {}; + rhs.boneMatrixFirstIndexBuffer = {}; rhs.instanceDataDescSet = {}; } @@ -79,31 +89,38 @@ namespace SHADE if (this == &rhs) return *this; - device = rhs.device ; - pipeline = rhs.pipeline ; - referencedMatInstances = std::move(rhs.referencedMatInstances); - matBufferDirty = std::move(rhs.matBufferDirty) ; - subBatches = std::move(rhs.subBatches) ; - isDirty = std::move(rhs.isDirty) ; - drawData = std::move(rhs.drawData) ; - transformData = std::move(rhs.transformData) ; - instancedIntegerData = std::move(rhs.instancedIntegerData) ; - matPropsData = std::move(rhs.matPropsData) ; - matPropsDataSize = rhs.matPropsDataSize ; - singleMatPropAlignedSize = rhs.singleMatPropAlignedSize ; - singleMatPropSize = rhs.singleMatPropSize ; - isCPUBuffersDirty = rhs.isCPUBuffersDirty ; - drawDataBuffer = rhs.drawDataBuffer ; - transformDataBuffer = rhs.transformDataBuffer ; - instancedIntegerBuffer = rhs.instancedIntegerBuffer ; - matPropsBuffer = rhs.matPropsBuffer ; - instanceDataDescSet = rhs.instanceDataDescSet ; + device = rhs.device ; + isAnimated = rhs.isAnimated ; + pipeline = rhs.pipeline ; + referencedMatInstances = std::move(rhs.referencedMatInstances); + matBufferDirty = std::move(rhs.matBufferDirty) ; + subBatches = std::move(rhs.subBatches) ; + isDirty = std::move(rhs.isDirty) ; + drawData = std::move(rhs.drawData) ; + transformData = std::move(rhs.transformData) ; + instancedIntegerData = std::move(rhs.instancedIntegerData) ; + matPropsData = std::move(rhs.matPropsData) ; + matPropsDataSize = rhs.matPropsDataSize ; + singleMatPropAlignedSize = rhs.singleMatPropAlignedSize ; + singleMatPropSize = rhs.singleMatPropSize ; + boneMatrixData = std::move(rhs.boneMatrixData) ; + boneMatrixIndices = std::move(rhs.boneMatrixIndices) ; + isCPUBuffersDirty = rhs.isCPUBuffersDirty ; + drawDataBuffer = rhs.drawDataBuffer ; + transformDataBuffer = rhs.transformDataBuffer ; + instancedIntegerBuffer = rhs.instancedIntegerBuffer ; + matPropsBuffer = rhs.matPropsBuffer ; + boneMatrixBuffer = rhs.boneMatrixBuffer ; + boneMatrixFirstIndexBuffer = rhs.boneMatrixFirstIndexBuffer ; + instanceDataDescSet = rhs.instanceDataDescSet ; // Unset values - rhs.drawDataBuffer = {}; - rhs.transformDataBuffer = {}; - rhs.instancedIntegerBuffer = {}; - rhs.matPropsBuffer = {}; + rhs.drawDataBuffer = {}; + rhs.transformDataBuffer = {}; + rhs.instancedIntegerBuffer = {}; + rhs.matPropsBuffer = {}; + rhs.boneMatrixBuffer = {}; + rhs.boneMatrixFirstIndexBuffer = {}; rhs.instanceDataDescSet = {}; return *this; @@ -363,25 +380,27 @@ namespace SHADE // Populate on the CPU for (auto& subBatch : subBatches) - for (auto rendId : subBatch.Renderables) + for (auto rendId : subBatch.Renderables) + { + auto* renderable = SHComponentManager::GetComponent(rendId); + instancedIntegerData.emplace_back(SHInstancedIntegerData { - auto* renderable = SHComponentManager::GetComponent(rendId); - instancedIntegerData.emplace_back(SHInstancedIntegerData - { - rendId, - renderable->GetLightLayer() - } - ); - } + rendId, + renderable->GetLightLayer() + }); + } // Transfer to GPU if (instancedIntegerBuffer[frameIndex] && !drawData.empty()) instancedIntegerBuffer[frameIndex]->WriteToMemory(instancedIntegerData.data(), static_cast(instancedIntegerData.size() * sizeof(SHInstancedIntegerData)), 0, 0); - } void SHBatch::UpdateAnimationBuffer(uint32_t frameIndex) { + // Ignore if not animated batch + if (!isAnimated) + return; + // Frame Index check if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS) { @@ -392,6 +411,9 @@ namespace SHADE // Reset Animation Matrix Data boneMatrixData.clear(); + // Add the first identity matrix into the bone matrix data + boneMatrixData.emplace_back(SHMatrix::Identity); // This kills the GPU + // Populate on the CPU for (auto& subBatch : subBatches) for (auto rendId : subBatch.Renderables) @@ -402,6 +424,7 @@ namespace SHADE const auto& MATRICES = animator->GetBoneMatrices(); boneMatrixData.insert(boneMatrixData.end(), MATRICES.cbegin(), MATRICES.cend()); } + // We don't have to account for missing animators or reset indices as the renderable list are not updated at this point } // Update GPU Buffers @@ -446,10 +469,19 @@ namespace SHADE // - EID data instancedIntegerData.reserve(numTotalElements); instancedIntegerData.clear(); + // - Bone Data + if (isAnimated) + { + boneMatrixData.clear(); + boneMatrixIndices.clear(); + boneMatrixIndices.reserve(numTotalElements); - auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING); + // Add the first identity matrix into the bone matrix data + boneMatrixData.emplace_back(SHMatrix::Identity); + } // - Material Properties Data + auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING); const Handle SHADER_INFO = pipeline->GetPipelineLayout()->GetShaderBlockInterface ( descMappings.at(SHPredefinedDescriptorTypes::PER_INSTANCE_BATCH), @@ -469,10 +501,6 @@ namespace SHADE matPropsDataSize = matPropTotalBytes; } } - // - Bone Data - boneMatrixData.clear(); - boneMatrixIndices.clear(); - boneMatrixIndices.reserve(numTotalElements); // Build Sub Batches uint32_t nextInstanceIndex = 0; @@ -548,12 +576,20 @@ namespace SHADE } // Bone Data - auto animator = SHComponentManager::GetComponent_s(rendId); - if (animator) + if (isAnimated) { - boneMatrixIndices.emplace_back(static_cast(boneMatrixData.size())); - const auto& BONE_MATRICES = animator->GetBoneMatrices(); - boneMatrixData.insert(boneMatrixData.end(), BONE_MATRICES.cbegin(), BONE_MATRICES.cend()); + auto animator = SHComponentManager::GetComponent_s(rendId); + if (animator) + { + boneMatrixIndices.emplace_back(static_cast(boneMatrixData.size())); + const auto& BONE_MATRICES = animator->GetBoneMatrices(); + boneMatrixData.insert(boneMatrixData.end(), BONE_MATRICES.cbegin(), BONE_MATRICES.cend()); + } + else + { + // Take the first matrix which is always identity + boneMatrixIndices.emplace_back(static_cast(0)); + } } } } @@ -590,7 +626,7 @@ namespace SHADE "Batch Instance Data Buffer" ); // - Bone Matrix Indices - if (!boneMatrixIndices.empty()) + if (isAnimated && !boneMatrixIndices.empty()) { const uint32_t BMI_DATA_BYTES = static_cast(boneMatrixIndices.size() * sizeof(uint32_t)); SHVkUtil::EnsureBufferAndCopyHostVisibleData @@ -625,7 +661,7 @@ namespace SHADE // Bind all required objects before drawing std::vector dynamicOffset{ 0 }; - if (!boneMatrixData.empty()) + if (isAnimated && !boneMatrixData.empty()) { dynamicOffset.emplace_back(0); } @@ -633,7 +669,7 @@ namespace SHADE cmdBuffer->BindPipeline(pipeline); cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0); cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::INTEGER_DATA, instancedIntegerBuffer[frameIndex], 0); - if (boneMatrixFirstIndexBuffer[frameIndex]) + if (isAnimated && boneMatrixFirstIndexBuffer[frameIndex]) { cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::BONE_MATRIX_FIRST_INDEX, boneMatrixFirstIndexBuffer[frameIndex], 0); } @@ -706,7 +742,9 @@ namespace SHADE layoutTypes = PreDefDescLayoutType::MATERIAL_AND_BONES; } - if (matPropsData || !boneMatrixData.empty()) + const bool MUST_BUILD_BONE_DESC = isAnimated && !boneMatrixData.empty(); + + if (matPropsData || MUST_BUILD_BONE_DESC) { // Make sure that we have a descriptor set if we don't already have one if (!instanceDataDescSet[frameIndex]) @@ -756,7 +794,7 @@ namespace SHADE } /* Animation Bone Data */ - if (!boneMatrixData.empty()) + if (MUST_BUILD_BONE_DESC) { // Update GPU Buffers const uint32_t BONE_MTX_DATA_BYTES = static_cast(boneMatrixData.size() * sizeof(SHMatrix)); @@ -786,4 +824,22 @@ namespace SHADE ); } } + + bool SHBatch::checkIfIsAnimatedPipeline(Handle pipeline) + { + if (!pipeline || !pipeline->GetPipelineLayout()) + return false; + + // Grab the pipeline descriptor set layouts + auto pipelineDescLayouts = pipeline->GetPipelineLayout()->GetDescriptorSetLayoutsPipeline(); + + // Check if they contain the material and bones layout, that indicates it is + using GfxPreDef = SHGraphicsPredefinedData; + using GfxPreDefType = GfxPreDef::PredefinedDescSetLayoutTypes; + const Handle BONE_DESC_SET_LAYOUT = GfxPreDef::GetPredefinedDescSetLayouts(GfxPreDefType::MATERIAL_AND_BONES)[0]; + return std::find_if(pipelineDescLayouts.begin(), pipelineDescLayouts.end(), [BONE_DESC_SET_LAYOUT](Handle layout) + { + return BONE_DESC_SET_LAYOUT == layout; + }) != pipelineDescLayouts.end(); + } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h index 913a7a04..86e17035 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h @@ -97,6 +97,7 @@ namespace SHADE bool IsEmpty() const noexcept { return subBatches.empty(); } Handle GetTransformBuffer(uint32_t frameIndex) const noexcept; Handle GetMDIBuffer(uint32_t frameIndex) const noexcept; + bool IsAnimated() const noexcept { return isAnimated; } private: /*---------------------------------------------------------------------------------*/ @@ -111,6 +112,8 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ // Resources Handle device; + // Config + bool isAnimated; // Whether the material supports animation // Batch Properties Handle pipeline; std::unordered_set> referencedMatInstances; @@ -126,7 +129,7 @@ namespace SHADE Byte matPropsDataSize = 0; Byte singleMatPropAlignedSize = 0; Byte singleMatPropSize = 0; - std::vector boneMatrixData; + std::vector boneMatrixData; // 0th element is always an identity matrix std::vector boneMatrixIndices; bool isCPUBuffersDirty = true; // GPU Buffers @@ -143,5 +146,6 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ void setAllDirtyFlags(); void rebuildDescriptorSetBuffers(uint32_t frameIndex, Handle descPool); + static bool checkIfIsAnimatedPipeline(Handle pipeline); }; }