// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com) // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp #include #include #include #include #include #include #include #include #include namespace Nz { SkeletonInstance::SkeletonInstance(std::shared_ptr skeleton) : m_skeleton(std::move(skeleton)), m_dataInvalided(true) { NazaraAssert(m_skeleton, "invalid skeleton"); PredefinedSkeletalData skeletalUboOffsets = PredefinedSkeletalData::GetOffsets(); m_skeletalDataBuffer = Graphics::Instance()->GetRenderDevice()->InstantiateBuffer(BufferType::Uniform, skeletalUboOffsets.totalSize, BufferUsage::DeviceLocal | BufferUsage::Dynamic | BufferUsage::Write); m_skeletalDataBuffer->UpdateDebugName("Skeletal data"); m_onSkeletonJointsInvalidated.Connect(m_skeleton->OnSkeletonJointsInvalidated, [this](const Skeleton*) { m_dataInvalided = true; OnTransferRequired(this); }); } SkeletonInstance::SkeletonInstance(SkeletonInstance&& skeletonInstance) noexcept : m_skeletalDataBuffer(std::move(skeletonInstance.m_skeletalDataBuffer)), m_skeleton(std::move(skeletonInstance.m_skeleton)), m_dataInvalided(skeletonInstance.m_dataInvalided) { m_onSkeletonJointsInvalidated.Connect(m_skeleton->OnSkeletonJointsInvalidated, [this](const Skeleton*) { m_dataInvalided = true; OnTransferRequired(this); }); } void SkeletonInstance::OnTransfer(RenderFrame& renderFrame, CommandBufferBuilder& builder) { if (!m_dataInvalided) return; PredefinedSkeletalData skeletalUboOffsets = PredefinedSkeletalData::GetOffsets(); auto& allocation = renderFrame.GetUploadPool().Allocate(m_skeletalDataBuffer->GetSize()); Matrix4f* matrices = AccessByOffset(allocation.mappedPtr, skeletalUboOffsets.jointMatricesOffset); for (std::size_t i = 0; i < m_skeleton->GetJointCount(); ++i) matrices[i] = m_skeleton->GetJoint(i)->GetSkinningMatrix(); builder.CopyBuffer(allocation, m_skeletalDataBuffer.get()); m_dataInvalided = false; } SkeletonInstance& SkeletonInstance::operator=(SkeletonInstance&& skeletonInstance) noexcept { m_skeletalDataBuffer = std::move(skeletonInstance.m_skeletalDataBuffer); m_skeleton = std::move(skeletonInstance.m_skeleton); m_dataInvalided = skeletonInstance.m_dataInvalided; m_onSkeletonJointsInvalidated.Connect(m_skeleton->OnSkeletonJointsInvalidated, [this](const Skeleton*) { m_dataInvalided = true; OnTransferRequired(this); }); return *this; } }