Graphics/RenderSystem: Fix skeleton not being used when added after graphics component

This commit is contained in:
SirLynix 2023-08-06 10:14:01 +02:00
parent ee361fc48c
commit fd73d62adf
4 changed files with 36 additions and 1 deletions

View File

@ -71,6 +71,7 @@ namespace Nz
void UpdateLightRenderMask(std::size_t lightIndex, UInt32 renderMask) override;
void UpdateRenderableRenderMask(std::size_t renderableIndex, UInt32 renderMask) override;
void UpdateRenderableScissorBox(std::size_t renderableIndex, const Recti& scissorBox) override;
void UpdateRenderableSkeletonInstance(std::size_t renderableIndex, std::size_t skeletonIndex) override;
void UpdateViewerRenderMask(std::size_t viewerIndex, Int32 renderOrder) override;
ForwardFramePipeline& operator=(const ForwardFramePipeline&) = delete;

View File

@ -63,6 +63,7 @@ namespace Nz
virtual void UpdateLightRenderMask(std::size_t lightIndex, UInt32 renderMask) = 0;
virtual void UpdateRenderableRenderMask(std::size_t renderableIndex, UInt32 renderMask) = 0;
virtual void UpdateRenderableScissorBox(std::size_t renderableIndex, const Recti& scissorBox) = 0;
virtual void UpdateRenderableSkeletonInstance(std::size_t renderableIndex, std::size_t skeletonIndex) = 0;
virtual void UpdateViewerRenderMask(std::size_t viewerIndex, Int32 renderOrder) = 0;
FramePipeline& operator=(const FramePipeline&) = delete;

View File

@ -559,6 +559,26 @@ namespace Nz
}
}
void ForwardFramePipeline::UpdateRenderableSkeletonInstance(std::size_t renderableIndex, std::size_t skeletonIndex)
{
RenderableData* renderableData = m_renderablePool.RetrieveFromIndex(renderableIndex);
renderableData->skeletonInstanceIndex = skeletonIndex;
// TODO: Invalidate only relevant viewers and passes
for (auto& viewerData : m_viewerPool)
{
UInt32 viewerRenderMask = viewerData.viewer->GetRenderMask();
if (viewerRenderMask & renderableData->renderMask)
{
if (viewerData.depthPrepass)
viewerData.depthPrepass->InvalidateElements();
viewerData.forwardPass->InvalidateElements();
}
}
}
void ForwardFramePipeline::UpdateViewerRenderMask(std::size_t viewerIndex, Int32 renderOrder)
{
ViewerData* viewerData = m_viewerPool.RetrieveFromIndex(viewerIndex);

View File

@ -351,7 +351,7 @@ namespace Nz
GraphicsEntity* graphicsEntity = m_graphicsEntityPool.Allocate(poolIndex);
graphicsEntity->entity = entity;
graphicsEntity->poolIndex = poolIndex;
graphicsEntity->renderableIndices.fill(std::numeric_limits<std::size_t>::max());
graphicsEntity->renderableIndices.fill(NoInstance);
graphicsEntity->skeletonInstanceIndex = NoInstance; //< will be set in skeleton observer
graphicsEntity->worldInstanceIndex = m_pipeline->RegisterWorldInstance(entityGfx.GetWorldInstance());
graphicsEntity->onNodeInvalidation.Connect(entityNode.OnNodeInvalidation, [this, graphicsEntity](const Node* /*node*/)
@ -374,6 +374,7 @@ namespace Nz
return;
m_pipeline->UnregisterRenderable(graphicsEntity->renderableIndices[renderableIndex]);
graphicsEntity->renderableIndices[renderableIndex] = NoInstance;
});
graphicsEntity->onScissorBoxUpdate.Connect(entityGfx.OnScissorBoxUpdate, [this, graphicsEntity](GraphicsComponent* gfx, const Recti& scissorBox)
@ -474,6 +475,12 @@ namespace Nz
it->second.useCount++;
graphicsEntity->skeletonInstanceIndex = it->second.skeletonInstanceIndex;
}
for (std::size_t renderableIndex : graphicsEntity->renderableIndices)
{
if (renderableIndex != NoInstance)
m_pipeline->UpdateRenderableSkeletonInstance(renderableIndex, graphicsEntity->skeletonInstanceIndex);
}
});
m_skeletonConstructObserver.each([&](entt::entity entity)
@ -484,6 +491,12 @@ namespace Nz
const std::shared_ptr<Skeleton>& skeleton = skeletonComponent.GetSkeleton();
graphicsEntity->skeletonInstanceIndex = m_pipeline->RegisterSkeleton(std::make_shared<SkeletonInstance>(skeleton));
for (std::size_t renderableIndex : graphicsEntity->renderableIndices)
{
if (renderableIndex != NoInstance)
m_pipeline->UpdateRenderableSkeletonInstance(renderableIndex, graphicsEntity->skeletonInstanceIndex);
}
});
}
}