summary refs log tree commit diff
path: root/src/GFX/Util/MeshBuilder.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/GFX/Util/MeshBuilder.hpp')
-rw-r--r--src/GFX/Util/MeshBuilder.hpp65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/GFX/Util/MeshBuilder.hpp b/src/GFX/Util/MeshBuilder.hpp
new file mode 100644
index 0000000..e3caa8c
--- /dev/null
+++ b/src/GFX/Util/MeshBuilder.hpp
@@ -0,0 +1,65 @@
+#pragma once
+
+#include "../../Common/Sizes.hpp"
+#include "../../Math/Common.hpp"
+#include <vector>
+
+namespace MC::GFX::Util {
+
+template <typename... Attributes>
+class MeshBuilder {
+    using AttributeTuple = std::tuple<std::vector<Attributes>...>;
+
+    template <int N, typename AttributeContainer>
+    using EnableIfCorrectAttributeIndex =
+        std::enable_if_t<std::is_same_v<
+            typename std::tuple_element_t<N, AttributeTuple>::value_type,
+            typename AttributeContainer::value_type>, Bool>;
+
+    template <int N, typename A>
+    std::vector<A>& get() {
+        return std::get<N>(m_attributes);
+    }
+
+    template <USize... Sequence>
+    Mesh mesh(std::index_sequence<Sequence...>) {
+        return {
+            {m_positions, std::get<Sequence>(m_attributes)...},
+            m_indices,
+        };
+    }
+
+    std::vector<Vector<3, F32>> m_positions{};
+    std::vector<U32> m_indices{};
+    AttributeTuple m_attributes;
+public:
+    static constexpr UInt AttributesN = sizeof...(Attributes);
+
+    MeshBuilder() = default;
+
+    template<int N, typename AC, EnableIfCorrectAttributeIndex<N, AC> = true>
+    void attributes(const AC& from) {
+        auto& attribute_list = get<N, typename AC::value_type>();
+        attribute_list.insert(attribute_list.end(), from.begin(), from.end());
+    }
+
+    template<typename AC>
+    void positions(const AC& from) {
+        m_positions.insert(m_positions.end(), from.begin(), from.end());
+    }
+
+    template<typename AC>
+    void indices(const AC& from) {
+        m_indices.insert(m_indices.end(), from.begin(), from.end());
+    }
+
+    Mesh mesh() {
+        return mesh(std::make_index_sequence<AttributesN>{});
+    }
+
+    USize vertex_count() const {
+        return m_positions.size();
+    }
+};
+
+}