summary refs log tree commit diff
path: root/src/GFX/Util
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2023-07-11 04:13:18 +0200
committerMel <einebeere@gmail.com>2023-07-11 04:13:18 +0200
commite6812d2df6bd8a0a71375096abe46f8039d8c570 (patch)
tree8fd1bb578f5a6e2edfc1b1dfffea32f9285c17c9 /src/GFX/Util
parent2c3ac8db3f539459166c801e61c5efdacf9150c3 (diff)
downloadmeowcraft-e6812d2df6bd8a0a71375096abe46f8039d8c570.tar.zst
meowcraft-e6812d2df6bd8a0a71375096abe46f8039d8c570.zip
Create MeshBuilder utility for comfy mesh building
Diffstat (limited to 'src/GFX/Util')
-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();
+    }
+};
+
+}