Added isAnimated check with base 0-index identity matrix for bones

This commit is contained in:
Kah Wei 2023-01-17 22:55:33 +08:00
parent 20ffd67fcc
commit b36145fa39
1 changed files with 56 additions and 15 deletions

View File

@ -397,6 +397,10 @@ namespace SHADE
void SHBatch::UpdateAnimationBuffer(uint32_t frameIndex) void SHBatch::UpdateAnimationBuffer(uint32_t frameIndex)
{ {
// Ignore if not animated batch
if (!isAnimated)
return;
// Frame Index check // Frame Index check
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS) if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
{ {
@ -407,6 +411,9 @@ namespace SHADE
// Reset Animation Matrix Data // Reset Animation Matrix Data
boneMatrixData.clear(); 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 // Populate on the CPU
for (auto& subBatch : subBatches) for (auto& subBatch : subBatches)
for (auto rendId : subBatch.Renderables) for (auto rendId : subBatch.Renderables)
@ -417,6 +424,7 @@ namespace SHADE
const auto& MATRICES = animator->GetBoneMatrices(); const auto& MATRICES = animator->GetBoneMatrices();
boneMatrixData.insert(boneMatrixData.end(), MATRICES.cbegin(), MATRICES.cend()); 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 // Update GPU Buffers
@ -461,10 +469,19 @@ namespace SHADE
// - EID data // - EID data
instancedIntegerData.reserve(numTotalElements); instancedIntegerData.reserve(numTotalElements);
instancedIntegerData.clear(); 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 // - Material Properties Data
auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING);
const Handle<SHShaderBlockInterface> SHADER_INFO = pipeline->GetPipelineLayout()->GetShaderBlockInterface const Handle<SHShaderBlockInterface> SHADER_INFO = pipeline->GetPipelineLayout()->GetShaderBlockInterface
( (
descMappings.at(SHPredefinedDescriptorTypes::PER_INSTANCE_BATCH), descMappings.at(SHPredefinedDescriptorTypes::PER_INSTANCE_BATCH),
@ -484,10 +501,6 @@ 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;
@ -563,12 +576,20 @@ namespace SHADE
} }
// Bone Data // Bone Data
auto animator = SHComponentManager::GetComponent_s<SHAnimatorComponent>(rendId); if (isAnimated)
if (animator)
{ {
boneMatrixIndices.emplace_back(static_cast<uint32_t>(boneMatrixData.size())); auto animator = SHComponentManager::GetComponent_s<SHAnimatorComponent>(rendId);
const auto& BONE_MATRICES = animator->GetBoneMatrices(); if (animator)
boneMatrixData.insert(boneMatrixData.end(), BONE_MATRICES.cbegin(), BONE_MATRICES.cend()); {
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());
}
else
{
// Take the first matrix which is always identity
boneMatrixIndices.emplace_back(static_cast<uint32_t>(0));
}
} }
} }
} }
@ -605,7 +626,7 @@ namespace SHADE
"Batch Instance Data Buffer" "Batch Instance Data Buffer"
); );
// - Bone Matrix Indices // - Bone Matrix Indices
if (!boneMatrixIndices.empty()) if (isAnimated && !boneMatrixIndices.empty())
{ {
const uint32_t BMI_DATA_BYTES = static_cast<uint32_t>(boneMatrixIndices.size() * sizeof(uint32_t)); const uint32_t BMI_DATA_BYTES = static_cast<uint32_t>(boneMatrixIndices.size() * sizeof(uint32_t));
SHVkUtil::EnsureBufferAndCopyHostVisibleData SHVkUtil::EnsureBufferAndCopyHostVisibleData
@ -640,7 +661,7 @@ namespace SHADE
// Bind all required objects before drawing // Bind all required objects before drawing
std::vector<uint32_t> dynamicOffset{ 0 }; std::vector<uint32_t> dynamicOffset{ 0 };
if (!boneMatrixData.empty()) if (isAnimated && !boneMatrixData.empty())
{ {
dynamicOffset.emplace_back(0); dynamicOffset.emplace_back(0);
} }
@ -648,7 +669,7 @@ namespace SHADE
cmdBuffer->BindPipeline(pipeline); cmdBuffer->BindPipeline(pipeline);
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0); cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0);
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::INTEGER_DATA, instancedIntegerBuffer[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); cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::BONE_MATRIX_FIRST_INDEX, boneMatrixFirstIndexBuffer[frameIndex], 0);
} }
@ -721,7 +742,9 @@ namespace SHADE
layoutTypes = PreDefDescLayoutType::MATERIAL_AND_BONES; 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 // Make sure that we have a descriptor set if we don't already have one
if (!instanceDataDescSet[frameIndex]) if (!instanceDataDescSet[frameIndex])
@ -771,7 +794,7 @@ namespace SHADE
} }
/* Animation Bone Data */ /* Animation Bone Data */
if (!boneMatrixData.empty()) if (MUST_BUILD_BONE_DESC)
{ {
// Update GPU Buffers // Update GPU Buffers
const uint32_t BONE_MTX_DATA_BYTES = static_cast<uint32_t>(boneMatrixData.size() * sizeof(SHMatrix)); const uint32_t BONE_MTX_DATA_BYTES = static_cast<uint32_t>(boneMatrixData.size() * sizeof(SHMatrix));
@ -801,4 +824,22 @@ namespace SHADE
); );
} }
} }
bool SHBatch::checkIfIsAnimatedPipeline(Handle<SHVkPipeline> 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<SHVkDescriptorSetLayout> BONE_DESC_SET_LAYOUT = GfxPreDef::GetPredefinedDescSetLayouts(GfxPreDefType::MATERIAL_AND_BONES)[0];
return std::find_if(pipelineDescLayouts.begin(), pipelineDescLayouts.end(), [BONE_DESC_SET_LAYOUT](Handle<SHVkDescriptorSetLayout> layout)
{
return BONE_DESC_SET_LAYOUT == layout;
}) != pipelineDescLayouts.end();
}
} }