Fleshed out SHAnimationComponent more and added preliminary implementation of SHBatch for bone data

This commit is contained in:
Kah Wei 2022-11-21 15:09:15 +08:00
parent 1ff8c9715d
commit 611744f5d4
4 changed files with 177 additions and 109 deletions

View File

@ -13,6 +13,9 @@ of DigiPen Institute of Technology is prohibited.
#include "SHpch.h" #include "SHpch.h"
// Primary Include // Primary Include
#include "SHAnimatorComponent.h" #include "SHAnimatorComponent.h"
// Project Includes
#include "SHRig.h"
#include "Math/SHMatrix.h"
namespace SHADE namespace SHADE
{ {

View File

@ -11,26 +11,48 @@ of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/ *//*************************************************************************************/
#pragma once #pragma once
// STL Includes
#include <vector>
// External Dependencies // External Dependencies
#include <rttr/registration> #include <rttr/registration>
// Project Includes // Project Includes
#include "ECS_Base/Components/SHComponent.h" #include "ECS_Base/Components/SHComponent.h"
#include "Resource/SHHandle.h"
namespace SHADE namespace SHADE
{ {
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Forward Declarations */ /* Forward Declarations */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
class SHRig;
struct SHMatrix;
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Type Definitions */ /* Type Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/// <summary>
/// Component that holds and controls the animation related properties of a skinned
/// mesh.
/// </summary>
class SH_API SHAnimatorComponent final : public SHComponent class SH_API SHAnimatorComponent final : public SHComponent
{ {
public:
/*---------------------------------------------------------------------------------*/
/* Getter Functions */
/*---------------------------------------------------------------------------------*/
const std::vector<SHMatrix>& GetBoneMatrices() const noexcept { return boneMatrices; }
private: private:
/*-------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Data Members */ /* Data Members */
/*-------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
Handle<SHRig> rig;
std::vector<SHMatrix> boneMatrices;
float currPlaybackTime = 0.0f;
/*---------------------------------------------------------------------------------*/
/* RTTR */
/*---------------------------------------------------------------------------------*/
RTTR_ENABLE() RTTR_ENABLE()
}; };
} }

View File

@ -29,12 +29,13 @@ of DigiPen Institute of Technology is prohibited.
#include "Graphics/Descriptors/SHVkDescriptorPool.h" #include "Graphics/Descriptors/SHVkDescriptorPool.h"
#include "Scene/SHSceneManager.h" #include "Scene/SHSceneManager.h"
#include "UI/SHUIComponent.h" #include "UI/SHUIComponent.h"
#include "Animation/SHAnimatorComponent.h"
namespace SHADE namespace SHADE
{ {
/*---------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* SHBatch - Usage Functions */ /* SHBatch - Constructors/Destructors */
/*---------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHBatch::SHBatch(Handle<SHVkPipeline> pipeline) SHBatch::SHBatch(Handle<SHVkPipeline> pipeline)
: pipeline{ pipeline } : pipeline{ pipeline }
{ {
@ -124,6 +125,9 @@ namespace SHADE
} }
} }
/*-----------------------------------------------------------------------------------*/
/* SHBatch - Usage Functions */
/*-----------------------------------------------------------------------------------*/
void SHBatch::Add(const SHRenderable* renderable) void SHBatch::Add(const SHRenderable* renderable)
{ {
// Ignore if null // Ignore if null
@ -407,8 +411,6 @@ namespace SHADE
// - EID data // - EID data
instancedIntegerData.reserve(numTotalElements); instancedIntegerData.reserve(numTotalElements);
instancedIntegerData.clear(); instancedIntegerData.clear();
// - Material Properties Data // - Material Properties Data
const Handle<SHShaderBlockInterface> SHADER_INFO = pipeline->GetPipelineLayout()->GetShaderBlockInterface const Handle<SHShaderBlockInterface> SHADER_INFO = pipeline->GetPipelineLayout()->GetShaderBlockInterface
( (
@ -429,6 +431,10 @@ namespace SHADE
matPropsDataSize = matPropTotalBytes; matPropsDataSize = matPropTotalBytes;
} }
} }
// - Bone Data
boneMatrixData.clear();
boneMatrixIndices.clear();
boneMatrixIndices.reserve(numTotalElements);
// Build Sub Batches // Build Sub Batches
uint32_t nextInstanceIndex = 0; uint32_t nextInstanceIndex = 0;
@ -499,6 +505,16 @@ namespace SHADE
//propsCurrPtr += singleMatPropAlignedSize; //propsCurrPtr += singleMatPropAlignedSize;
propsCurrPtr += singleMatPropSize; propsCurrPtr += singleMatPropSize;
} }
// Bone Data
auto animator = SHComponentManager::GetComponent_s<SHAnimatorComponent>(rendId);
if (animator)
{
boneMatrixIndices.emplace_back(static_cast<uint32_t>(boneMatrixData.size()));
const auto& BONE_MATRICES = animator->GetBoneMatrices();
boneMatrixData.insert(boneMatrixData.end(), BONE_MATRICES.cbegin(), BONE_MATRICES.cend());
}
} }
} }
@ -533,6 +549,24 @@ namespace SHADE
); );
// - Material Properties Buffer // - Material Properties Buffer
rebuildMaterialBuffers(frameIndex, descPool); rebuildMaterialBuffers(frameIndex, descPool);
// - Bone Buffers
if (!boneMatrixIndices.empty())
{
const uint32_t BONE_IDX_DATA_BYTES = static_cast<uint32_t>(boneMatrixIndices.size() * sizeof(uint32_t));
SHVkUtil::EnsureBufferAndCopyHostVisibleData
(
device, boneFirstIndexBuffer[frameIndex], boneMatrixIndices.data(), BONE_IDX_DATA_BYTES,
BuffUsage::eVertexBuffer,
"Batch Bone Index Buffer"
);
const uint32_t BONE_MTX_DATA_BYTES = static_cast<uint32_t>(boneMatrixData.size() * sizeof(uint32_t));
SHVkUtil::EnsureBufferAndCopyHostVisibleData
(
device, boneMatrixBuffer[frameIndex], boneMatrixData.data(), BONE_MTX_DATA_BYTES,
BuffUsage::eStorageBuffer,
"Batch Bone Matrix Buffer"
);
}
// Mark this frame as no longer dirty // Mark this frame as no longer dirty
isDirty[frameIndex] = false; isDirty[frameIndex] = false;
@ -569,6 +603,11 @@ namespace SHADE
dynamicOffset dynamicOffset
); );
} }
if (boneMatrixBuffer[frameIndex] && boneFirstIndexBuffer[frameIndex])
{
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::BONE_INDICES, boneFirstIndexBuffer[frameIndex], 0);
// TODO: Bind storage buffer
}
cmdBuffer->DrawMultiIndirect(drawDataBuffer[frameIndex], static_cast<uint32_t>(drawData.size())); cmdBuffer->DrawMultiIndirect(drawDataBuffer[frameIndex], static_cast<uint32_t>(drawData.size()));
cmdBuffer->EndLabeledSegment(); cmdBuffer->EndLabeledSegment();
} }

View File

@ -27,114 +27,118 @@ of DigiPen Institute of Technology is prohibited.
namespace SHADE namespace SHADE
{ {
/*-----------------------------------------------------------------------------------*/
/* Forward Declarations */
/*-----------------------------------------------------------------------------------*/
class SHVkBuffer;
class SHVkCommandBuffer;
class SHVkPipeline;
class SHMesh;
class SHRenderable;
class SHVkLogicalDevice;
class SHMaterialInstance;
class SHVkDescriptorSetGroup;
class SHVkDescriptorPool;
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
/*************************************************************************************/
/*!
\brief
Describes a segment of the sub batch operation.
*/
/*************************************************************************************/
struct SHSubBatch
{
public:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Forward Declarations */ /* Data Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
class SHVkBuffer; Handle<SHMesh> Mesh;
class SHVkCommandBuffer; std::unordered_set<EntityID> Renderables;
class SHVkPipeline; };
class SHMesh; /*************************************************************************************/
class SHRenderable; /*!
class SHVkLogicalDevice; \brief
class SHMaterialInstance; Describes a segment of the sub batch operation.
class SHVkDescriptorSetGroup; */
class SHVkDescriptorPool; /*************************************************************************************/
class SHBatch
{
public:
/*---------------------------------------------------------------------------------*/
/* Constructor/Destructors */
/*---------------------------------------------------------------------------------*/
SHBatch(Handle<SHVkPipeline> pipeline);
SHBatch(const SHBatch&) = delete;
SHBatch(SHBatch&& rhs);
SHBatch& operator=(const SHBatch&) = delete;
SHBatch& operator=(SHBatch&& rhs);
~SHBatch();
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Type Definitions */ /* Usage Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/***********************************************************************************/ void Add(const SHRenderable* renderable);
/*! void Remove(const SHRenderable* renderable);
\brief void Clear();
Describes a segment of the sub batch operation. void UpdateMaterialBuffer(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
*/ void UpdateTransformBuffer(uint32_t frameIndex);
/***********************************************************************************/ void UpdateInstancedIntegerBuffer(uint32_t frameIndex);
struct SHSubBatch void Build(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex);
{ void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex);
public:
/*-----------------------------------------------------------------------------*/
/* Data Members */
/*-----------------------------------------------------------------------------*/
Handle<SHMesh> Mesh;
std::unordered_set<EntityID> Renderables;
};
/***********************************************************************************/
/*!
\brief
Describes a segment of the sub batch operation.
*/
/***********************************************************************************/
class SHBatch
{
public:
/*-----------------------------------------------------------------------------*/
/* Constructor/Destructors */
/*-----------------------------------------------------------------------------*/
SHBatch(Handle<SHVkPipeline> pipeline);
SHBatch(const SHBatch&) = delete;
SHBatch(SHBatch&& rhs);
SHBatch& operator=(const SHBatch&) = delete;
SHBatch& operator=(SHBatch&& rhs);
~SHBatch();
/*-----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Usage Functions */ /* Getter Functions */
/*-----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void Add(const SHRenderable* renderable); Handle<SHVkPipeline> GetPipeline() const noexcept { return pipeline; };
void Remove(const SHRenderable* renderable); bool IsEmpty() const noexcept { return subBatches.empty(); }
void Clear();
void UpdateMaterialBuffer(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
void UpdateTransformBuffer(uint32_t frameIndex);
void UpdateInstancedIntegerBuffer(uint32_t frameIndex);
void Build(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) ;
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex);
/*-----------------------------------------------------------------------------*/ private:
/* Getter Functions */ /*---------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------*/ /* Type Definition */
Handle<SHVkPipeline> GetPipeline() const noexcept { return pipeline; }; /*---------------------------------------------------------------------------------*/
bool IsEmpty() const noexcept { return subBatches.empty(); } using TripleBool = std::array<bool, SHGraphicsConstants::NUM_FRAME_BUFFERS>;
using TripleBuffer = std::array<Handle<SHVkBuffer>, SHGraphicsConstants::NUM_FRAME_BUFFERS>;
using TripleDescSet = std::array<Handle<SHVkDescriptorSetGroup>, SHGraphicsConstants::NUM_FRAME_BUFFERS>;
private: /*---------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------*/ /* Data Members */
/* Type Definition */ /*---------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------*/ // Resources
using TripleBool = std::array<bool, SHGraphicsConstants::NUM_FRAME_BUFFERS>; Handle<SHVkLogicalDevice> device;
using TripleBuffer = std::array<Handle<SHVkBuffer>, SHGraphicsConstants::NUM_FRAME_BUFFERS>; // Batch Properties
using TripleDescSet = std::array<Handle<SHVkDescriptorSetGroup>, SHGraphicsConstants::NUM_FRAME_BUFFERS>; Handle<SHVkPipeline> pipeline;
std::unordered_set<Handle<SHMaterialInstance>> referencedMatInstances;
TripleBool matBufferDirty;
// Batch Tree
std::vector<SHSubBatch> subBatches;
TripleBool isDirty;
// CPU Buffers
std::vector<vk::DrawIndexedIndirectCommand> drawData;
std::vector<SHMatrix> transformData;
std::vector<SHInstancedIntegerData> instancedIntegerData;
std::unique_ptr<char> matPropsData;
Byte matPropsDataSize = 0;
Byte singleMatPropAlignedSize = 0;
Byte singleMatPropSize = 0;
std::vector<SHMatrix> boneMatrixData;
std::vector<uint32_t> boneMatrixIndices;
bool isCPUBuffersDirty = true;
// GPU Buffers
TripleBuffer drawDataBuffer;
TripleBuffer transformDataBuffer;
TripleBuffer instancedIntegerBuffer;
TripleBuffer matPropsBuffer;
TripleDescSet matPropsDescSet;
TripleBuffer boneMatrixBuffer;
TripleBuffer boneFirstIndexBuffer;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Data Members */ /* Helper Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
// Resources void setAllDirtyFlags();
Handle<SHVkLogicalDevice> device; void rebuildMaterialBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
// Batch Properties };
Handle<SHVkPipeline> pipeline;
std::unordered_set<Handle<SHMaterialInstance>> referencedMatInstances;
TripleBool matBufferDirty;
// Batch Tree
std::vector<SHSubBatch> subBatches;
TripleBool isDirty;
// CPU Buffers
std::vector<vk::DrawIndexedIndirectCommand> drawData;
std::vector<SHMatrix> transformData;
std::vector<SHInstancedIntegerData> instancedIntegerData;
std::unique_ptr<char> matPropsData;
Byte matPropsDataSize = 0;
Byte singleMatPropAlignedSize = 0;
Byte singleMatPropSize = 0;
bool isCPUBuffersDirty = true;
// GPU Buffers
TripleBuffer drawDataBuffer;
TripleBuffer transformDataBuffer;
TripleBuffer instancedIntegerBuffer;
TripleBuffer matPropsBuffer;
TripleDescSet matPropsDescSet;
/*-----------------------------------------------------------------------------*/
/* Helper Functions */
/*-----------------------------------------------------------------------------*/
void setAllDirtyFlags();
void rebuildMaterialBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
};
} }