// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "raf/BaseImpl.h" #include "raf/RegionAffiliationReader.h" #include "raf/TypeDefs.h" #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable : 4365 4987) #endif #include #include #include #include #include #ifdef _MSC_VER #pragma warning(pop) #endif namespace raf { template typename std::enable_if::value>::type ensureHasSize(TContainer& target, std::size_t size) { target.reserve(size); while (target.size() < size) { target.push_back(typename TContainer::value_type(target.get_allocator().getMemoryResource())); } } template typename std::enable_if::value>::type ensureHasSize(TContainer& target, std::size_t size) { if (target.size() < size) { target.resize(size); } } template typename std::enable_if::value, typename TContainer::value_type&>::type getAt(TContainer& target, U index) { ensureHasSize(target, index + 1ul); return target[index]; } template typename std::enable_if::value>::type setAt(TContainer& target, TSize index, const TValue& value) { getAt(target, index) = value; } template class WriterImpl : public TWriterBase, public virtual BaseImpl { public: using WriterInterface = TWriterBase; public: explicit WriterImpl(MemoryResource* memRes_); // JointRegionAffiliationWriter methods void setJointRegionIndices(std::uint16_t jointIndex, const std::uint16_t* regionIndices, std::uint16_t count) override; void setJointRegionAffiliation(std::uint16_t jointIndex, const float* regionAffiliationValues, std::uint16_t count) override; void clearJointAffiliations() override; void deleteJointAffiliation(std::uint16_t jointIndex) override; // VertexRegionAffiliationWriter methods void setVertexRegionIndices(std::uint16_t meshIndex, std::uint32_t vertexIndex, const std::uint16_t* regionIndices, std::uint16_t count) override; void setVertexRegionAffiliation(std::uint16_t meshIndex, std::uint32_t vertexIndex, const float* regionAffiliationValues, std::uint16_t count) override; void clearVertexAffiliations() override; void clearVertexAffiliations(std::uint16_t meshIndex) override; void deleteVertexAffiliation(std::uint16_t meshIndex, std::uint32_t vertexIndex) override; // RegionAffiliationWriter methods void clearRegionNames() override; void setRegionName(std::uint16_t regionIndex, const char* regionName) override; void setFrom(const RegionAffiliationReader* source) override; }; #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable : 4589) #endif template WriterImpl::WriterImpl(MemoryResource* memRes_) : BaseImpl{memRes_} { } #ifdef _MSC_VER #pragma warning(pop) #endif #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable : 4505) #endif template inline void WriterImpl::setJointRegionIndices(std::uint16_t jointIndex, const std::uint16_t* regionIndices, std::uint16_t count) { auto& jointRegion = getAt(regionAffiliation.jointRegions, jointIndex); jointRegion.regionIndices.assign(regionIndices, regionIndices + count); } template inline void WriterImpl::setJointRegionAffiliation(std::uint16_t jointIndex, const float* regionAffiliationValues, std::uint16_t count) { auto& jointRegion = getAt(regionAffiliation.jointRegions, jointIndex); jointRegion.values.assign(regionAffiliationValues, regionAffiliationValues + count); } template inline void WriterImpl::clearJointAffiliations() { regionAffiliation.jointRegions.clear(); } template inline void WriterImpl::deleteJointAffiliation(std::uint16_t jointIndex) { if (jointIndex < regionAffiliation.jointRegions.size()) { auto& joints = regionAffiliation.jointRegions; joints.erase(std::next(joints.begin(), jointIndex)); } } template inline void WriterImpl::setVertexRegionIndices(std::uint16_t meshIndex, std::uint32_t vertexIndex, const std::uint16_t* regionIndices, std::uint16_t count) { auto& mesh = getAt(regionAffiliation.vertexRegions, meshIndex); auto& vertex = getAt(mesh, vertexIndex); vertex.regionIndices.assign(regionIndices, regionIndices + count); } template inline void WriterImpl::setVertexRegionAffiliation(std::uint16_t meshIndex, std::uint32_t vertexIndex, const float* regionAffiliationValues, std::uint16_t count) { auto& mesh = getAt(regionAffiliation.vertexRegions, meshIndex); auto& vertex = getAt(mesh, vertexIndex); vertex.values.assign(regionAffiliationValues, regionAffiliationValues + count); } template inline void WriterImpl::clearVertexAffiliations() { regionAffiliation.vertexRegions.clear(); } template inline void WriterImpl::clearVertexAffiliations(std::uint16_t meshIndex) { if (meshIndex < regionAffiliation.vertexRegions.size()) { regionAffiliation.vertexRegions[meshIndex].clear(); } } template inline void WriterImpl::deleteVertexAffiliation(std::uint16_t meshIndex, std::uint32_t vertexIndex) { if (meshIndex < regionAffiliation.vertexRegions.size()) { auto& mesh = regionAffiliation.vertexRegions[meshIndex]; if (vertexIndex < mesh.size()) { mesh.erase(std::next(mesh.begin(), meshIndex)); } } } template inline void WriterImpl::clearRegionNames() { regionAffiliation.regionNames.clear(); } template inline void WriterImpl::setRegionName(std::uint16_t regionIndex, const char* regionName) { getAt(regionAffiliation.regionNames, regionIndex) = regionName; } template inline void WriterImpl::setFrom(const RegionAffiliationReader* source) { clearRegionNames(); for (std::uint16_t riPlusOne = source->getRegionCount(); riPlusOne > 0u; riPlusOne--) { const auto ri = static_cast(riPlusOne - 1u); setRegionName(ri, source->getRegionName(ri)); } clearJointAffiliations(); for (std::uint16_t jiPlusOne = source->getJointCount(); jiPlusOne > 0; jiPlusOne--) { const auto ji = static_cast(jiPlusOne - 1u); ConstArrayView values = source->getJointRegionAffiliation(ji); ConstArrayView indices = source->getJointRegionIndices(ji); setJointRegionAffiliation(ji, values.data(), static_cast(values.size())); setJointRegionIndices(ji, indices.data(), static_cast(indices.size())); } clearVertexAffiliations(); for (std::uint16_t miPlusOne = source->getMeshCount(); miPlusOne > 0; miPlusOne--) { const auto mi = static_cast(miPlusOne - 1u); for (std::uint32_t viPlusOne = source->getVertexCount(mi); viPlusOne > 0; viPlusOne--) { const auto vi = viPlusOne - 1u; ConstArrayView values = source->getVertexRegionAffiliation(mi, vi); ConstArrayView indices = source->getVertexRegionIndices(mi, vi); setVertexRegionAffiliation(mi, vi, values.data(), static_cast(values.size())); setVertexRegionIndices(mi, vi, indices.data(), static_cast(indices.size())); } } } #ifdef _MSC_VER #pragma warning(pop) #endif } // namespace raf