#pragma once enum ATTRIBUTE_TYPE { POSITION, NORMAL, UV_0, MAX_ATTRIBUTE, }; struct material; class Mesh { struct submesh_info { uint32_t vertex_offset; uint32_t index_offset; size_t element_count; material& material; }; public: struct mesh_instance { const Mesh& mesh; // transform a transform matrice for the instance }; struct attribute { const uint8_t* data = nullptr; size_t length = 0; }; struct submesh { attribute indices; std::array attributes; u32 vertex_count = 0; u32 index_count = 0; // material& material; }; Mesh() = default; [[nodiscard]] mesh_instance instantiate () const; void add_submesh(const submesh& submesh, material& material); static inline uint32_t attribute_components(enum ATTRIBUTE_TYPE attribute_type) { switch(attribute_type) { case ATTRIBUTE_TYPE::POSITION: case ATTRIBUTE_TYPE::NORMAL: return 3; case ATTRIBUTE_TYPE::UV_0: return 2; default: return 0; } } static inline size_t attribute_size(enum ATTRIBUTE_TYPE attribute_type) { return sizeof(float) * attribute_components(attribute_type); } [[nodiscard]] inline uint32_t triangle_count() const { return index_count / 3; }; [[nodiscard]] inline uint32_t vertices_count() const { return vertex_count; }; [[nodiscard]] inline const std::vector& get_submeshes() const { return submeshes; }; [[nodiscard]] inline const std::vector& get_attribute(enum ATTRIBUTE_TYPE attribute_type) const { return attributes[(uint32_t)attribute_type]; }; [[nodiscard]] inline const std::vector& get_indices() const { return indices; } static void register_mesh(const Mesh& mesh); private: uint32_t vertex_count; uint32_t index_count; std::array, ATTRIBUTE_TYPE::MAX_ATTRIBUTE> attributes; std::vector indices; std::vector submeshes; struct gpu_mesh { std::array, ATTRIBUTE_TYPE::MAX_ATTRIBUTE> attributes; const device_buffer& indices; const device_buffer& submeshes; }; // allocate gpu mesh upon instanciation // static std::vector gpu_meshes; // static std::vector instances; };