Merge branch 'SP3-17-animation-system' of https://github.com/SHADE-DP/SHADE_Y3 into SP3-17-animation-system
This commit is contained in:
commit
6c6e3bfe28
|
@ -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}
|
|
@ -0,0 +1,3 @@
|
||||||
|
Name: AnimatedBag
|
||||||
|
ID: 117923942
|
||||||
|
Type: 7
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -67,7 +67,7 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
const std::vector<Channel>& GetChannels() const noexcept { return channels; }
|
const std::vector<Channel>& GetChannels() const noexcept { return channels; }
|
||||||
int GetTicksPerSecond() const noexcept { return ticksPerSecond; }
|
int GetTicksPerSecond() const noexcept { return ticksPerSecond; }
|
||||||
float GetTotalTime() const noexcept { return totalTime; }
|
float GetTotalTime() const noexcept { return totalTime/(float)ticksPerSecond; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -7,25 +7,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
SHRigAsset::~SHRigAsset()
|
SHRigAsset::~SHRigAsset()
|
||||||
{
|
{
|
||||||
if (root == nullptr)
|
if (root != nullptr)
|
||||||
{
|
delete[] root;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::queue<SHRigNode*> nodeQueue;
|
|
||||||
nodeQueue.push(root);
|
|
||||||
|
|
||||||
while(!nodeQueue.empty())
|
|
||||||
{
|
|
||||||
auto curr = nodeQueue.front();
|
|
||||||
nodeQueue.pop();
|
|
||||||
|
|
||||||
for (auto child : curr->children)
|
|
||||||
{
|
|
||||||
nodeQueue.push(child);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete curr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,8 +176,8 @@ namespace SHADE
|
||||||
std::queue<std::pair<SHRigNode*, NodeTemp*>> nodeQueue;
|
std::queue<std::pair<SHRigNode*, NodeTemp*>> nodeQueue;
|
||||||
nodeQueue.emplace(std::make_pair(nodePool, dst));
|
nodeQueue.emplace(std::make_pair(nodePool, dst));
|
||||||
|
|
||||||
auto depthPtr = nodePool + 1;
|
SHRigNode* depthPtr = nodePool + 1;
|
||||||
auto depthTempPtr = dst + 1;
|
NodeTemp* depthTempPtr = dst + 1;
|
||||||
|
|
||||||
while(!nodeQueue.empty())
|
while(!nodeQueue.empty())
|
||||||
{
|
{
|
||||||
|
@ -240,15 +240,18 @@ namespace SHADE
|
||||||
file.read(bone.name.data(), info.charCount);
|
file.read(bone.name.data(), info.charCount);
|
||||||
file.read(reinterpret_cast<char*>(&bone.offset), sizeof(SHMatrix));
|
file.read(reinterpret_cast<char*>(&bone.offset), sizeof(SHMatrix));
|
||||||
|
|
||||||
uint32_t weightCount;
|
bone.weights.resize(info.weightCount);
|
||||||
file.read(reinterpret_cast<char*>(&weightCount), sizeof(uint32_t));
|
file.read(reinterpret_cast<char*>(bone.weights.data()), sizeof(BoneWeight) * info.weightCount);
|
||||||
bone.weights.resize(weightCount);
|
|
||||||
file.read(reinterpret_cast<char*>(bone.weights.data()), sizeof(BoneWeight) * weightCount);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data.VertexBoneIndices.resize(header.vertexCount);
|
data.VertexBoneIndices.resize(header.vertexCount);
|
||||||
data.VertexBoneWeights.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)
|
for (uint32_t boneIndex{0}; boneIndex < bones.size(); ++boneIndex)
|
||||||
{
|
{
|
||||||
auto const& bone = bones[boneIndex];
|
auto const& bone = bones[boneIndex];
|
||||||
|
@ -263,6 +266,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
boneIndices[j] = boneIndex;
|
boneIndices[j] = boneIndex;
|
||||||
boneWeight[j] = weight.weight;
|
boneWeight[j] = weight.weight;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,40 +37,50 @@ namespace SHADE
|
||||||
/* SHBatch - Constructors/Destructors */
|
/* SHBatch - Constructors/Destructors */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
SHBatch::SHBatch(Handle<SHVkPipeline> pipeline)
|
SHBatch::SHBatch(Handle<SHVkPipeline> pipeline)
|
||||||
: pipeline{ pipeline }
|
: pipeline{ pipeline }
|
||||||
{
|
{
|
||||||
if (!pipeline)
|
if (!pipeline)
|
||||||
throw std::invalid_argument("Attempted to create a SHBatch with an invalid SHPipeline!");
|
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
|
// Mark all as dirty
|
||||||
setAllDirtyFlags();
|
setAllDirtyFlags();
|
||||||
}
|
}
|
||||||
|
|
||||||
SHBatch::SHBatch(SHBatch&& rhs)
|
SHBatch::SHBatch(SHBatch&& rhs)
|
||||||
: device { rhs.device }
|
: device { rhs.device }
|
||||||
, pipeline { rhs.pipeline }
|
, isAnimated { rhs.isAnimated }
|
||||||
, referencedMatInstances { std::move(rhs.referencedMatInstances) }
|
, pipeline { rhs.pipeline }
|
||||||
, matBufferDirty { std::move(rhs.matBufferDirty) }
|
, referencedMatInstances { std::move(rhs.referencedMatInstances) }
|
||||||
, subBatches { std::move(rhs.subBatches) }
|
, matBufferDirty { std::move(rhs.matBufferDirty) }
|
||||||
, isDirty { std::move(rhs.isDirty) }
|
, subBatches { std::move(rhs.subBatches) }
|
||||||
, drawData { std::move(rhs.drawData) }
|
, isDirty { std::move(rhs.isDirty) }
|
||||||
, transformData { std::move(rhs.transformData) }
|
, drawData { std::move(rhs.drawData) }
|
||||||
, instancedIntegerData { std::move(rhs.instancedIntegerData) }
|
, transformData { std::move(rhs.transformData) }
|
||||||
, matPropsData { std::move(rhs.matPropsData) }
|
, instancedIntegerData { std::move(rhs.instancedIntegerData) }
|
||||||
, matPropsDataSize { rhs.matPropsDataSize }
|
, matPropsData { std::move(rhs.matPropsData) }
|
||||||
, singleMatPropAlignedSize { rhs.singleMatPropAlignedSize }
|
, matPropsDataSize { rhs.matPropsDataSize }
|
||||||
, singleMatPropSize { rhs.singleMatPropSize }
|
, singleMatPropAlignedSize { rhs.singleMatPropAlignedSize }
|
||||||
, isCPUBuffersDirty { rhs.isCPUBuffersDirty }
|
, singleMatPropSize { rhs.singleMatPropSize }
|
||||||
, drawDataBuffer { rhs.drawDataBuffer }
|
, boneMatrixData { std::move(rhs.boneMatrixData) }
|
||||||
, transformDataBuffer { rhs.transformDataBuffer }
|
, boneMatrixIndices { std::move(rhs.boneMatrixIndices) }
|
||||||
, instancedIntegerBuffer { rhs.instancedIntegerBuffer }
|
, isCPUBuffersDirty { rhs.isCPUBuffersDirty }
|
||||||
, matPropsBuffer { rhs.matPropsBuffer }
|
, drawDataBuffer { rhs.drawDataBuffer }
|
||||||
, instanceDataDescSet { rhs.instanceDataDescSet }
|
, transformDataBuffer { rhs.transformDataBuffer }
|
||||||
|
, instancedIntegerBuffer { rhs.instancedIntegerBuffer }
|
||||||
|
, matPropsBuffer { rhs.matPropsBuffer }
|
||||||
|
, boneMatrixBuffer { rhs.boneMatrixBuffer }
|
||||||
|
, boneMatrixFirstIndexBuffer { rhs.boneMatrixFirstIndexBuffer }
|
||||||
|
, instanceDataDescSet { rhs.instanceDataDescSet }
|
||||||
{
|
{
|
||||||
rhs.drawDataBuffer = {};
|
rhs.drawDataBuffer = {};
|
||||||
rhs.transformDataBuffer = {};
|
rhs.transformDataBuffer = {};
|
||||||
rhs.instancedIntegerBuffer = {};
|
rhs.instancedIntegerBuffer = {};
|
||||||
rhs.matPropsBuffer = {};
|
rhs.matPropsBuffer = {};
|
||||||
|
rhs.boneMatrixBuffer = {};
|
||||||
|
rhs.boneMatrixFirstIndexBuffer = {};
|
||||||
rhs.instanceDataDescSet = {};
|
rhs.instanceDataDescSet = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,31 +89,38 @@ namespace SHADE
|
||||||
if (this == &rhs)
|
if (this == &rhs)
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
device = rhs.device ;
|
device = rhs.device ;
|
||||||
pipeline = rhs.pipeline ;
|
isAnimated = rhs.isAnimated ;
|
||||||
referencedMatInstances = std::move(rhs.referencedMatInstances);
|
pipeline = rhs.pipeline ;
|
||||||
matBufferDirty = std::move(rhs.matBufferDirty) ;
|
referencedMatInstances = std::move(rhs.referencedMatInstances);
|
||||||
subBatches = std::move(rhs.subBatches) ;
|
matBufferDirty = std::move(rhs.matBufferDirty) ;
|
||||||
isDirty = std::move(rhs.isDirty) ;
|
subBatches = std::move(rhs.subBatches) ;
|
||||||
drawData = std::move(rhs.drawData) ;
|
isDirty = std::move(rhs.isDirty) ;
|
||||||
transformData = std::move(rhs.transformData) ;
|
drawData = std::move(rhs.drawData) ;
|
||||||
instancedIntegerData = std::move(rhs.instancedIntegerData) ;
|
transformData = std::move(rhs.transformData) ;
|
||||||
matPropsData = std::move(rhs.matPropsData) ;
|
instancedIntegerData = std::move(rhs.instancedIntegerData) ;
|
||||||
matPropsDataSize = rhs.matPropsDataSize ;
|
matPropsData = std::move(rhs.matPropsData) ;
|
||||||
singleMatPropAlignedSize = rhs.singleMatPropAlignedSize ;
|
matPropsDataSize = rhs.matPropsDataSize ;
|
||||||
singleMatPropSize = rhs.singleMatPropSize ;
|
singleMatPropAlignedSize = rhs.singleMatPropAlignedSize ;
|
||||||
isCPUBuffersDirty = rhs.isCPUBuffersDirty ;
|
singleMatPropSize = rhs.singleMatPropSize ;
|
||||||
drawDataBuffer = rhs.drawDataBuffer ;
|
boneMatrixData = std::move(rhs.boneMatrixData) ;
|
||||||
transformDataBuffer = rhs.transformDataBuffer ;
|
boneMatrixIndices = std::move(rhs.boneMatrixIndices) ;
|
||||||
instancedIntegerBuffer = rhs.instancedIntegerBuffer ;
|
isCPUBuffersDirty = rhs.isCPUBuffersDirty ;
|
||||||
matPropsBuffer = rhs.matPropsBuffer ;
|
drawDataBuffer = rhs.drawDataBuffer ;
|
||||||
instanceDataDescSet = rhs.instanceDataDescSet ;
|
transformDataBuffer = rhs.transformDataBuffer ;
|
||||||
|
instancedIntegerBuffer = rhs.instancedIntegerBuffer ;
|
||||||
|
matPropsBuffer = rhs.matPropsBuffer ;
|
||||||
|
boneMatrixBuffer = rhs.boneMatrixBuffer ;
|
||||||
|
boneMatrixFirstIndexBuffer = rhs.boneMatrixFirstIndexBuffer ;
|
||||||
|
instanceDataDescSet = rhs.instanceDataDescSet ;
|
||||||
|
|
||||||
// Unset values
|
// Unset values
|
||||||
rhs.drawDataBuffer = {};
|
rhs.drawDataBuffer = {};
|
||||||
rhs.transformDataBuffer = {};
|
rhs.transformDataBuffer = {};
|
||||||
rhs.instancedIntegerBuffer = {};
|
rhs.instancedIntegerBuffer = {};
|
||||||
rhs.matPropsBuffer = {};
|
rhs.matPropsBuffer = {};
|
||||||
|
rhs.boneMatrixBuffer = {};
|
||||||
|
rhs.boneMatrixFirstIndexBuffer = {};
|
||||||
rhs.instanceDataDescSet = {};
|
rhs.instanceDataDescSet = {};
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -363,25 +380,27 @@ namespace SHADE
|
||||||
|
|
||||||
// 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)
|
||||||
|
{
|
||||||
|
auto* renderable = SHComponentManager::GetComponent<SHRenderable>(rendId);
|
||||||
|
instancedIntegerData.emplace_back(SHInstancedIntegerData
|
||||||
{
|
{
|
||||||
auto* renderable = SHComponentManager::GetComponent<SHRenderable>(rendId);
|
rendId,
|
||||||
instancedIntegerData.emplace_back(SHInstancedIntegerData
|
renderable->GetLightLayer()
|
||||||
{
|
});
|
||||||
rendId,
|
}
|
||||||
renderable->GetLightLayer()
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transfer to GPU
|
// Transfer to GPU
|
||||||
if (instancedIntegerBuffer[frameIndex] && !drawData.empty())
|
if (instancedIntegerBuffer[frameIndex] && !drawData.empty())
|
||||||
instancedIntegerBuffer[frameIndex]->WriteToMemory(instancedIntegerData.data(), static_cast<uint32_t>(instancedIntegerData.size() * sizeof(SHInstancedIntegerData)), 0, 0);
|
instancedIntegerBuffer[frameIndex]->WriteToMemory(instancedIntegerData.data(), static_cast<uint32_t>(instancedIntegerData.size() * sizeof(SHInstancedIntegerData)), 0, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
@ -392,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)
|
||||||
|
@ -402,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
|
||||||
|
@ -446,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),
|
||||||
|
@ -469,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;
|
||||||
|
@ -548,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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -590,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
|
||||||
|
@ -625,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);
|
||||||
}
|
}
|
||||||
|
@ -633,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);
|
||||||
}
|
}
|
||||||
|
@ -706,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])
|
||||||
|
@ -756,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));
|
||||||
|
@ -786,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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,6 +97,7 @@ namespace SHADE
|
||||||
bool IsEmpty() const noexcept { return subBatches.empty(); }
|
bool IsEmpty() const noexcept { return subBatches.empty(); }
|
||||||
Handle<SHVkBuffer> GetTransformBuffer(uint32_t frameIndex) const noexcept;
|
Handle<SHVkBuffer> GetTransformBuffer(uint32_t frameIndex) const noexcept;
|
||||||
Handle<SHVkBuffer> GetMDIBuffer(uint32_t frameIndex) const noexcept;
|
Handle<SHVkBuffer> GetMDIBuffer(uint32_t frameIndex) const noexcept;
|
||||||
|
bool IsAnimated() const noexcept { return isAnimated; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -111,6 +112,8 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
// Resources
|
// Resources
|
||||||
Handle<SHVkLogicalDevice> device;
|
Handle<SHVkLogicalDevice> device;
|
||||||
|
// Config
|
||||||
|
bool isAnimated; // Whether the material supports animation
|
||||||
// Batch Properties
|
// Batch Properties
|
||||||
Handle<SHVkPipeline> pipeline;
|
Handle<SHVkPipeline> pipeline;
|
||||||
std::unordered_set<Handle<SHMaterialInstance>> referencedMatInstances;
|
std::unordered_set<Handle<SHMaterialInstance>> referencedMatInstances;
|
||||||
|
@ -126,7 +129,7 @@ namespace SHADE
|
||||||
Byte matPropsDataSize = 0;
|
Byte matPropsDataSize = 0;
|
||||||
Byte singleMatPropAlignedSize = 0;
|
Byte singleMatPropAlignedSize = 0;
|
||||||
Byte singleMatPropSize = 0;
|
Byte singleMatPropSize = 0;
|
||||||
std::vector<SHMatrix> boneMatrixData;
|
std::vector<SHMatrix> boneMatrixData; // 0th element is always an identity matrix
|
||||||
std::vector<uint32_t> boneMatrixIndices;
|
std::vector<uint32_t> boneMatrixIndices;
|
||||||
bool isCPUBuffersDirty = true;
|
bool isCPUBuffersDirty = true;
|
||||||
// GPU Buffers
|
// GPU Buffers
|
||||||
|
@ -143,5 +146,6 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
void setAllDirtyFlags();
|
void setAllDirtyFlags();
|
||||||
void rebuildDescriptorSetBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
|
void rebuildDescriptorSetBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
|
||||||
|
static bool checkIfIsAnimatedPipeline(Handle<SHVkPipeline> pipeline);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue