#pragma once #include "../../Common/Sizes.hpp" #include "../../Math/Common.hpp" #include "Primitives.hpp" #include namespace MC::GFX::Util { template class MeshBuilder { using AttributeTuple = std::tuple...>; template using EnableIfCorrectAttributeIndex = std::enable_if_t::value_type, typename AttributeContainer::value_type>, Bool>; template std::vector& get() { return std::get(m_attributes); } template Mesh mesh(std::index_sequence) { return { {m_positions, std::get(m_attributes)...}, m_indices, }; } std::vector> m_positions{}; std::vector m_indices{}; AttributeTuple m_attributes; public: static constexpr UInt AttributesN = sizeof...(Attributes); MeshBuilder() = default; template = true> void attributes(const AC& from) { auto& attribute_list = get(); attribute_list.insert(attribute_list.end(), from.begin(), from.end()); } template void positions(const AC& from) { m_positions.insert(m_positions.end(), from.begin(), from.end()); } template void indices(const AC& from) { m_indices.insert(m_indices.end(), from.begin(), from.end()); } template void primitive(const Primitives::Primitive& primitive) { decltype(primitive.indices) relativized_indices{}; for (Int i = 0; i < primitive.indices.size(); i++) { relativized_indices[i] = primitive.indices[i] + m_positions.size(); } positions(primitive.positions); attributes<0>(primitive.normals); indices(relativized_indices); } Mesh mesh() { return mesh(std::make_index_sequence{}); } USize vertex_count() const { return m_positions.size(); } }; }