tried making naming more uniform and implemented most of the opengl managers
This commit is contained in:
99
source/assets/data/material_data.ipp
Normal file
99
source/assets/data/material_data.ipp
Normal file
@@ -0,0 +1,99 @@
|
||||
#ifndef INCLUDE_DYNAMIC_MATERIAL_DATA_IMPLEMENTATION
|
||||
# error Never include this file directly include 'dynamic_material_buffer.hpp'
|
||||
#endif
|
||||
|
||||
|
||||
inline std::optional<assets::material_components::surface_properties>& assets::material_data::surface_properties()
|
||||
{
|
||||
return std::get<material_components::indices::surface_properties>(data);
|
||||
}
|
||||
inline std::optional<assets::material_components::transparency>& assets::material_data::transparency()
|
||||
{
|
||||
return std::get<material_components::indices::transparency>(data);
|
||||
}
|
||||
inline std::optional<assets::material_components::ambient_color_texture>& assets::material_data::ambient_color_texture_id()
|
||||
{
|
||||
return std::get<material_components::indices::ambient_color_texture>(data);
|
||||
}
|
||||
inline std::optional<assets::material_components::diffuse_color_texture>& assets::material_data::diffuse_color_texture_id()
|
||||
{
|
||||
return std::get<material_components::indices::diffuse_color_texture>(data);
|
||||
}
|
||||
inline std::optional<assets::material_components::specular_color_texture>& assets::material_data::specular_color_texture_id()
|
||||
{
|
||||
return std::get<material_components::indices::specular_color_texture>(data);
|
||||
}
|
||||
inline std::optional<assets::material_components::shininess_texture>& assets::material_data::shininess_texture_id()
|
||||
{
|
||||
return std::get<material_components::indices::shininess_texture>(data);
|
||||
}
|
||||
inline std::optional<assets::material_components::alpha_texture>& assets::material_data::alpha_texture_id()
|
||||
{
|
||||
return std::get<material_components::indices::alpha_texture>(data);
|
||||
}
|
||||
inline std::optional<assets::material_components::bump_texture>& assets::material_data::bump_texture_id()
|
||||
{
|
||||
return std::get<material_components::indices::bump_texture(data);
|
||||
}
|
||||
|
||||
inline const std::optional<assets::material_components::surface_properties>& assets::material_data::surface_properties() const
|
||||
{
|
||||
return std::get<material_components::indices::surface_properties>(data);
|
||||
}
|
||||
|
||||
inline const std::optional<assets::material_components::transparency>& assets::material_data::transparency() const
|
||||
{
|
||||
return std::get<material_components::indices::transparency>(data);
|
||||
}
|
||||
|
||||
inline const std::optional<assets::material_components::ambient_color_texture>& assets::material_data::ambient_color_texture_id() const
|
||||
{
|
||||
return std::get<material_components::indices::ambient_color_texture>(data);
|
||||
}
|
||||
|
||||
inline const std::optional<assets::material_components::diffuse_color_texture>& assets::material_data::diffuse_color_texture_id() const
|
||||
{
|
||||
return std::get<material_components::indices::diffuse_color_texture>(data);
|
||||
}
|
||||
|
||||
inline const std::optional<assets::material_components::specular_color_texture>& assets::material_data::specular_color_texture_id() const
|
||||
{
|
||||
return std::get<material_components::indices::specular_color_texture>(data);
|
||||
}
|
||||
|
||||
inline const std::optional<assets::material_components::shininess_texture>& assets::material_data::shininess_texture_id() const
|
||||
{
|
||||
return std::get<material_components::indices::shininess_texture>(data);
|
||||
}
|
||||
|
||||
inline const std::optional<assets::material_components::alpha_texture>& assets::material_data::alpha_texture_id() const
|
||||
{
|
||||
return std::get<material_components::indices::alpha_texture>(data);
|
||||
}
|
||||
|
||||
inline const std::optional<assets::material_components::bump_texture>& assets::material_data::bump_texture_id() const
|
||||
{
|
||||
return std::get<material_components::indices::bump_texture>(data);
|
||||
}
|
||||
|
||||
|
||||
inline assets::material_components::surface_properties& assets::material_data::initialized_surface_properties()
|
||||
{
|
||||
auto& surface_properties_opt = surface_properties();
|
||||
if (not surface_properties_opt)
|
||||
{
|
||||
surface_properties_opt = material_components::surface_properties{};
|
||||
}
|
||||
return *surface_properties_opt;
|
||||
}
|
||||
|
||||
inline void assets::material_data::clear()
|
||||
{
|
||||
std::apply(
|
||||
[](auto&... data_opt) {
|
||||
(data_opt.reset(), ...);
|
||||
},
|
||||
data
|
||||
);
|
||||
}
|
||||
|
||||
80
source/assets/data/mesh_data.ipp
Normal file
80
source/assets/data/mesh_data.ipp
Normal file
@@ -0,0 +1,80 @@
|
||||
#ifndef INCLUDE_DYNAMIC_MESH_DATA_IMPLEMENTATION
|
||||
# error Never include this file directly include 'dynamic_mesh_buffer.hpp'
|
||||
#endif
|
||||
|
||||
inline std::vector<assets::mesh_vertex_components::position>& assets::mesh_data::positions()
|
||||
{
|
||||
return std::get<mesh_vertex_components::indices::position>(vertices);
|
||||
}
|
||||
|
||||
inline std::vector<assets::mesh_vertex_components::normal>& assets::mesh_data::normals()
|
||||
{
|
||||
return std::get<mesh_vertex_components::indices::normal>(vertices);
|
||||
}
|
||||
|
||||
inline std::vector<assets::mesh_vertex_components::tex_coord>& assets::mesh_data::tex_coords()
|
||||
{
|
||||
return std::get<mesh_vertex_components::indices::tex_coord>(vertices);
|
||||
}
|
||||
|
||||
inline std::vector<assets::mesh_vertex_components::color>& assets::mesh_data::colors()
|
||||
{
|
||||
return std::get<mesh_vertex_components::indices::color>(vertices);
|
||||
}
|
||||
|
||||
inline std::vector<assets::mesh_vertex_components::reflectance>& assets::mesh_data::reflectances()
|
||||
{
|
||||
return std::get<mesh_vertex_components::indices::reflectance>(vertices);
|
||||
}
|
||||
|
||||
inline std::vector<assets::mesh_data::triangle_type>& assets::mesh_data::triangles()
|
||||
{
|
||||
return m_triangles;
|
||||
}
|
||||
|
||||
inline auto& assets::mesh_data::material_id()
|
||||
{
|
||||
return m_material_id;
|
||||
}
|
||||
|
||||
inline const std::vector<assets::mesh_vertex_components::position>& assets::mesh_data::positions() const
|
||||
{
|
||||
return std::get<mesh_vertex_components::indices::position>(vertices);
|
||||
}
|
||||
|
||||
inline const std::vector<assets::mesh_vertex_components::normal>& assets::mesh_data::normals() const
|
||||
{
|
||||
return std::get<mesh_vertex_components::indices::normal>(vertices);
|
||||
}
|
||||
|
||||
inline const std::vector<assets::mesh_vertex_components::tex_coord>& assets::mesh_data::tex_coords() const
|
||||
{
|
||||
return std::get<mesh_vertex_components::indices::tex_coord>(vertices);
|
||||
}
|
||||
|
||||
inline const std::vector<assets::mesh_vertex_components::color>& assets::mesh_data::colors() const
|
||||
{
|
||||
return std::get<mesh_vertex_components::indices::color>(vertices);
|
||||
}
|
||||
|
||||
inline const std::vector<assets::mesh_vertex_components::reflectance>& assets::mesh_data::reflectances() const
|
||||
{
|
||||
return std::get<mesh_vertex_components::indices::reflectance>(vertices);
|
||||
}
|
||||
|
||||
inline const std::vector<assets::mesh_data::triangle_type>& assets::mesh_data::triangles() const
|
||||
{
|
||||
return m_triangles;
|
||||
}
|
||||
|
||||
inline const auto& assets::mesh_data::material_id() const
|
||||
{
|
||||
return m_material_id;
|
||||
}
|
||||
|
||||
inline void assets::mesh_data::clear()
|
||||
{
|
||||
clear_vertices();
|
||||
m_triangles.clear();
|
||||
m_material_id = {};
|
||||
}
|
||||
49
source/assets/data/point_cloud_data.ipp
Normal file
49
source/assets/data/point_cloud_data.ipp
Normal file
@@ -0,0 +1,49 @@
|
||||
#ifndef INCLUDE_DYNAMIC_TEXTURE_DATA_IMPLEMENTATION
|
||||
# error Never include this file directly include 'dynamic_point_cloud_buffer.hpp'
|
||||
#endif
|
||||
#include "assets/components/point_cloud_vertex_components.hpp"
|
||||
|
||||
inline std::vector<assets::point_cloud_vertex_components::position>& assets::point_cloud_data::positions()
|
||||
{
|
||||
return std::get<point_cloud_vertex_components::indices::position>(vertices);
|
||||
}
|
||||
|
||||
inline std::vector<assets::point_cloud_vertex_components::normal>& assets::point_cloud_data::normals()
|
||||
{
|
||||
return std::get<point_cloud_vertex_components::indices::normal>(vertices);
|
||||
}
|
||||
|
||||
inline std::vector<assets::point_cloud_vertex_components::color>& assets::point_cloud_data::colors()
|
||||
{
|
||||
return std::get<point_cloud_vertex_components::indices::color>(vertices);
|
||||
}
|
||||
|
||||
inline std::vector<assets::point_cloud_vertex_components::reflectance>& assets::point_cloud_data::reflectances()
|
||||
{
|
||||
return std::get<point_cloud_vertex_components::indices::reflectance>(vertices);
|
||||
}
|
||||
|
||||
inline const std::vector<assets::point_cloud_vertex_components::position>& assets::point_cloud_data::positions() const
|
||||
{
|
||||
return std::get<point_cloud_vertex_components::indices::position>(vertices);
|
||||
}
|
||||
|
||||
inline const std::vector<assets::point_cloud_vertex_components::normal>& assets::point_cloud_data::normals() const
|
||||
{
|
||||
return std::get<point_cloud_vertex_components::indices::normal>(vertices);
|
||||
}
|
||||
|
||||
inline const std::vector<assets::point_cloud_vertex_components::color>& assets::point_cloud_data::colors() const
|
||||
{
|
||||
return std::get<point_cloud_vertex_components::indices::color>(vertices);
|
||||
}
|
||||
|
||||
inline const std::vector<assets::point_cloud_vertex_components::reflectance>& assets::point_cloud_data::reflectances() const
|
||||
{
|
||||
return std::get<point_cloud_vertex_components::indices::reflectance>(vertices);
|
||||
}
|
||||
|
||||
inline void assets::point_cloud_data::clear()
|
||||
{
|
||||
clear_vertices();
|
||||
}
|
||||
159
source/assets/data/texture_data.ipp
Normal file
159
source/assets/data/texture_data.ipp
Normal file
@@ -0,0 +1,159 @@
|
||||
#ifndef INCLUDE_DYNAMIC_TEXTURE_DATA_IMPLEMENTATION
|
||||
# error Never include this file directly include 'dynamic_texture_buffer.hpp'
|
||||
#endif
|
||||
|
||||
|
||||
inline assets::texture_data::texture_data(
|
||||
std::unique_ptr<value_type[]>&& data,
|
||||
const dim_type width,
|
||||
const dim_type height,
|
||||
const texture_components::flags components
|
||||
) :
|
||||
m_data{ std::move(data) },
|
||||
m_width{ width },
|
||||
m_height{ height },
|
||||
m_components{ components }
|
||||
{};
|
||||
|
||||
inline assets::texture_data::texture_data(const assets::texture_data& other) :
|
||||
m_data{ new value_type[other.component_count()] },
|
||||
m_width{ other.m_width },
|
||||
m_height{ other.m_height },
|
||||
m_components{ other.m_components }
|
||||
{
|
||||
std::copy_n(other.m_data.get(), other.m_width * other.m_height, this->m_data.get());
|
||||
}
|
||||
|
||||
inline assets::texture_data::texture_data(texture_data&& other) noexcept :
|
||||
m_data{ std::move(other.m_data) },
|
||||
m_width{ other.m_width },
|
||||
m_height{ other.m_height },
|
||||
m_components{ other.m_components }
|
||||
{
|
||||
other.m_width = 0;
|
||||
other.m_height = 0;
|
||||
other.m_components = texture_components::flags::none;
|
||||
}
|
||||
|
||||
inline assets::texture_data& assets::texture_data::operator=(const assets::texture_data& other)
|
||||
{
|
||||
if (this != &other) [[likely]]
|
||||
{
|
||||
|
||||
const auto m_size = this->component_count();
|
||||
const auto o_size = other.component_count();
|
||||
|
||||
if (o_size > m_size) {
|
||||
this->~texture_data();
|
||||
this->m_data.reset(new value_type[o_size]);
|
||||
}
|
||||
|
||||
std::copy_n(other.m_data.get(), o_size, this->m_data.get());
|
||||
|
||||
this->m_width = other.m_width;
|
||||
this->m_height = other.m_height;
|
||||
this->m_components = other.m_components;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline assets::texture_data& assets::texture_data::operator=(texture_data&& other) noexcept
|
||||
{
|
||||
if (this != &other) [[likely]]
|
||||
{
|
||||
this->~texture_data();
|
||||
|
||||
this->m_data = std::move(other.m_data);
|
||||
this->m_width = other.m_width;
|
||||
this->m_height = other.m_height;
|
||||
|
||||
other.m_width = 0;
|
||||
other.m_height = 0;
|
||||
other.m_components = texture_components::flags::none;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline assets::texture_components::flags assets::texture_data::components() const
|
||||
{
|
||||
return m_components;
|
||||
}
|
||||
|
||||
inline assets::texture_data::dim_type assets::texture_data::width() const
|
||||
{
|
||||
return m_width;
|
||||
}
|
||||
|
||||
inline assets::texture_data::dim_type assets::texture_data::height() const
|
||||
{
|
||||
return m_height;
|
||||
}
|
||||
|
||||
inline std::pair<assets::texture_data::dim_type, assets::texture_data::dim_type> assets::texture_data::dimensions() const
|
||||
{
|
||||
return { m_width, m_height };
|
||||
}
|
||||
|
||||
inline assets::texture_data::size_type assets::texture_data::pixel_count() const
|
||||
{
|
||||
return static_cast<size_type>(m_width) * static_cast<size_type>(m_height);
|
||||
}
|
||||
|
||||
inline assets::texture_data::size_type assets::texture_data::component_count() const
|
||||
{
|
||||
return std::popcount(static_cast<std::underlying_type_t<texture_components::flags>>(m_components));
|
||||
}
|
||||
|
||||
inline assets::texture_data::size_type assets::texture_data::size() const
|
||||
{
|
||||
return pixel_count() * component_count();
|
||||
}
|
||||
|
||||
inline assets::texture_data::const_pointer assets::texture_data::data() const
|
||||
{
|
||||
return m_data.get();
|
||||
}
|
||||
|
||||
inline assets::texture_data::pointer assets::texture_data::data()
|
||||
{
|
||||
return m_data.get();
|
||||
}
|
||||
|
||||
inline assets::texture_data::const_iterator assets::texture_data::begin() const
|
||||
{
|
||||
return data();
|
||||
}
|
||||
|
||||
inline assets::texture_data::iterator assets::texture_data::begin()
|
||||
{
|
||||
return data();
|
||||
}
|
||||
|
||||
inline assets::texture_data::const_iterator assets::texture_data::end() const
|
||||
{
|
||||
return begin() + component_count();
|
||||
}
|
||||
|
||||
inline assets::texture_data::iterator assets::texture_data::end()
|
||||
{
|
||||
return begin() + component_count();
|
||||
}
|
||||
|
||||
inline assets::texture_data::const_iterator assets::texture_data::cbegin() const
|
||||
{
|
||||
return const_cast<const_iterator>(begin());
|
||||
}
|
||||
|
||||
inline assets::texture_data::const_iterator assets::texture_data::cend() const
|
||||
{
|
||||
return const_cast<const_iterator>(begin());
|
||||
}
|
||||
|
||||
inline void assets::texture_data::clear()
|
||||
{
|
||||
m_data.reset();
|
||||
m_width = 0;
|
||||
m_height = 0;
|
||||
m_components = {};
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "util/for_each.hpp"
|
||||
|
||||
template<typename C, class... Loaders>
|
||||
base_dynamic_loader<C, Loaders...>::base_dynamic_loader(const C enabled_components) :
|
||||
assetsbase_dynamic_loader<C, Loaders...>::base_dynamic_loader(const C enabled_components) :
|
||||
m_enabled_components{ enabled_components }
|
||||
{
|
||||
[&]<std::size_t... Is>(std::index_sequence<Is...>) {
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "assets/dynamic_data_loaders/dynamic_mesh_loader.hpp"
|
||||
#include "assets/data_loaders/mesh_loader.hpp"
|
||||
|
||||
std::error_code dynamic_mesh_loader::prefetch(
|
||||
std::error_code assets::mesh_loader::prefetch(
|
||||
loader_id_type loader_id,
|
||||
const ztu::string_list& directories,
|
||||
prefetch_queue& queue
|
||||
@@ -17,10 +17,10 @@ std::error_code dynamic_mesh_loader::prefetch(
|
||||
);
|
||||
}
|
||||
|
||||
std::error_code dynamic_mesh_loader::load(
|
||||
std::error_code assets::mesh_loader::load(
|
||||
loader_id_type loader_id,
|
||||
const ztu::string_list& directories,
|
||||
dynamic_mesh_store& store,
|
||||
mesh_store& store,
|
||||
mesh_prefetch_lookup& id_lookup,
|
||||
const bool pedantic
|
||||
) {
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "assets/dynamic_data_loaders/dynamic_point_cloud_loader.hpp"
|
||||
#include "assets/data_loaders/point_cloud_loader.hpp"
|
||||
|
||||
std::error_code dynamic_point_cloud_loader::prefetch(
|
||||
std::error_code assets::point_cloud_loader::prefetch(
|
||||
const loader_id_type loader_id,
|
||||
const ztu::string_list& directories,
|
||||
prefetch_queue& queue
|
||||
@@ -17,10 +17,10 @@ std::error_code dynamic_point_cloud_loader::prefetch(
|
||||
);
|
||||
}
|
||||
|
||||
std::error_code dynamic_point_cloud_loader::load(
|
||||
std::error_code assets::point_cloud_loader::load(
|
||||
const loader_id_type loader_id,
|
||||
const ztu::string_list& directories,
|
||||
dynamic_point_cloud_store& store,
|
||||
point_cloud_store& store,
|
||||
point_cloud_prefetch_lookup& id_lookup,
|
||||
const bool pedantic
|
||||
) {
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "assets/dynamic_data_loaders/dynamic_texture_loader.hpp"
|
||||
#include "assets/data_loaders/texture_loader.hpp"
|
||||
|
||||
#if defined(__GNUC__) || defined(__GNUG__)
|
||||
#pragma GCC diagnostic push
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
#include "util/logger.hpp"
|
||||
|
||||
dynamic_texture_loader::dynamic_texture_loader(components::texture::flags enabled_components) :
|
||||
assets::texture_loader::texture_loader(assets::texture_components::flags enabled_components) :
|
||||
m_enabled_components{ enabled_components },
|
||||
m_loader_id_lookup{
|
||||
{ "jpg", loader_id_type{ 0 } },
|
||||
@@ -30,7 +30,7 @@ dynamic_texture_loader::dynamic_texture_loader(components::texture::flags enable
|
||||
{ "pic", loader_id_type{ 7 } }
|
||||
} {}
|
||||
|
||||
std::optional<dynamic_texture_loader::loader_id_type> dynamic_texture_loader::find_loader(const std::string_view& name)
|
||||
std::optional<assets::texture_loader::loader_id_type> assets::texture_loader::find_loader(const std::string_view& name)
|
||||
{
|
||||
const auto it = m_loader_id_lookup.find(name);
|
||||
|
||||
@@ -42,7 +42,7 @@ std::optional<dynamic_texture_loader::loader_id_type> dynamic_texture_loader::fi
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::error_code dynamic_texture_loader::prefetch(
|
||||
std::error_code assets::texture_loader::prefetch(
|
||||
const loader_id_type loader_id,
|
||||
const ztu::string_list& directories,
|
||||
prefetch_queue& queue
|
||||
@@ -51,10 +51,10 @@ std::error_code dynamic_texture_loader::prefetch(
|
||||
return {};
|
||||
}
|
||||
|
||||
std::error_code dynamic_texture_loader::load(
|
||||
const loader_id_type loader_id,
|
||||
std::error_code assets::texture_loader::load(
|
||||
const loader_id_type,
|
||||
const ztu::string_list& directories,
|
||||
dynamic_texture_store& store,
|
||||
texture_store& store,
|
||||
texture_prefetch_lookup& id_lookup,
|
||||
const bool pedantic
|
||||
) {
|
||||
@@ -85,7 +85,7 @@ std::error_code dynamic_texture_loader::load(
|
||||
|
||||
auto data = std::unique_ptr<std::uint8_t[]>(ptr);
|
||||
|
||||
using flags = components::texture::flags;
|
||||
using flags = texture_components::flags;
|
||||
|
||||
auto components = flags{};
|
||||
switch (channels)
|
||||
@@ -107,12 +107,13 @@ std::error_code dynamic_texture_loader::load(
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto id = store.add(dynamic_texture_buffer(
|
||||
const auto id = store.add(texture_data(
|
||||
std::move(data),
|
||||
width,
|
||||
height,
|
||||
components
|
||||
));
|
||||
|
||||
id_lookup.emplace_hint(id_it, filename, id);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#ifndef INCLUDE_GENERIC_DYNAMIC_STORE_IMPLEMENTATION
|
||||
# error Never include this file directly include 'basic_dynamic_store.hpp'
|
||||
#ifndef INCLUDE_GENERIC_BASIC_STORE_IMPLEMENTATION
|
||||
# error Never include this file directly include 'generic_basic_store.hpp'
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
template<typename T>
|
||||
typename generic_dynamic_store<T>::id_type generic_dynamic_store<T>::add(const T& data)
|
||||
typename generic_basic_store<T>::id_type generic_basic_store<T>::add(const T& data)
|
||||
{
|
||||
auto id = id_type{ m_next_data_id.index++ };
|
||||
m_data.emplace_back(data);
|
||||
@@ -14,9 +14,10 @@ typename generic_dynamic_store<T>::id_type generic_dynamic_store<T>::add(const T
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::pair<typename generic_dynamic_store<T>::iterator_type, bool> generic_dynamic_store<T>::find(id_type id)
|
||||
std::pair<typename generic_basic_store<T>::iterator_type, bool> generic_basic_store<T>::find(id_type id)
|
||||
{
|
||||
const auto it = std::ranges::upper_bound(m_ids, id);
|
||||
|
||||
const auto found = it != m_ids.begin() and *std::prev(it) == id;
|
||||
const auto index = it - m_ids.begin() - found;
|
||||
|
||||
@@ -24,9 +25,10 @@ std::pair<typename generic_dynamic_store<T>::iterator_type, bool> generic_dynami
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::pair<typename generic_dynamic_store<T>::const_iterator, bool> generic_dynamic_store<T>::find(id_type id) const
|
||||
std::pair<typename generic_basic_store<T>::const_iterator, bool> generic_basic_store<T>::find(id_type id) const
|
||||
{
|
||||
const auto it = std::ranges::upper_bound(m_ids, id);
|
||||
|
||||
const auto found = it != m_ids.begin() and *std::prev(it) == id;
|
||||
const auto index = it - m_ids.begin() - found;
|
||||
|
||||
@@ -34,7 +36,7 @@ std::pair<typename generic_dynamic_store<T>::const_iterator, bool> generic_dynam
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void generic_dynamic_store<T>::remove(iterator_type it)
|
||||
void generic_basic_store<T>::remove(iterator_type it)
|
||||
{
|
||||
const auto index = it - m_data.begin();
|
||||
m_data.erase(it);
|
||||
@@ -42,20 +44,20 @@ void generic_dynamic_store<T>::remove(iterator_type it)
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void generic_dynamic_store<T>::clear()
|
||||
void generic_basic_store<T>::clear()
|
||||
{
|
||||
m_data.clear();
|
||||
m_ids.clear();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::span<T> generic_dynamic_store<T>::data()
|
||||
std::span<T> generic_basic_store<T>::data()
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::span<const T> generic_dynamic_store<T>::data() const
|
||||
std::span<const T> generic_basic_store<T>::data() const
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
@@ -5,11 +5,13 @@
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
component_array_iterator<C, Ts...>::component_array_iterator(
|
||||
component_array_pointer_type components,
|
||||
id_array_pointer_type ids,
|
||||
const component_array_pointer_type& components,
|
||||
flag_count_pointer_type flags,
|
||||
std::size_t index,
|
||||
const offsets_type& offsets
|
||||
) :
|
||||
m_ids{ ids },
|
||||
m_components{ components },
|
||||
m_flag_counts{ flags },
|
||||
m_index{ index },
|
||||
@@ -67,14 +69,14 @@ template<typename C, typename... Ts>
|
||||
component_array_iterator<C, Ts...> component_array_iterator<C, Ts...>::operator+(const difference_type n) const
|
||||
{
|
||||
auto tmp = *this;
|
||||
return tmp += n;
|
||||
return tmp += n; // TODO clion says n is unused
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
component_array_iterator<C, Ts...> component_array_iterator<C, Ts...>::operator-(const difference_type n) const
|
||||
{
|
||||
auto tmp = *this;
|
||||
return tmp -= n;
|
||||
return tmp -= n; // TODO clion says n is unused
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
@@ -94,7 +96,7 @@ typename component_array_iterator<C, Ts...>::reference component_array_iterator<
|
||||
template<typename C, typename... Ts>
|
||||
bool component_array_iterator<C, Ts...>::operator==(const component_array_iterator& other) const
|
||||
{
|
||||
return m_components == other.m_components and m_index == other.m_index;
|
||||
return m_ids == other.m_ids and m_index == other.m_index;
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
@@ -148,10 +150,11 @@ void component_array_iterator<C, Ts...>::calc_offsets(std::index_sequence<Is...>
|
||||
|
||||
while (n--)
|
||||
{
|
||||
const auto& [ flags, count ] = m_flag_counts[m_index + n];
|
||||
const auto& [ flags, count ] = m_flag_counts[m_index];
|
||||
|
||||
([&] {
|
||||
if (is_component_enabled<Is>(flags)) {
|
||||
if (is_component_enabled<Is>(flags))
|
||||
{
|
||||
std::get<Is>(m_offsets) += step * count;
|
||||
}
|
||||
}(), ...);
|
||||
@@ -165,26 +168,24 @@ template<std::size_t... Is>
|
||||
typename component_array_iterator<C, Ts...>::reference
|
||||
component_array_iterator<C, Ts...>::dereference(std::index_sequence<Is...>) const
|
||||
{
|
||||
return std::make_tuple(get_span<Is>()...);
|
||||
const auto& [ flags, component_count ] = m_flag_counts[m_index];
|
||||
|
||||
return std::make_pair(
|
||||
m_ids[m_index],
|
||||
std::make_tuple(
|
||||
flags,
|
||||
std::make_tuple(
|
||||
std::span(
|
||||
&std::get<Is>(m_components)[m_offsets[Is]],
|
||||
is_component_enabled<Is>(flags) ? component_count : 0
|
||||
)...
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
template<std::size_t N>
|
||||
std::tuple_element_t<N, typename component_array_iterator<C, Ts...>::value_type>
|
||||
component_array_iterator<C, Ts...>::get_span() const
|
||||
{
|
||||
const auto& [ flags, count ] = m_flag_counts[m_index];
|
||||
|
||||
if (is_component_enabled<N>(flags))
|
||||
{
|
||||
return { &std::get<N>(m_components)[m_offsets[N]], count };
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
std::tuple<std::add_pointer_t<Ts>...> generic_dynamic_component_array_store<C, Ts...>::data_ptrs()
|
||||
std::tuple<std::add_pointer_t<Ts>...> generic_dynamic_component_array_store<C, Ts...>::component_array_ptrs()
|
||||
{
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
@@ -194,7 +195,7 @@ std::tuple<std::add_pointer_t<Ts>...> generic_dynamic_component_array_store<C, T
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> generic_dynamic_component_array_store<C, Ts...>::data_ptrs() const
|
||||
std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> generic_dynamic_component_array_store<C, Ts...>::component_array_ptrs() const
|
||||
{
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
@@ -204,7 +205,7 @@ std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> generic_dynamic_componen
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
std::array<std::size_t, sizeof...(Ts)> generic_dynamic_component_array_store<C, Ts...>::data_counts() const
|
||||
std::array<std::size_t, sizeof...(Ts)> generic_dynamic_component_array_store<C, Ts...>::array_counts() const
|
||||
{
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
@@ -219,21 +220,23 @@ typename generic_dynamic_component_array_store<C, Ts...>::id_type generic_dynami
|
||||
) {
|
||||
|
||||
auto component_flags = C{};
|
||||
auto count = count_type{};
|
||||
auto min_component_count = count_type{};
|
||||
|
||||
[&]<auto... Is>(std::integer_sequence<Is...>)
|
||||
{
|
||||
const auto& array = std::get<Is>(component_arrays);
|
||||
if (not array.empty())
|
||||
const auto& component_array = std::get<Is>(component_arrays);
|
||||
if (not component_array.empty())
|
||||
{
|
||||
const auto array_count = static_cast<count_type>(array.size());
|
||||
count = count ? std::min(array_count, count) : array_count;
|
||||
const auto component_count = static_cast<count_type>(component_array.size());
|
||||
if (min_component_count != 0 and component_count < min_component_count)
|
||||
{
|
||||
min_component_count = component_count;
|
||||
}
|
||||
component_flags |= C{ 1 } << Is;
|
||||
}
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
|
||||
|
||||
[&]<auto... Is>(std::integer_sequence<Is...>)
|
||||
{
|
||||
const auto& src_array = std::get<Is>(component_arrays);
|
||||
@@ -246,7 +249,7 @@ typename generic_dynamic_component_array_store<C, Ts...>::id_type generic_dynami
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
|
||||
m_component_flag_counts.emplace_back(component_flags, count);
|
||||
m_component_flag_counts.emplace_back(component_flags, min_component_count);
|
||||
|
||||
const auto id = id_type{ m_next_data_id.index++ };
|
||||
m_ids.push_back(id);
|
||||
@@ -323,7 +326,8 @@ template<typename C, typename... Ts>
|
||||
typename generic_dynamic_component_array_store<C, Ts...>::iterator_type generic_dynamic_component_array_store<C, Ts...>::begin()
|
||||
{
|
||||
return iterator_type{
|
||||
data_ptrs(),
|
||||
m_ids.data(),
|
||||
component_array_ptrs(),
|
||||
m_component_flag_counts.data(),
|
||||
0,
|
||||
{}
|
||||
@@ -334,10 +338,11 @@ template<typename C, typename... Ts>
|
||||
typename generic_dynamic_component_array_store<C, Ts...>::iterator_type generic_dynamic_component_array_store<C, Ts...>::end()
|
||||
{
|
||||
return iterator_type{
|
||||
data_ptrs(),
|
||||
m_ids.data(),
|
||||
component_array_ptrs(),
|
||||
m_component_flag_counts.data(),
|
||||
m_component_flag_counts.size(),
|
||||
data_counts()
|
||||
array_counts()
|
||||
};
|
||||
}
|
||||
|
||||
@@ -345,7 +350,8 @@ template<typename C, typename... Ts>
|
||||
typename generic_dynamic_component_array_store<C, Ts...>::const_iterator generic_dynamic_component_array_store<C, Ts...>::begin() const
|
||||
{
|
||||
return iterator_type{
|
||||
data_ptrs(),
|
||||
m_ids.data(),
|
||||
component_array_ptrs(),
|
||||
m_component_flag_counts.data(),
|
||||
0,
|
||||
{}
|
||||
@@ -356,10 +362,11 @@ template<typename C, typename... Ts>
|
||||
typename generic_dynamic_component_array_store<C, Ts...>::const_iterator generic_dynamic_component_array_store<C, Ts...>::end() const
|
||||
{
|
||||
return iterator_type{
|
||||
data_ptrs(),
|
||||
m_ids.data(),
|
||||
component_array_ptrs(),
|
||||
m_component_flag_counts.data(),
|
||||
m_component_flag_counts.size(),
|
||||
data_counts()
|
||||
array_counts()
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
# error Never include this file directly include 'generic_dynamic_indexed_component_array_store.hpp'
|
||||
#endif
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <span>
|
||||
@@ -13,12 +12,14 @@
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
indexed_component_array_iterator<C, I, Ts...>::indexed_component_array_iterator(
|
||||
id_array_pointer_type ids,
|
||||
const index_array_pointer_type indices,
|
||||
const component_array_pointer_type& components,
|
||||
const flag_count_pointer_type flag_counts,
|
||||
std::size_t index,
|
||||
const offsets_type& offsets
|
||||
) :
|
||||
m_ids{ ids },
|
||||
m_indices{ indices },
|
||||
m_components{ components },
|
||||
m_flag_counts{ flag_counts },
|
||||
@@ -77,14 +78,14 @@ template<typename C, typename I, typename... Ts>
|
||||
indexed_component_array_iterator<C, I, Ts...> indexed_component_array_iterator<C, I, Ts...>::operator+(const difference_type n) const
|
||||
{
|
||||
auto tmp = *this;
|
||||
return tmp += n;
|
||||
return tmp += n; // TODO clion says n is unused
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
indexed_component_array_iterator<C, I, Ts...> indexed_component_array_iterator<C, I, Ts...>::operator-(const difference_type n) const
|
||||
{
|
||||
auto tmp = *this;
|
||||
return tmp -= n;
|
||||
return tmp -= n; // TODO clion says n is unused
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
@@ -98,13 +99,13 @@ template<typename C, typename I, typename... Ts>
|
||||
typename indexed_component_array_iterator<C, I, Ts...>::reference indexed_component_array_iterator<C, I, Ts...>::operator[](
|
||||
const difference_type n
|
||||
) const {
|
||||
return *((*this) + n);
|
||||
return *(*this + n);
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
bool indexed_component_array_iterator<C, I, Ts...>::operator==(const indexed_component_array_iterator& other) const
|
||||
{
|
||||
return m_components == other.m_components and m_index == other.m_index;
|
||||
return m_ids == other.m_ids and m_index == other.m_index;
|
||||
}
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
@@ -160,12 +161,13 @@ void indexed_component_array_iterator<C, I, Ts...>::calc_offsets(
|
||||
|
||||
while (n--)
|
||||
{
|
||||
const auto& [ flags, index_count, component_count ] = m_flag_counts[m_index + n];
|
||||
const auto& [ flags, index_count, component_count ] = m_flag_counts[m_index];
|
||||
|
||||
std::get<0>(m_offsets) += step * index_count;
|
||||
|
||||
([&] {
|
||||
if (is_component_enabled<Is>(flags)) {
|
||||
if (is_component_enabled<Is>(flags))
|
||||
{
|
||||
std::get<1 + Is>(m_offsets) += step * component_count;
|
||||
}
|
||||
}(), ...);
|
||||
@@ -181,24 +183,24 @@ indexed_component_array_iterator<C, I, Ts...>::dereference(std::index_sequence<I
|
||||
{
|
||||
const auto& [ flags, index_count, component_count ] = m_flag_counts[m_index];
|
||||
|
||||
return std::make_tuple(
|
||||
std::span(
|
||||
m_indices[m_offsets[0]],
|
||||
index_count
|
||||
),
|
||||
std::span(
|
||||
(
|
||||
is_component_enabled<Is>(flags)
|
||||
? &std::get<Is>(m_components)[m_offsets[1 + Is]]
|
||||
: nullptr
|
||||
return std::make_pair(
|
||||
m_ids[m_index],
|
||||
std::make_tuple(
|
||||
flags,
|
||||
std::span(
|
||||
m_indices[m_offsets[0]],
|
||||
index_count
|
||||
),
|
||||
component_count
|
||||
)...
|
||||
std::make_tuple(
|
||||
std::span(
|
||||
&std::get<Is>(m_components)[m_offsets[1 + Is]],
|
||||
is_component_enabled<Is>(flags) ? component_count : 0
|
||||
)...
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename C, typename I, typename... Ts>
|
||||
std::tuple<std::add_pointer_t<Ts>...> generic_dynamic_indexed_component_array_store<C, I, Ts...>::component_array_ptrs()
|
||||
{
|
||||
@@ -350,6 +352,7 @@ template<typename C, typename I, typename... Ts>
|
||||
typename generic_dynamic_indexed_component_array_store<C, I,Ts...>::iterator_type generic_dynamic_indexed_component_array_store<C, I,Ts...>::begin()
|
||||
{
|
||||
return iterator_type{
|
||||
m_ids.data(),
|
||||
m_indices.data(),
|
||||
component_array_ptrs(),
|
||||
m_component_flag_counts.data(),
|
||||
@@ -362,6 +365,7 @@ template<typename C, typename I, typename... Ts>
|
||||
typename generic_dynamic_indexed_component_array_store<C, I,Ts...>::iterator_type generic_dynamic_indexed_component_array_store<C, I,Ts...>::end()
|
||||
{
|
||||
return iterator_type{
|
||||
m_ids.data(),
|
||||
m_indices.data(),
|
||||
component_array_ptrs(),
|
||||
m_component_flag_counts.data(),
|
||||
@@ -374,6 +378,7 @@ template<typename C, typename I, typename... Ts>
|
||||
typename generic_dynamic_indexed_component_array_store<C, I,Ts...>::const_iterator generic_dynamic_indexed_component_array_store<C, I,Ts...>::begin() const
|
||||
{
|
||||
return iterator_type{
|
||||
m_ids.data(),
|
||||
m_indices.data(),
|
||||
component_array_ptrs(),
|
||||
m_component_flag_counts.data(),
|
||||
@@ -386,6 +391,7 @@ template<typename C, typename I, typename... Ts>
|
||||
typename generic_dynamic_indexed_component_array_store<C, I,Ts...>::const_iterator generic_dynamic_indexed_component_array_store<C, I,Ts...>::end() const
|
||||
{
|
||||
return iterator_type{
|
||||
m_ids.data(),
|
||||
m_indices.data(),
|
||||
component_array_ptrs(),
|
||||
m_component_flag_counts.data(),
|
||||
386
source/assets/data_stores/generic/generic_material_store.ipp
Normal file
386
source/assets/data_stores/generic/generic_material_store.ipp
Normal file
@@ -0,0 +1,386 @@
|
||||
#ifndef INCLUDE_GENERIC_MATERIAL_STORE_IMPLEMENTATION
|
||||
# error Never include this file directly include 'generic_material_store.hpp'
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <span>
|
||||
#include <tuple>
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include <algorithm>
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_material_store_iterator<Ts...>::generic_material_store_iterator(
|
||||
id_iterator_type ids,
|
||||
const component_iterator_type& components,
|
||||
flag_count_iterator_type flag_counts,
|
||||
std::size_t index,
|
||||
const offsets_type& offsets
|
||||
) :
|
||||
m_ids{ ids },
|
||||
m_components{ components },
|
||||
m_flag_counts{ flag_counts },
|
||||
m_index{ index },
|
||||
m_offsets{ offsets } {}
|
||||
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_material_store_iterator<Ts...>::reference assets::detail::generic_material_store_iterator<Ts...>::operator*() const {
|
||||
return dereference(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_material_store_iterator<Ts...>& assets::detail::generic_material_store_iterator<Ts...>::operator++() {
|
||||
adjust_offsets(std::index_sequence_for<Ts...>{}, 1);
|
||||
++m_index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_material_store_iterator<Ts...> assets::detail::generic_material_store_iterator<Ts...>::operator++(int) {
|
||||
generic_material_store_iterator tmp = *this;
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_material_store_iterator<Ts...>& assets::detail::generic_material_store_iterator<Ts...>::operator--() {
|
||||
adjust_offsets(std::index_sequence_for<Ts...>{}, -1);
|
||||
--m_index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_material_store_iterator<Ts...> assets::detail::generic_material_store_iterator<Ts...>::operator--(int) {
|
||||
auto tmp = *this;
|
||||
--(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_material_store_iterator<Ts...>& assets::detail::generic_material_store_iterator<Ts...>::operator+=(const difference_type n)
|
||||
{
|
||||
adjust_offsets(std::index_sequence_for<Ts...>{}, n);
|
||||
m_index += n;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_material_store_iterator<Ts...>& assets::detail::generic_material_store_iterator<Ts...>::operator-=(const difference_type n)
|
||||
{
|
||||
return (*this) += -n;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_material_store_iterator<Ts...> assets::detail::generic_material_store_iterator<Ts...>::operator+(const difference_type n) const
|
||||
{
|
||||
auto tmp = *this;
|
||||
return tmp += n; // TODO clion says n is unused
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_material_store_iterator<Ts...> assets::detail::generic_material_store_iterator<Ts...>::operator-(const difference_type n) const
|
||||
{
|
||||
auto tmp = *this;
|
||||
return tmp -= n; // TODO clion says n is unused
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_material_store_iterator<Ts...>::difference_type
|
||||
assets::detail::generic_material_store_iterator<Ts...>::operator-(const generic_material_store_iterator& other) const
|
||||
{
|
||||
return static_cast<difference_type>(m_index) - static_cast<difference_type>(other.m_index);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_material_store_iterator<Ts...>::reference assets::detail::generic_material_store_iterator<Ts...>::operator[](
|
||||
const difference_type n
|
||||
) const {
|
||||
return *(*this + n);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_material_store_iterator<Ts...>::operator==(const generic_material_store_iterator& other) const
|
||||
{
|
||||
return m_ids == other.m_ids and m_index == other.m_index;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_material_store_iterator<Ts...>::operator!=(const generic_material_store_iterator& other) const
|
||||
{
|
||||
return not (*this == other);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_material_store_iterator<Ts...>::operator<(const generic_material_store_iterator& other) const
|
||||
{
|
||||
return m_index < other.m_index;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_material_store_iterator<Ts...>::operator<=(const generic_material_store_iterator& other) const
|
||||
{
|
||||
return m_index <= other.m_index;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_material_store_iterator<Ts...>::operator>(const generic_material_store_iterator& other) const
|
||||
{
|
||||
return m_index > other.m_index;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_material_store_iterator<Ts...>::operator>=(const generic_material_store_iterator& other) const
|
||||
{
|
||||
return m_index >= other.m_index;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
template<std::size_t N>
|
||||
bool assets::detail::generic_material_store_iterator<Ts...>::is_component_enabled(component_flag_type flag)
|
||||
{
|
||||
return (flag & (component_flag_type{ 1 } << N)) != component_flag_type{};
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
template<std::size_t... Is>
|
||||
void assets::detail::generic_material_store_iterator<Ts...>::calc_offsets(
|
||||
std::index_sequence<Is...>,
|
||||
difference_type n
|
||||
) {
|
||||
|
||||
const auto negative = n < difference_type{ 0 };
|
||||
const auto positive = n > difference_type{ 0 };
|
||||
const auto step = difference_type{ positive } - difference_type{ negative };
|
||||
n = negative ? -n : n;
|
||||
|
||||
// TODO template optimize for single steps
|
||||
|
||||
while (n--)
|
||||
{
|
||||
const auto& [ flags, index_count, component_count ] = m_flag_counts[m_index];
|
||||
|
||||
std::get<0>(m_offsets) += step * index_count;
|
||||
|
||||
([&] {
|
||||
if (is_component_enabled<Is>(flags))
|
||||
{
|
||||
std::get<1 + Is>(m_offsets) += step * component_count;
|
||||
}
|
||||
}(), ...);
|
||||
|
||||
m_index += step;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
template<std::size_t... Is>
|
||||
typename assets::detail::generic_material_store_iterator<Ts...>::reference
|
||||
assets::detail::generic_material_store_iterator<Ts...>::dereference(std::index_sequence<Is...>) const
|
||||
{
|
||||
const auto& flags = m_flag_counts[m_index];
|
||||
|
||||
return std::make_pair(
|
||||
m_ids[m_index],
|
||||
material_view{
|
||||
.data = {
|
||||
(
|
||||
is_component_enabled<Is>(flags)
|
||||
? std::optional{ std::get<Is>(m_components)[m_offsets[Is]] }
|
||||
: std::nullopt
|
||||
)...
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
std::tuple<std::add_pointer_t<Ts>...> assets::detail::generic_material_store<Ts...>::component_iterators()
|
||||
{
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
return std::make_tuple(std::get<Is>(m_component_arrays).data()...);
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> assets::detail::generic_material_store<Ts...>::component_iterators() const
|
||||
{
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
return std::make_tuple(std::get<Is>(m_component_arrays).data()...);
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
std::array<typename assets::detail::generic_material_store<Ts...>::count_type, 1 + sizeof...(Ts)>
|
||||
assets::detail::generic_material_store<Ts...>::array_counts() const
|
||||
{
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
return std::array{
|
||||
std::get<Is>(m_component_arrays).size()...
|
||||
};
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_material_store<Ts...>::id_type assets::detail::generic_material_store<Ts...>::add(
|
||||
const material_data& material
|
||||
) {
|
||||
|
||||
const auto id = id_type{ m_next_data_id.index++ };
|
||||
m_ids.push_back(id);
|
||||
|
||||
auto component_flags = component_flag_type{};
|
||||
|
||||
[&]<auto... Is>(std::integer_sequence<Is...>)
|
||||
{
|
||||
if (const auto& component_opt = std::get<Is>(material.data))
|
||||
{
|
||||
std::get<Is>(material.data).push_back(*component_opt);
|
||||
component_flags |= component_flag_type{ 1 } << Is;
|
||||
}
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
|
||||
m_component_flag_counts.push_back(component_flags);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
std::pair<typename assets::detail::generic_material_store<Ts...>::iterator_type, bool> assets::detail::generic_material_store<Ts...>::find(id_type id)
|
||||
{
|
||||
const auto id_it = std::ranges::upper_bound(m_ids, id);
|
||||
|
||||
const auto match = (
|
||||
id_it != m_ids.begin() and
|
||||
*std::prev(id_it) == id
|
||||
);
|
||||
|
||||
const auto index = id_it - m_ids.begin() - match;
|
||||
|
||||
auto it = begin();
|
||||
it += index;
|
||||
|
||||
return { it, match };
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
std::pair<typename assets::detail::generic_material_store<Ts...>::const_iterator, bool> assets::detail::generic_material_store<Ts...>::find(id_type id) const
|
||||
{
|
||||
const auto id_it = std::ranges::upper_bound(m_ids, id);
|
||||
|
||||
const auto match = (
|
||||
id_it != m_ids.begin() and
|
||||
*std::prev(id_it) == id
|
||||
);
|
||||
|
||||
const auto index = id_it - m_ids.begin() - match;
|
||||
|
||||
auto it = begin();
|
||||
it += index;
|
||||
|
||||
return { it, match };
|
||||
}
|
||||
|
||||
|
||||
template<typename... Ts>
|
||||
void assets::detail::generic_material_store<Ts...>::remove(const iterator_type& it)
|
||||
{
|
||||
m_ids.erase(m_ids.begin() + it.m_index);
|
||||
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
auto& component_vector = std::get<Is>(m_component_arrays);
|
||||
(component_vector.erase(component_vector.begin() + it.m_offsets[Is]), ...);
|
||||
} (std::index_sequence_for<Ts...>{});
|
||||
|
||||
m_component_flag_counts.erase(m_component_flag_counts.begin() + it.m_index);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
void assets::detail::generic_material_store<Ts...>::clear()
|
||||
{
|
||||
m_ids.clear();
|
||||
[&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
std::get<Is>(m_component_arrays).clear();
|
||||
} (std::index_sequence_for<Ts...>{});
|
||||
m_component_flag_counts.clear();
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_material_store<Ts...>::iterator_type assets::detail::generic_material_store<Ts...>::begin()
|
||||
{
|
||||
return iterator_type{
|
||||
m_ids.data(),
|
||||
component_iterators(),
|
||||
m_component_flag_counts.data(),
|
||||
0,
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_material_store<Ts...>::iterator_type assets::detail::generic_material_store<Ts...>::end()
|
||||
{
|
||||
return iterator_type{
|
||||
m_ids.data(),
|
||||
component_iterators(),
|
||||
m_component_flag_counts.data(),
|
||||
m_component_flag_counts.size(),
|
||||
array_counts()
|
||||
};
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_material_store<Ts...>::const_iterator assets::detail::generic_material_store<Ts...>::begin() const
|
||||
{
|
||||
return const_iterator{
|
||||
m_ids.data(),
|
||||
component_iterators(),
|
||||
m_component_flag_counts.data(),
|
||||
0,
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_material_store<Ts...>::const_iterator assets::detail::generic_material_store<Ts...>::end() const
|
||||
{
|
||||
return const_iterator{
|
||||
m_ids.data(),
|
||||
component_iterators(),
|
||||
m_component_flag_counts.data(),
|
||||
m_component_flag_counts.size(),
|
||||
array_counts()
|
||||
};
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_material_store<Ts...>::const_iterator assets::detail::generic_material_store<Ts...>::cbegin() const
|
||||
{
|
||||
return const_cast<const generic_material_store*>(this)->begin();
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_material_store<Ts...>::const_iterator assets::detail::generic_material_store<Ts...>::cend() const
|
||||
{
|
||||
return const_cast<const generic_material_store*>(this)->end();
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_material_store<Ts...>::view_type assets::detail::generic_material_store<Ts...>::view()
|
||||
{
|
||||
return { begin(), end() };
|
||||
}
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_material_store<Ts...>::const_view_type assets::detail::generic_material_store<Ts...>::view() const
|
||||
{
|
||||
return { begin(), end() };
|
||||
}
|
||||
449
source/assets/data_stores/generic/generic_mesh_store.ipp
Normal file
449
source/assets/data_stores/generic/generic_mesh_store.ipp
Normal file
@@ -0,0 +1,449 @@
|
||||
#ifndef INCLUDE_GENERIC_MESH_STORE_IMPLEMENTATION
|
||||
# error Never include this file directly include 'generic_mesh_store.hpp'
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <span>
|
||||
#include <tuple>
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include <algorithm>
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_mesh_store_iterator<Ts...>::generic_mesh_store_iterator(
|
||||
id_iterator_type ids,
|
||||
index_iterator_type indices,
|
||||
const component_iterator_type& components,
|
||||
material_id_iterator_type material_ids,
|
||||
flag_count_iterator_type flag_counts,
|
||||
std::size_t index,
|
||||
const offsets_type& offsets
|
||||
) :
|
||||
m_ids{ ids },
|
||||
m_indices{ indices },
|
||||
m_components{ components },
|
||||
m_material_ids{ material_ids },
|
||||
m_flag_counts{ flag_counts },
|
||||
m_index{ index },
|
||||
m_offsets{ offsets } {}
|
||||
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_mesh_store_iterator<Ts...>::reference assets::detail::generic_mesh_store_iterator<Ts...>::operator*() const {
|
||||
return dereference(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_mesh_store_iterator<Ts...>& assets::detail::generic_mesh_store_iterator<Ts...>::operator++() {
|
||||
adjust_offsets(std::index_sequence_for<Ts...>{}, 1);
|
||||
++m_index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_mesh_store_iterator<Ts...> assets::detail::generic_mesh_store_iterator<Ts...>::operator++(int) {
|
||||
generic_mesh_store_iterator tmp = *this;
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_mesh_store_iterator<Ts...>& assets::detail::generic_mesh_store_iterator<Ts...>::operator--() {
|
||||
adjust_offsets(std::index_sequence_for<Ts...>{}, -1);
|
||||
--m_index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_mesh_store_iterator<Ts...> assets::detail::generic_mesh_store_iterator<Ts...>::operator--(int) {
|
||||
auto tmp = *this;
|
||||
--(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_mesh_store_iterator<Ts...>& assets::detail::generic_mesh_store_iterator<Ts...>::operator+=(const difference_type n)
|
||||
{
|
||||
adjust_offsets(std::index_sequence_for<Ts...>{}, n);
|
||||
m_index += n;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_mesh_store_iterator<Ts...>& assets::detail::generic_mesh_store_iterator<Ts...>::operator-=(const difference_type n)
|
||||
{
|
||||
return (*this) += -n;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_mesh_store_iterator<Ts...> assets::detail::generic_mesh_store_iterator<Ts...>::operator+(const difference_type n) const
|
||||
{
|
||||
auto tmp = *this;
|
||||
return tmp += n; // TODO clion says n is unused
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_mesh_store_iterator<Ts...> assets::detail::generic_mesh_store_iterator<Ts...>::operator-(const difference_type n) const
|
||||
{
|
||||
auto tmp = *this;
|
||||
return tmp -= n; // TODO clion says n is unused
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_mesh_store_iterator<Ts...>::difference_type
|
||||
assets::detail::generic_mesh_store_iterator<Ts...>::operator-(const generic_mesh_store_iterator& other) const
|
||||
{
|
||||
return static_cast<difference_type>(m_index) - static_cast<difference_type>(other.m_index);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_mesh_store_iterator<Ts...>::reference assets::detail::generic_mesh_store_iterator<Ts...>::operator[](
|
||||
const difference_type n
|
||||
) const {
|
||||
return *(*this + n);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_mesh_store_iterator<Ts...>::operator==(const generic_mesh_store_iterator& other) const
|
||||
{
|
||||
return m_ids == other.m_ids and m_index == other.m_index;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_mesh_store_iterator<Ts...>::operator!=(const generic_mesh_store_iterator& other) const
|
||||
{
|
||||
return not (*this == other);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_mesh_store_iterator<Ts...>::operator<(const generic_mesh_store_iterator& other) const
|
||||
{
|
||||
return m_index < other.m_index;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_mesh_store_iterator<Ts...>::operator<=(const generic_mesh_store_iterator& other) const
|
||||
{
|
||||
return m_index <= other.m_index;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_mesh_store_iterator<Ts...>::operator>(const generic_mesh_store_iterator& other) const
|
||||
{
|
||||
return m_index > other.m_index;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_mesh_store_iterator<Ts...>::operator>=(const generic_mesh_store_iterator& other) const
|
||||
{
|
||||
return m_index >= other.m_index;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
template<std::size_t N>
|
||||
bool assets::detail::generic_mesh_store_iterator<Ts...>::is_component_enabled(component_flag_type flag)
|
||||
{
|
||||
return (flag & (component_flag_type{ 1 } << N)) != component_flag_type{};
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
template<std::size_t... Is>
|
||||
void assets::detail::generic_mesh_store_iterator<Ts...>::calc_offsets(
|
||||
std::index_sequence<Is...>,
|
||||
difference_type n
|
||||
) {
|
||||
|
||||
const auto negative = n < difference_type{ 0 };
|
||||
const auto positive = n > difference_type{ 0 };
|
||||
const auto step = difference_type{ positive } - difference_type{ negative };
|
||||
n = negative ? -n : n;
|
||||
|
||||
// TODO template optimize for single steps
|
||||
|
||||
while (n--)
|
||||
{
|
||||
const auto& [ flags, index_count, component_count ] = m_flag_counts[m_index];
|
||||
|
||||
std::get<0>(m_offsets) += step * index_count;
|
||||
|
||||
([&] {
|
||||
if (is_component_enabled<Is>(flags))
|
||||
{
|
||||
std::get<1 + Is>(m_offsets) += step * component_count;
|
||||
}
|
||||
}(), ...);
|
||||
|
||||
m_index += step;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
template<std::size_t... Is>
|
||||
typename assets::detail::generic_mesh_store_iterator<Ts...>::reference
|
||||
assets::detail::generic_mesh_store_iterator<Ts...>::dereference(std::index_sequence<Is...>) const
|
||||
{
|
||||
const auto& [ flags, index_count, component_count ] = m_flag_counts[m_index];
|
||||
|
||||
return std::make_pair(
|
||||
m_ids[m_index],
|
||||
mesh_view{
|
||||
.component_flags = flags,
|
||||
.indices = std::span(
|
||||
m_indices[m_offsets[0]],
|
||||
index_count
|
||||
),
|
||||
.vertex_component_arrays = std::make_tuple(
|
||||
std::span(
|
||||
&std::get<Is>(m_components)[m_offsets[1 + Is]],
|
||||
is_component_enabled<Is>(flags) ? component_count : 0
|
||||
)...
|
||||
)
|
||||
.material_id = m_material_ids[m_index]
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
std::tuple<std::add_pointer_t<Ts>...> assets::detail::generic_mesh_store<Ts...>::component_iterators()
|
||||
{
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
return std::make_tuple(std::get<Is>(m_component_arrays).data()...);
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> assets::detail::generic_mesh_store<Ts...>::component_iterators() const
|
||||
{
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
return std::make_tuple(std::get<Is>(m_component_arrays).data()...);
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
std::array<typename assets::detail::generic_mesh_store<Ts...>::count_type, 1 + sizeof...(Ts)>
|
||||
assets::detail::generic_mesh_store<Ts...>::array_counts() const
|
||||
{
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
return std::array{
|
||||
m_indices.size(),
|
||||
std::get<Is>(m_component_arrays).size()...
|
||||
};
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_mesh_store<Ts...>::id_type assets::detail::generic_mesh_store<Ts...>::add(
|
||||
const mesh_data& mesh
|
||||
) {
|
||||
|
||||
const auto id = id_type{ m_next_data_id.index++ };
|
||||
m_ids.push_back(id);
|
||||
|
||||
const auto& vertices = mesh.vertices;
|
||||
const auto& triangles = mesh.triangles();
|
||||
const auto indices = std::span(triangles.front().data(), triangles.size() * 3);
|
||||
|
||||
auto component_flags = component_flag_type{};
|
||||
auto min_component_count = count_type{};
|
||||
|
||||
// finding out correct component flags and count
|
||||
[&]<auto... Is>(std::integer_sequence<Is...>)
|
||||
{
|
||||
const auto& component_array = std::get<Is>(vertices);
|
||||
if (not component_array.empty())
|
||||
{
|
||||
const auto component_count = static_cast<count_type>(component_array.size());
|
||||
if (min_component_count != 0 and component_count < min_component_count)
|
||||
{
|
||||
min_component_count = component_count;
|
||||
}
|
||||
component_flags |= component_flag_type{ 1 } << Is;
|
||||
}
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
|
||||
// Insert indices
|
||||
m_indices.insert(m_indices.end(), indices.begin(), indices.end());
|
||||
|
||||
// Insert vertex components
|
||||
[&]<auto... Is>(std::integer_sequence<Is...>)
|
||||
{
|
||||
const auto& src_array = std::get<Is>(vertices);
|
||||
auto& dst_array = std::get<Is>(m_component_arrays);
|
||||
|
||||
if (not src_array.empty())
|
||||
{
|
||||
dst_array.insert(dst_array.end(), src_array.begin(), src_array.begin() + min_component_count);
|
||||
}
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
|
||||
// Insert material
|
||||
m_material_ids.emplace_back(mesh.material_id());
|
||||
|
||||
// TODO check count
|
||||
m_component_flag_counts.emplace_back(
|
||||
mesh.component_flags,
|
||||
static_cast<count_type>(indices.size()),
|
||||
min_component_count
|
||||
);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
std::pair<typename assets::detail::generic_mesh_store<Ts...>::iterator_type, bool> assets::detail::generic_mesh_store<Ts...>::find(id_type id)
|
||||
{
|
||||
const auto id_it = std::ranges::upper_bound(m_ids, id);
|
||||
|
||||
const auto match = (
|
||||
id_it != m_ids.begin() and
|
||||
*std::prev(id_it) == id
|
||||
);
|
||||
|
||||
const auto index = id_it - m_ids.begin() - match;
|
||||
|
||||
auto it = begin();
|
||||
it += index;
|
||||
|
||||
return { it, match };
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
std::pair<typename assets::detail::generic_mesh_store<Ts...>::const_iterator, bool> assets::detail::generic_mesh_store<Ts...>::find(id_type id) const
|
||||
{
|
||||
const auto id_it = std::ranges::upper_bound(m_ids, id);
|
||||
|
||||
const auto match = (
|
||||
id_it != m_ids.begin() and
|
||||
*std::prev(id_it) == id
|
||||
);
|
||||
|
||||
const auto index = id_it - m_ids.begin() - match;
|
||||
|
||||
auto it = begin();
|
||||
it += index;
|
||||
|
||||
return { it, match };
|
||||
}
|
||||
|
||||
|
||||
template<typename... Ts>
|
||||
void assets::detail::generic_mesh_store<Ts...>::remove(const iterator_type& it)
|
||||
{
|
||||
m_ids.erase(m_ids.begin() + it.m_index);
|
||||
|
||||
m_indices.erase(m_indices.begin() + it.m_offsets[0]);
|
||||
|
||||
[&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
([&]{
|
||||
auto& component_vector = std::get<Is>(m_component_arrays);
|
||||
const auto begin = component_vector.begin() + it.m_offsets[1 + Is];
|
||||
const auto end = begin + it.m_flag_counts[it.m_index];
|
||||
component_vector.erase(begin, end);
|
||||
}(), ...);
|
||||
} (std::index_sequence_for<Ts...>{});
|
||||
|
||||
m_material_ids.erase(m_material_ids.begin() + it.m_index);
|
||||
|
||||
m_component_flag_counts.erase(m_component_flag_counts.begin() + it.m_index);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
void assets::detail::generic_mesh_store<Ts...>::clear()
|
||||
{
|
||||
m_ids.clear();
|
||||
m_indices.clear();
|
||||
[&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
std::get<Is>(m_component_arrays).clear();
|
||||
} (std::index_sequence_for<Ts...>{});
|
||||
m_component_flag_counts.clear();
|
||||
m_material_ids.clear();
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_mesh_store<Ts...>::iterator_type assets::detail::generic_mesh_store<Ts...>::begin()
|
||||
{
|
||||
return iterator_type{
|
||||
m_ids.data(),
|
||||
m_indices.data(),
|
||||
component_iterators(),
|
||||
m_material_ids.data(),
|
||||
m_component_flag_counts.data(),
|
||||
0,
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_mesh_store<Ts...>::iterator_type assets::detail::generic_mesh_store<Ts...>::end()
|
||||
{
|
||||
return iterator_type{
|
||||
m_ids.data(),
|
||||
m_indices.data(),
|
||||
component_iterators(),
|
||||
m_material_ids.data(),
|
||||
m_component_flag_counts.data(),
|
||||
m_component_flag_counts.size(),
|
||||
array_counts()
|
||||
};
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_mesh_store<Ts...>::const_iterator assets::detail::generic_mesh_store<Ts...>::begin() const
|
||||
{
|
||||
return const_iterator{
|
||||
m_ids.data(),
|
||||
m_indices.data(),
|
||||
component_iterators(),
|
||||
m_material_ids.data(),
|
||||
m_component_flag_counts.data(),
|
||||
0,
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_mesh_store<Ts...>::const_iterator assets::detail::generic_mesh_store<Ts...>::end() const
|
||||
{
|
||||
return const_iterator{
|
||||
m_ids.data(),
|
||||
m_indices.data(),
|
||||
component_iterators(),
|
||||
m_material_ids.data(),
|
||||
m_component_flag_counts.data(),
|
||||
m_component_flag_counts.size(),
|
||||
array_counts()
|
||||
};
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_mesh_store<Ts...>::const_iterator assets::detail::generic_mesh_store<Ts...>::cbegin() const
|
||||
{
|
||||
return const_cast<const generic_mesh_store*>(this)->begin();
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_mesh_store<Ts...>::const_iterator assets::detail::generic_mesh_store<Ts...>::cend() const
|
||||
{
|
||||
return const_cast<const generic_mesh_store*>(this)->end();
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_mesh_store<Ts...>::view_type assets::detail::generic_mesh_store<Ts...>::view()
|
||||
{
|
||||
return { begin(), end() };
|
||||
}
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_mesh_store<Ts...>::const_view_type assets::detail::generic_mesh_store<Ts...>::view() const
|
||||
{
|
||||
return { begin(), end() };
|
||||
}
|
||||
415
source/assets/data_stores/generic/generic_point_cloud_store.ipp
Normal file
415
source/assets/data_stores/generic/generic_point_cloud_store.ipp
Normal file
@@ -0,0 +1,415 @@
|
||||
#ifndef INCLUDE_GENERIC_POINT_CLOUD_STORE_IMPLEMENTATION
|
||||
# error Never include this file directly include 'generic_point_cloud_store.hpp'
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <span>
|
||||
#include <tuple>
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include <algorithm>
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_point_cloud_store_iterator<Ts...>::generic_point_cloud_store_iterator(
|
||||
id_iterator_type ids,
|
||||
const component_iterator_type& components,
|
||||
const flag_count_iterator_type flag_counts,
|
||||
std::size_t index,
|
||||
const offsets_type& offsets
|
||||
) :
|
||||
m_ids{ ids },
|
||||
m_components{ components },
|
||||
m_flag_counts{ flag_counts },
|
||||
m_index{ index },
|
||||
m_offsets{ offsets } {}
|
||||
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_point_cloud_store_iterator<Ts...>::reference assets::detail::generic_point_cloud_store_iterator<Ts...>::operator*() const {
|
||||
return dereference(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_point_cloud_store_iterator<Ts...>& assets::detail::generic_point_cloud_store_iterator<Ts...>::operator++() {
|
||||
adjust_offsets(std::index_sequence_for<Ts...>{}, 1);
|
||||
++m_index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_point_cloud_store_iterator<Ts...> assets::detail::generic_point_cloud_store_iterator<Ts...>::operator++(int) {
|
||||
generic_point_cloud_store_iterator tmp = *this;
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_point_cloud_store_iterator<Ts...>& assets::detail::generic_point_cloud_store_iterator<Ts...>::operator--() {
|
||||
adjust_offsets(std::index_sequence_for<Ts...>{}, -1);
|
||||
--m_index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_point_cloud_store_iterator<Ts...> assets::detail::generic_point_cloud_store_iterator<Ts...>::operator--(int) {
|
||||
auto tmp = *this;
|
||||
--(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_point_cloud_store_iterator<Ts...>& assets::detail::generic_point_cloud_store_iterator<Ts...>::operator+=(const difference_type n)
|
||||
{
|
||||
adjust_offsets(std::index_sequence_for<Ts...>{}, n);
|
||||
m_index += n;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_point_cloud_store_iterator<Ts...>& assets::detail::generic_point_cloud_store_iterator<Ts...>::operator-=(const difference_type n)
|
||||
{
|
||||
return (*this) += -n;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_point_cloud_store_iterator<Ts...> assets::detail::generic_point_cloud_store_iterator<Ts...>::operator+(const difference_type n) const
|
||||
{
|
||||
auto tmp = *this;
|
||||
return tmp += n; // TODO clion says n is unused
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
assets::detail::generic_point_cloud_store_iterator<Ts...> assets::detail::generic_point_cloud_store_iterator<Ts...>::operator-(const difference_type n) const
|
||||
{
|
||||
auto tmp = *this;
|
||||
return tmp -= n; // TODO clion says n is unused
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_point_cloud_store_iterator<Ts...>::difference_type
|
||||
assets::detail::generic_point_cloud_store_iterator<Ts...>::operator-(const generic_point_cloud_store_iterator& other) const
|
||||
{
|
||||
return static_cast<difference_type>(m_index) - static_cast<difference_type>(other.m_index);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_point_cloud_store_iterator<Ts...>::reference assets::detail::generic_point_cloud_store_iterator<Ts...>::operator[](
|
||||
const difference_type n
|
||||
) const {
|
||||
return *(*this + n);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_point_cloud_store_iterator<Ts...>::operator==(const generic_point_cloud_store_iterator& other) const
|
||||
{
|
||||
return m_ids == other.m_ids and m_index == other.m_index;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_point_cloud_store_iterator<Ts...>::operator!=(const generic_point_cloud_store_iterator& other) const
|
||||
{
|
||||
return not (*this == other);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_point_cloud_store_iterator<Ts...>::operator<(const generic_point_cloud_store_iterator& other) const
|
||||
{
|
||||
return m_index < other.m_index;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_point_cloud_store_iterator<Ts...>::operator<=(const generic_point_cloud_store_iterator& other) const
|
||||
{
|
||||
return m_index <= other.m_index;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_point_cloud_store_iterator<Ts...>::operator>(const generic_point_cloud_store_iterator& other) const
|
||||
{
|
||||
return m_index > other.m_index;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool assets::detail::generic_point_cloud_store_iterator<Ts...>::operator>=(const generic_point_cloud_store_iterator& other) const
|
||||
{
|
||||
return m_index >= other.m_index;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
template<std::size_t N>
|
||||
bool assets::detail::generic_point_cloud_store_iterator<Ts...>::is_component_enabled(component_flag_type flag)
|
||||
{
|
||||
return (flag & (component_flag_type{ 1 } << N)) != component_flag_type{};
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
template<std::size_t... Is>
|
||||
void assets::detail::generic_point_cloud_store_iterator<Ts...>::calc_offsets(
|
||||
std::index_sequence<Is...>,
|
||||
difference_type n
|
||||
) {
|
||||
|
||||
const auto negative = n < difference_type{ 0 };
|
||||
const auto positive = n > difference_type{ 0 };
|
||||
const auto step = difference_type{ positive } - difference_type{ negative };
|
||||
n = negative ? -n : n;
|
||||
|
||||
// TODO template optimize for single steps
|
||||
|
||||
while (n--)
|
||||
{
|
||||
const auto& [ flags, index_count, component_count ] = m_flag_counts[m_index];
|
||||
|
||||
std::get<0>(m_offsets) += step * index_count;
|
||||
|
||||
([&] {
|
||||
if (is_component_enabled<Is>(flags))
|
||||
{
|
||||
std::get<1 + Is>(m_offsets) += step * component_count;
|
||||
}
|
||||
}(), ...);
|
||||
|
||||
m_index += step;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
template<std::size_t... Is>
|
||||
typename assets::detail::generic_point_cloud_store_iterator<Ts...>::reference
|
||||
assets::detail::generic_point_cloud_store_iterator<Ts...>::dereference(std::index_sequence<Is...>) const
|
||||
{
|
||||
const auto& [ flags, index_count, component_count ] = m_flag_counts[m_index];
|
||||
|
||||
return std::make_pair(
|
||||
m_ids[m_index],
|
||||
point_cloud_view{
|
||||
.vertex_components = flags,
|
||||
.vertex_component_arrays = std::make_tuple(
|
||||
std::span(
|
||||
&std::get<Is>(m_components)[m_offsets[1 + Is]],
|
||||
is_component_enabled<Is>(flags) ? component_count : 0
|
||||
)...
|
||||
)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
std::tuple<std::add_pointer_t<Ts>...> assets::detail::generic_point_cloud_store<Ts...>::component_iterators()
|
||||
{
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
return std::make_tuple(std::get<Is>(m_component_arrays).data()...);
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> assets::detail::generic_point_cloud_store<Ts...>::component_iterators() const
|
||||
{
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
return std::make_tuple(std::get<Is>(m_component_arrays).data()...);
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
std::array<typename assets::detail::generic_point_cloud_store<Ts...>::count_type, 1 + sizeof...(Ts)>
|
||||
assets::detail::generic_point_cloud_store<Ts...>::array_counts() const
|
||||
{
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
return std::array{
|
||||
std::get<Is>(m_component_arrays).size()...
|
||||
};
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_point_cloud_store<Ts...>::id_type assets::detail::generic_point_cloud_store<Ts...>::add(
|
||||
const point_cloud_data& point_cloud
|
||||
) {
|
||||
|
||||
const auto id = id_type{ m_next_data_id.index++ };
|
||||
m_ids.push_back(id);
|
||||
|
||||
const auto& vertices = point_cloud.vertices;
|
||||
|
||||
auto component_flags = component_flag_type{};
|
||||
auto min_component_count = count_type{};
|
||||
|
||||
// finding out correct component flags and count
|
||||
[&]<auto... Is>(std::integer_sequence<Is...>)
|
||||
{
|
||||
const auto& component_array = std::get<Is>(vertices);
|
||||
if (not component_array.empty())
|
||||
{
|
||||
const auto component_count = static_cast<count_type>(component_array.size());
|
||||
if (min_component_count != 0 and component_count < min_component_count)
|
||||
{
|
||||
min_component_count = component_count;
|
||||
}
|
||||
component_flags |= component_flag_type{ 1 } << Is;
|
||||
}
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
|
||||
// Insert vertex components
|
||||
[&]<auto... Is>(std::integer_sequence<Is...>)
|
||||
{
|
||||
const auto& src_array = std::get<Is>(vertices);
|
||||
auto& dst_array = std::get<Is>(m_component_arrays);
|
||||
|
||||
if (not src_array.empty())
|
||||
{
|
||||
dst_array.insert(dst_array.end(), src_array.begin(), src_array.begin() + min_component_count);
|
||||
}
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
|
||||
// TODO check count
|
||||
m_component_flag_counts.emplace_back(
|
||||
point_cloud.component_flags,
|
||||
min_component_count
|
||||
);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
std::pair<typename assets::detail::generic_point_cloud_store<Ts...>::iterator_type, bool> assets::detail::generic_point_cloud_store<Ts...>::find(id_type id)
|
||||
{
|
||||
const auto id_it = std::ranges::upper_bound(m_ids, id);
|
||||
|
||||
const auto match = (
|
||||
id_it != m_ids.begin() and
|
||||
*std::prev(id_it) == id
|
||||
);
|
||||
|
||||
const auto index = id_it - m_ids.begin() - match;
|
||||
|
||||
auto it = begin();
|
||||
it += index;
|
||||
|
||||
return { it, match };
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
std::pair<typename assets::detail::generic_point_cloud_store<Ts...>::const_iterator, bool> assets::detail::generic_point_cloud_store<Ts...>::find(id_type id) const
|
||||
{
|
||||
const auto id_it = std::ranges::upper_bound(m_ids, id);
|
||||
|
||||
const auto match = (
|
||||
id_it != m_ids.begin() and
|
||||
*std::prev(id_it) == id
|
||||
);
|
||||
|
||||
const auto index = id_it - m_ids.begin() - match;
|
||||
|
||||
auto it = begin();
|
||||
it += index;
|
||||
|
||||
return { it, match };
|
||||
}
|
||||
|
||||
|
||||
template<typename... Ts>
|
||||
void assets::detail::generic_point_cloud_store<Ts...>::remove(const iterator_type& it)
|
||||
{
|
||||
[&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
([&]{
|
||||
auto& component_vector = std::get<Is>(m_component_arrays);
|
||||
const auto begin = component_vector.begin() + it.m_offsets[1 + Is];
|
||||
const auto end = begin + it.m_flag_counts[it.m_index];
|
||||
component_vector.erase(begin, end);
|
||||
}(), ...);
|
||||
} (std::index_sequence_for<Ts...>{});
|
||||
|
||||
m_component_flag_counts.erase(m_component_flag_counts.begin() + it.m_index);
|
||||
m_ids.erase(m_ids.begin() + it.m_index);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
void assets::detail::generic_point_cloud_store<Ts...>::clear()
|
||||
{
|
||||
m_ids.clear();
|
||||
[&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
std::get<Is>(m_component_arrays).clear();
|
||||
} (std::index_sequence_for<Ts...>{});
|
||||
m_component_flag_counts.clear();
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_point_cloud_store<Ts...>::iterator_type assets::detail::generic_point_cloud_store<Ts...>::begin()
|
||||
{
|
||||
return iterator_type{
|
||||
m_ids.data(),
|
||||
component_iterators(),
|
||||
m_component_flag_counts.data(),
|
||||
0,
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_point_cloud_store<Ts...>::iterator_type assets::detail::generic_point_cloud_store<Ts...>::end()
|
||||
{
|
||||
return iterator_type{
|
||||
m_ids.data(),
|
||||
component_iterators(),
|
||||
m_component_flag_counts.data(),
|
||||
m_component_flag_counts.size(),
|
||||
array_counts()
|
||||
};
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_point_cloud_store<Ts...>::const_iterator assets::detail::generic_point_cloud_store<Ts...>::begin() const
|
||||
{
|
||||
return const_iterator{
|
||||
m_ids.data(),
|
||||
component_iterators(),
|
||||
m_component_flag_counts.data(),
|
||||
0,
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_point_cloud_store<Ts...>::const_iterator assets::detail::generic_point_cloud_store<Ts...>::end() const
|
||||
{
|
||||
return const_iterator{
|
||||
m_ids.data(),
|
||||
component_iterators(),
|
||||
m_component_flag_counts.data(),
|
||||
m_component_flag_counts.size(),
|
||||
array_counts()
|
||||
};
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_point_cloud_store<Ts...>::const_iterator assets::detail::generic_point_cloud_store<Ts...>::cbegin() const
|
||||
{
|
||||
return const_cast<const generic_point_cloud_store*>(this)->begin();
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_point_cloud_store<Ts...>::const_iterator assets::detail::generic_point_cloud_store<Ts...>::cend() const
|
||||
{
|
||||
return const_cast<const generic_point_cloud_store*>(this)->end();
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_point_cloud_store<Ts...>::view_type assets::detail::generic_point_cloud_store<Ts...>::view()
|
||||
{
|
||||
return { begin(), end() };
|
||||
}
|
||||
template<typename... Ts>
|
||||
typename assets::detail::generic_point_cloud_store<Ts...>::const_view_type assets::detail::generic_point_cloud_store<Ts...>::view() const
|
||||
{
|
||||
return { begin(), end() };
|
||||
}
|
||||
303
source/assets/data_stores/shader_source_store.ipp
Normal file
303
source/assets/data_stores/shader_source_store.ipp
Normal file
@@ -0,0 +1,303 @@
|
||||
#ifndef INCLUDE_SHADER_SOURCE_STORE_IMPLEMENTATION
|
||||
# error Never include this file directly include 'shader_source_store.hpp'
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <span>
|
||||
#include <tuple>
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include <algorithm>
|
||||
|
||||
template<typename Char>
|
||||
assets::shader_source_store_iterator<Char>::shader_source_store_iterator(
|
||||
id_iterator_type ids,
|
||||
string_iterator_type strings,
|
||||
length_iterator_type lengths,
|
||||
std::size_t index,
|
||||
const offset_type& offset
|
||||
) :
|
||||
m_ids{ ids },
|
||||
m_strings{ strings },
|
||||
m_lengths{ lengths },
|
||||
m_index{ index },
|
||||
m_offset{ offset } {}
|
||||
|
||||
|
||||
template<typename Char>
|
||||
typename assets::shader_source_store_iterator<Char>::reference assets::shader_source_store_iterator<Char>::operator*() const {
|
||||
return dereference(std::index_sequence_for<Char>{});
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
assets::shader_source_store_iterator<Char>& assets::shader_source_store_iterator<Char>::operator++() {
|
||||
adjust_offsets(std::index_sequence_for<Char>{}, 1);
|
||||
++m_index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
assets::shader_source_store_iterator<Char> assets::shader_source_store_iterator<Char>::operator++(int) {
|
||||
shader_source_store_iterator tmp = *this;
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
assets::shader_source_store_iterator<Char>& assets::shader_source_store_iterator<Char>::operator--() {
|
||||
adjust_offsets(std::index_sequence_for<Char>{}, -1);
|
||||
--m_index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
assets::shader_source_store_iterator<Char> assets::shader_source_store_iterator<Char>::operator--(int) {
|
||||
auto tmp = *this;
|
||||
--(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
assets::shader_source_store_iterator<Char>& assets::shader_source_store_iterator<Char>::operator+=(const difference_type n)
|
||||
{
|
||||
adjust_offsets(std::index_sequence_for<Char>{}, n);
|
||||
m_index += n;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
assets::shader_source_store_iterator<Char>& assets::shader_source_store_iterator<Char>::operator-=(const difference_type n)
|
||||
{
|
||||
return (*this) += -n;
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
assets::shader_source_store_iterator<Char> assets::shader_source_store_iterator<Char>::operator+(const difference_type n) const
|
||||
{
|
||||
auto tmp = *this;
|
||||
return tmp += n; // TODO clion says n is unused
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
assets::shader_source_store_iterator<Char> assets::shader_source_store_iterator<Char>::operator-(const difference_type n) const
|
||||
{
|
||||
auto tmp = *this;
|
||||
return tmp -= n; // TODO clion says n is unused
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
typename assets::shader_source_store_iterator<Char>::difference_type
|
||||
assets::shader_source_store_iterator<Char>::operator-(const shader_source_store_iterator& other) const
|
||||
{
|
||||
return static_cast<difference_type>(m_index) - static_cast<difference_type>(other.m_index);
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
typename assets::shader_source_store_iterator<Char>::reference assets::shader_source_store_iterator<Char>::operator[](
|
||||
const difference_type n
|
||||
) const {
|
||||
return *(*this + n);
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
bool assets::shader_source_store_iterator<Char>::operator==(const shader_source_store_iterator& other) const
|
||||
{
|
||||
return m_ids == other.m_ids and m_index == other.m_index;
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
bool assets::shader_source_store_iterator<Char>::operator!=(const shader_source_store_iterator& other) const
|
||||
{
|
||||
return not (*this == other);
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
bool assets::shader_source_store_iterator<Char>::operator<(const shader_source_store_iterator& other) const
|
||||
{
|
||||
return m_index < other.m_index;
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
bool assets::shader_source_store_iterator<Char>::operator<=(const shader_source_store_iterator& other) const
|
||||
{
|
||||
return m_index <= other.m_index;
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
bool assets::shader_source_store_iterator<Char>::operator>(const shader_source_store_iterator& other) const
|
||||
{
|
||||
return m_index > other.m_index;
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
bool assets::shader_source_store_iterator<Char>::operator>=(const shader_source_store_iterator& other) const
|
||||
{
|
||||
return m_index >= other.m_index;
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
void assets::shader_source_store_iterator<Char>::calc_offset(
|
||||
difference_type n
|
||||
) {
|
||||
|
||||
const auto negative = n < difference_type{ 0 };
|
||||
const auto positive = n > difference_type{ 0 };
|
||||
const auto step = difference_type{ positive } - difference_type{ negative };
|
||||
n = negative ? -n : n;
|
||||
|
||||
// TODO template optimize for single steps
|
||||
|
||||
while (n--)
|
||||
{
|
||||
const auto& count = m_lengths[m_index];
|
||||
m_offset += step * count;
|
||||
m_index += step;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
template<std::size_t... Is>
|
||||
typename assets::shader_source_store_iterator<Char>::reference
|
||||
assets::shader_source_store_iterator<Char>::dereference(std::index_sequence<Is...>) const
|
||||
{
|
||||
return std::make_pair(
|
||||
m_ids[m_index],
|
||||
shader_source_view(
|
||||
m_strings[m_offset],
|
||||
m_lengths[m_index]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
assets::shader_source_store::id_type assets::shader_source_store::add(
|
||||
const shader_source_data& shader_source
|
||||
) {
|
||||
|
||||
const auto id = id_type{ m_next_data_id.index++ };
|
||||
m_ids.push_back(id);
|
||||
|
||||
m_strings.reserve(m_strings.size() + shader_source.source.size() + 1);
|
||||
m_strings.insert(m_strings.end(), shader_source.source.begin(), shader_source.source.end());
|
||||
m_strings.push_back('\0');
|
||||
|
||||
m_lengths.push_back(shader_source.source.size());
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
std::pair<assets::shader_source_store::iterator_type, bool> assets::shader_source_store::find(id_type id)
|
||||
{
|
||||
const auto id_it = std::ranges::upper_bound(m_ids, id);
|
||||
|
||||
const auto match = (
|
||||
id_it != m_ids.begin() and
|
||||
*std::prev(id_it) == id
|
||||
);
|
||||
|
||||
const auto index = id_it - m_ids.begin() - match;
|
||||
|
||||
auto it = begin();
|
||||
it += index;
|
||||
|
||||
return { it, match };
|
||||
}
|
||||
|
||||
std::pair<assets::shader_source_store::const_iterator, bool> assets::shader_source_store::find(id_type id) const
|
||||
{
|
||||
const auto id_it = std::ranges::upper_bound(m_ids, id);
|
||||
|
||||
const auto match = (
|
||||
id_it != m_ids.begin() and
|
||||
*std::prev(id_it) == id
|
||||
);
|
||||
|
||||
const auto index = id_it - m_ids.begin() - match;
|
||||
|
||||
auto it = begin();
|
||||
it += index;
|
||||
|
||||
return { it, match };
|
||||
}
|
||||
|
||||
void assets::shader_source_store::remove(const iterator_type& it)
|
||||
{
|
||||
m_ids.erase(m_ids.begin() + it.m_index);
|
||||
|
||||
const auto begin = m_strings.begin() + it.m_offset;
|
||||
const auto end = begin + it.m_lengths[it.m_index];
|
||||
m_strings.erase(begin, end);
|
||||
|
||||
m_lengths.erase(m_lengths.begin() + it.m_index);
|
||||
}
|
||||
|
||||
void assets::shader_source_store::clear()
|
||||
{
|
||||
m_ids.clear();
|
||||
m_strings.clear();
|
||||
m_lengths.clear();
|
||||
}
|
||||
|
||||
assets::shader_source_store::iterator_type assets::shader_source_store::begin()
|
||||
{
|
||||
return iterator_type{
|
||||
m_ids.data(),
|
||||
m_strings.data(),
|
||||
m_lengths.data(),
|
||||
0,
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
||||
assets::shader_source_store::iterator_type assets::shader_source_store::end()
|
||||
{
|
||||
return iterator_type{
|
||||
m_ids.data(),
|
||||
m_strings.data(),
|
||||
m_lengths.data(),
|
||||
m_lengths.size(),
|
||||
m_strings.size()
|
||||
};
|
||||
}
|
||||
|
||||
assets::shader_source_store::const_iterator assets::shader_source_store::begin() const
|
||||
{
|
||||
return const_iterator{
|
||||
m_ids.data(),
|
||||
m_strings.data(),
|
||||
m_lengths.data(),
|
||||
0,
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
||||
assets::shader_source_store::const_iterator assets::shader_source_store::end() const
|
||||
{
|
||||
return const_iterator{
|
||||
m_ids.data(),
|
||||
m_strings.data(),
|
||||
m_lengths.data(),
|
||||
m_lengths.size(),
|
||||
m_strings.size()
|
||||
};
|
||||
}
|
||||
|
||||
assets::shader_source_store::const_iterator assets::shader_source_store::cbegin() const
|
||||
{
|
||||
return const_cast<const shader_source_store*>(this)->begin();
|
||||
}
|
||||
|
||||
assets::shader_source_store::const_iterator assets::shader_source_store::cend() const
|
||||
{
|
||||
return const_cast<const shader_source_store*>(this)->end();
|
||||
}
|
||||
|
||||
assets::shader_source_store::view_type assets::shader_source_store::view()
|
||||
{
|
||||
return { begin(), end() };
|
||||
}
|
||||
|
||||
assets::shader_source_store::const_view_type assets::shader_source_store::view() const
|
||||
{
|
||||
return { begin(), end() };
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
#include "assets/dynamic_data_stores/dynamic_material_store.hpp"
|
||||
|
||||
dynamic_material_store::id_type dynamic_material_store::add(const dynamic_material_buffer& buffer)
|
||||
{
|
||||
return m_store.add(buffer.data);
|
||||
}
|
||||
|
||||
std::pair<dynamic_material_store::iterator_type, bool> dynamic_material_store::find(const id_type id)
|
||||
{
|
||||
return m_store.find(id);
|
||||
}
|
||||
|
||||
std::pair<dynamic_material_store::const_iterator, bool> dynamic_material_store::find(const id_type id) const
|
||||
{
|
||||
return m_store.find(id);
|
||||
}
|
||||
|
||||
void dynamic_material_store::remove(const iterator_type& it)
|
||||
{
|
||||
m_store.remove(it);
|
||||
}
|
||||
|
||||
void dynamic_material_store::clear()
|
||||
{
|
||||
m_store.clear();
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
#include "assets/dynamic_data_stores/dynamic_mesh_store.hpp"
|
||||
|
||||
|
||||
dynamic_mesh_store::id_type dynamic_mesh_store::add(const dynamic_mesh_buffer& mesh_buffer)
|
||||
{
|
||||
const auto& triangles = mesh_buffer.triangles();
|
||||
return m_store.add(
|
||||
std::span{ triangles.front().data(), triangles.size() * 3 },
|
||||
mesh_buffer.vertices
|
||||
);
|
||||
}
|
||||
|
||||
std::pair<dynamic_mesh_store::iterator_type, bool> dynamic_mesh_store::find(id_type id)
|
||||
{
|
||||
return m_store.find(id);
|
||||
}
|
||||
|
||||
std::pair<dynamic_mesh_store::const_iterator, bool> dynamic_mesh_store::find(id_type id) const
|
||||
{
|
||||
return m_store.find(id);
|
||||
}
|
||||
|
||||
void dynamic_mesh_store::remove(const iterator_type& it)
|
||||
{
|
||||
m_store.remove(it);
|
||||
}
|
||||
|
||||
void dynamic_mesh_store::clear()
|
||||
{
|
||||
m_store.clear();
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
#include "assets/dynamic_data_stores/dynamic_point_cloud_store.hpp"
|
||||
|
||||
|
||||
dynamic_point_cloud_store::id_type dynamic_point_cloud_store::add(const dynamic_point_cloud_buffer& mesh_buffer)
|
||||
{
|
||||
return m_store.add(mesh_buffer.vertices);
|
||||
}
|
||||
|
||||
std::pair<dynamic_point_cloud_store::iterator_type, bool> dynamic_point_cloud_store::find(id_type id)
|
||||
{
|
||||
return m_store.find(id);
|
||||
}
|
||||
|
||||
std::pair<dynamic_point_cloud_store::const_iterator, bool> dynamic_point_cloud_store::find(id_type id) const
|
||||
{
|
||||
return m_store.find(id);
|
||||
}
|
||||
|
||||
void dynamic_point_cloud_store::remove(const iterator_type& it)
|
||||
{
|
||||
m_store.remove(it);
|
||||
}
|
||||
|
||||
void dynamic_point_cloud_store::clear()
|
||||
{
|
||||
m_store.clear();
|
||||
}
|
||||
@@ -1,373 +0,0 @@
|
||||
#ifndef INCLUDE_GENERIC_DYNAMIC_COMPONENT_STORE_IMPLEMENTATION
|
||||
# error Never include this file directly include 'basic_dynamic_component_store.hpp'
|
||||
#endif
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <span>
|
||||
|
||||
#include "util/uix.hpp"
|
||||
#include "util/id_type.hpp"
|
||||
|
||||
#include <tuple>
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include <algorithm>
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
component_iterator<C, Ts...>::component_iterator(
|
||||
const value_type components,
|
||||
const C* flags,
|
||||
std::size_t index,
|
||||
const offsets_type& offsets
|
||||
) : m_components{ components }, m_flags{ flags }, m_index{ index }, m_offsets{ offsets } {}
|
||||
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
typename component_iterator<C, Ts...>::reference component_iterator<C, Ts...>::operator*() const {
|
||||
return dereference(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
component_iterator<C, Ts...>& component_iterator<C, Ts...>::operator++() {
|
||||
adjust_offsets(std::index_sequence_for<Ts...>{}, 1);
|
||||
++m_index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
component_iterator<C, Ts...> component_iterator<C, Ts...>::operator++(int) {
|
||||
component_iterator tmp = *this;
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
component_iterator<C, Ts...>& component_iterator<C, Ts...>::operator--() {
|
||||
adjust_offsets(std::index_sequence_for<Ts...>{}, -1);
|
||||
--m_index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
component_iterator<C, Ts...> component_iterator<C, Ts...>::operator--(int) {
|
||||
auto tmp = *this;
|
||||
--(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
component_iterator<C, Ts...>& component_iterator<C, Ts...>::operator+=(const difference_type n)
|
||||
{
|
||||
adjust_offsets(std::index_sequence_for<Ts...>{}, n);
|
||||
m_index += n;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
component_iterator<C, Ts...>& component_iterator<C, Ts...>::operator-=(const difference_type n)
|
||||
{
|
||||
return (*this) += -n;
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
component_iterator<C, Ts...> component_iterator<C, Ts...>::operator+(const difference_type n) const
|
||||
{
|
||||
auto tmp = *this;
|
||||
return tmp += n;
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
component_iterator<C, Ts...> component_iterator<C, Ts...>::operator-(const difference_type n) const
|
||||
{
|
||||
auto tmp = *this;
|
||||
return tmp -= n;
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
typename component_iterator<C, Ts...>::difference_type
|
||||
component_iterator<C, Ts...>::operator-(const component_iterator& other) const
|
||||
{
|
||||
return static_cast<difference_type>(m_index) - static_cast<difference_type>(other.m_index);
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
typename component_iterator<C, Ts...>::reference component_iterator<C, Ts...>::operator[](
|
||||
const difference_type n
|
||||
) const {
|
||||
return *((*this) + n);
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
bool component_iterator<C, Ts...>::operator==(const component_iterator& other) const
|
||||
{
|
||||
return m_components == other.m_components and m_index == other.m_index;
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
bool component_iterator<C, Ts...>::operator!=(const component_iterator& other) const
|
||||
{
|
||||
return not (*this == other);
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
bool component_iterator<C, Ts...>::operator<(const component_iterator& other) const
|
||||
{
|
||||
return m_index < other.m_index;
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
bool component_iterator<C, Ts...>::operator<=(const component_iterator& other) const
|
||||
{
|
||||
return m_index <= other.m_index;
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
bool component_iterator<C, Ts...>::operator>(const component_iterator& other) const
|
||||
{
|
||||
return m_index > other.m_index;
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
bool component_iterator<C, Ts...>::operator>=(const component_iterator& other) const
|
||||
{
|
||||
return m_index >= other.m_index;
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
template<std::size_t I>
|
||||
bool component_iterator<C, Ts...>::is_component_enabled(C flag)
|
||||
{
|
||||
return (flag & (C{1} << I)) != C{};
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
template<std::size_t... Is>
|
||||
void component_iterator<C, Ts...>::calc_offsets(std::index_sequence<Is...>, difference_type n)
|
||||
{
|
||||
|
||||
const auto negative = n < difference_type{ 0 };
|
||||
const auto positive = n > difference_type{ 0 };
|
||||
const auto step = difference_type{ positive } - difference_type{ negative };
|
||||
n = negative ? -n : n;
|
||||
|
||||
// TODO template optimize for single steps
|
||||
|
||||
while (n--)
|
||||
{
|
||||
const C& flag = m_flags[m_index + n];
|
||||
|
||||
([&] {
|
||||
if (is_component_enabled<Is>(flag)) {
|
||||
std::get<Is>(m_offsets) += step;
|
||||
}
|
||||
}(), ...);
|
||||
|
||||
m_index += step;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
template<std::size_t... Is>
|
||||
typename component_iterator<C, Ts...>::reference
|
||||
component_iterator<C, Ts...>::dereference(std::index_sequence<Is...>) const
|
||||
{
|
||||
return std::make_tuple(get_pointer<Is>()...);
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
template<std::size_t N>
|
||||
std::tuple_element_t<N, typename component_iterator<C, Ts...>::value_type>
|
||||
component_iterator<C, Ts...>::get_pointer() const
|
||||
{
|
||||
if (is_component_enabled<N>(m_flags[m_index]))
|
||||
{
|
||||
return &std::get<N>(m_components)[m_offsets[N]];
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
std::tuple<std::add_pointer_t<Ts>...> component_iterator<C, Ts...>::data_ptrs()
|
||||
{
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
return std::make_tuple(std::get<Is>(m_components).data()...);
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> component_iterator<C, Ts...>::data_ptrs() const
|
||||
{
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
return std::make_tuple(std::get<Is>(m_components).data()...);
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
std::array<std::size_t, sizeof...(Ts)> component_iterator<C, Ts...>::data_counts() const
|
||||
{
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
return std::array{ std::get<Is>(m_components).size()... };
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
typename generic_dynamic_component_store<C, Ts...>::id_type generic_dynamic_component_store<C, Ts...>::add(
|
||||
const std::tuple<std::optional<Ts>...>& data
|
||||
) {
|
||||
|
||||
auto component_flags = C{};
|
||||
|
||||
[&]<auto... Is>(std::integer_sequence<Is...>)
|
||||
{
|
||||
if (const auto& component_opt = std::get<Is>(data))
|
||||
{
|
||||
std::get<Is>(m_components).push_back(*component_opt);
|
||||
component_flags |= C{ 1 } << Is;
|
||||
}
|
||||
}
|
||||
(std::index_sequence_for<Ts...>{});
|
||||
|
||||
m_component_flags.push_back(component_flags);
|
||||
|
||||
const auto id = id_type{ m_next_data_id.index++ };
|
||||
m_ids.push_back(id);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
std::pair<typename generic_dynamic_component_store<C, Ts...>::iterator_type, bool> generic_dynamic_component_store<C, Ts...>::find(id_type id)
|
||||
{
|
||||
const auto id_it = std::ranges::upper_bound(m_ids, id);
|
||||
|
||||
const auto match = (
|
||||
id_it != m_ids.begin() and
|
||||
*std::prev(id_it) == id
|
||||
);
|
||||
|
||||
const auto index = id_it - m_ids.begin() - match;
|
||||
|
||||
auto it = begin();
|
||||
it += index;
|
||||
|
||||
return { it, match };
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
std::pair<typename generic_dynamic_component_store<C, Ts...>::const_iterator, bool> generic_dynamic_component_store<C, Ts...>::find(id_type id) const
|
||||
{
|
||||
const auto id_it = std::ranges::upper_bound(m_ids, id);
|
||||
|
||||
const auto match = (
|
||||
id_it != m_ids.begin() and
|
||||
*std::prev(id_it) == id
|
||||
);
|
||||
|
||||
const auto index = id_it - m_ids.begin() - match;
|
||||
|
||||
auto it = begin();
|
||||
it += index;
|
||||
|
||||
return { it, match };
|
||||
}
|
||||
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
void generic_dynamic_component_store<C, Ts...>::remove(const iterator_type& it)
|
||||
{
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
auto& component_vector = std::get<Is>(m_components);
|
||||
(component_vector.erase(component_vector.begin() + it.m_offsets[Is]), ...);
|
||||
} (std::index_sequence_for<Ts...>{});
|
||||
|
||||
m_component_flags.erase(m_component_flags.begin() + it.m_index);
|
||||
m_ids.erase(m_ids.begin() + it.m_index);
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
void generic_dynamic_component_store<C, Ts...>::clear()
|
||||
{
|
||||
return [&]<auto... Is>(std::index_sequence<Is>)
|
||||
{
|
||||
std::get<Is>(m_component_counts).clear();
|
||||
} (std::index_sequence_for<Ts...>{});
|
||||
m_component_flags.clear();
|
||||
m_ids.clear();
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
generic_dynamic_component_store<C, Ts...>::iterator_type generic_dynamic_component_store<C, Ts...>::begin()
|
||||
{
|
||||
return iterator_type{
|
||||
data_ptrs(),
|
||||
m_component_flags.data(),
|
||||
0,
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
generic_dynamic_component_store<C, Ts...>::iterator_type generic_dynamic_component_store<C, Ts...>::end()
|
||||
{
|
||||
return iterator_type{
|
||||
data_ptrs(),
|
||||
m_component_flags.data(),
|
||||
m_component_flags.size(),
|
||||
data_counts()
|
||||
};
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
generic_dynamic_component_store<C, Ts...>::const_iterator generic_dynamic_component_store<C, Ts...>::begin() const
|
||||
{
|
||||
return iterator_type{
|
||||
data_ptrs(),
|
||||
m_component_flags.data(),
|
||||
0,
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
generic_dynamic_component_store<C, Ts...>::const_iterator generic_dynamic_component_store<C, Ts...>::end() const
|
||||
{
|
||||
return iterator_type{
|
||||
data_ptrs(),
|
||||
m_component_flags.data(),
|
||||
m_component_flags.size(),
|
||||
data_counts()
|
||||
};
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
generic_dynamic_component_store<C, Ts...>::const_iterator generic_dynamic_component_store<C, Ts...>::cbegin() const
|
||||
{
|
||||
return const_cast<const generic_dynamic_component_store*>(this)->begin();
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
generic_dynamic_component_store<C, Ts...>::const_iterator generic_dynamic_component_store<C, Ts...>::cend() const
|
||||
{
|
||||
return const_cast<const generic_dynamic_component_store*>(this)->end();
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
generic_dynamic_component_store<C, Ts...>::view_type generic_dynamic_component_store<C, Ts...>::view()
|
||||
{
|
||||
return { begin(), end() };
|
||||
}
|
||||
template<typename C, typename... Ts>
|
||||
generic_dynamic_component_store<C, Ts...>::const_view_type generic_dynamic_component_store<C, Ts...>::view() const
|
||||
{
|
||||
return { begin(), end() };
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
#ifndef INCLUDE_DYNAMIC_MATERIAL_DATA_IMPLEMENTATION
|
||||
# error Never include this file directly include 'dynamic_material_buffer.hpp'
|
||||
#endif
|
||||
|
||||
|
||||
inline std::optional<components::material::surface_properties>& dynamic_material_buffer::surface_properties()
|
||||
{
|
||||
return std::get<components::material::indices::surface_properties>(data);
|
||||
}
|
||||
inline std::optional<components::material::transparency>& dynamic_material_buffer::transparency()
|
||||
{
|
||||
return std::get<components::material::indices::transparency>(data);
|
||||
}
|
||||
inline std::optional<dynamic_texture_store::id_type>& dynamic_material_buffer::ambient_color_texture_id()
|
||||
{
|
||||
return std::get<components::material::indices::ambient_color_texture>(data);
|
||||
}
|
||||
inline std::optional<dynamic_texture_store::id_type>& dynamic_material_buffer::diffuse_color_texture_id()
|
||||
{
|
||||
return std::get<components::material::indices::diffuse_color_texture>(data);
|
||||
}
|
||||
inline std::optional<dynamic_texture_store::id_type>& dynamic_material_buffer::specular_color_texture_id()
|
||||
{
|
||||
return std::get<components::material::indices::specular_color_texture>(data);
|
||||
}
|
||||
inline std::optional<dynamic_texture_store::id_type>& dynamic_material_buffer::shininess_texture_id()
|
||||
{
|
||||
return std::get<components::material::indices::shininess_texture>(data);
|
||||
}
|
||||
inline std::optional<dynamic_texture_store::id_type>& dynamic_material_buffer::alpha_texture_id()
|
||||
{
|
||||
return std::get<components::material::indices::alpha_texture>(data);
|
||||
}
|
||||
inline std::optional<dynamic_texture_store::id_type>& dynamic_material_buffer::bump_texture_id()
|
||||
{
|
||||
return std::get<components::material::indices::bump_texture(data);
|
||||
}
|
||||
|
||||
inline const std::optional<components::material::surface_properties>& dynamic_material_buffer::surface_properties() const
|
||||
{
|
||||
return std::get<components::material::indices::surface_properties>(data);
|
||||
}
|
||||
|
||||
inline const std::optional<components::material::transparency>& dynamic_material_buffer::transparency() const
|
||||
{
|
||||
return std::get<components::material::indices::transparency>(data);
|
||||
}
|
||||
|
||||
inline const std::optional<dynamic_texture_store::id_type>& dynamic_material_buffer::ambient_color_texture_id() const
|
||||
{
|
||||
return std::get<components::material::indices::ambient_color_texture>(data);
|
||||
}
|
||||
|
||||
inline const std::optional<dynamic_texture_store::id_type>& dynamic_material_buffer::diffuse_color_texture_id() const
|
||||
{
|
||||
return std::get<components::material::indices::diffuse_color_texture>(data);
|
||||
}
|
||||
|
||||
inline const std::optional<dynamic_texture_store::id_type>& dynamic_material_buffer::specular_color_texture_id() const
|
||||
{
|
||||
return std::get<components::material::indices::specular_color_texture>(data);
|
||||
}
|
||||
|
||||
inline const std::optional<dynamic_texture_store::id_type>& dynamic_material_buffer::shininess_texture_id() const
|
||||
{
|
||||
return std::get<components::material::indices::shininess_texture>(data);
|
||||
}
|
||||
|
||||
inline const std::optional<dynamic_texture_store::id_type>& dynamic_material_buffer::alpha_texture_id() const
|
||||
{
|
||||
return std::get<components::material::indices::alpha_texture>(data);
|
||||
}
|
||||
|
||||
inline const std::optional<dynamic_texture_store::id_type>& dynamic_material_buffer::bump_texture_id() const
|
||||
{
|
||||
return std::get<components::material::indices::bump_texture>(data);
|
||||
}
|
||||
|
||||
|
||||
inline components::material::surface_properties& dynamic_material_buffer::initialized_surface_properties()
|
||||
{
|
||||
auto& surface_properties_opt = surface_properties();
|
||||
if (not surface_properties_opt)
|
||||
{
|
||||
surface_properties_opt = components::material::surface_properties{};
|
||||
}
|
||||
return *surface_properties_opt;
|
||||
}
|
||||
|
||||
inline void dynamic_material_buffer::clear()
|
||||
{
|
||||
std::apply(
|
||||
[](auto&... data_opt) {
|
||||
(data_opt.reset(), ...);
|
||||
},
|
||||
data
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
#ifndef INCLUDE_DYNAMIC_MESH_DATA_IMPLEMENTATION
|
||||
# error Never include this file directly include 'dynamic_mesh_buffer.hpp'
|
||||
#endif
|
||||
|
||||
inline std::vector<components::mesh_vertex::position>& dynamic_mesh_buffer::positions()
|
||||
{
|
||||
return std::get<components::mesh_vertex::indices::position>(vertices);
|
||||
}
|
||||
|
||||
inline std::vector<components::mesh_vertex::normal>& dynamic_mesh_buffer::normals()
|
||||
{
|
||||
return std::get<components::mesh_vertex::indices::normal>(vertices);
|
||||
}
|
||||
|
||||
inline std::vector<components::mesh_vertex::tex_coord>& dynamic_mesh_buffer::tex_coords()
|
||||
{
|
||||
return std::get<components::mesh_vertex::indices::tex_coord>(vertices);
|
||||
}
|
||||
|
||||
inline std::vector<components::mesh_vertex::color>& dynamic_mesh_buffer::colors()
|
||||
{
|
||||
return std::get<components::mesh_vertex::indices::color>(vertices);
|
||||
}
|
||||
|
||||
inline std::vector<components::mesh_vertex::reflectance>& dynamic_mesh_buffer::reflectances()
|
||||
{
|
||||
return std::get<components::mesh_vertex::indices::reflectance>(vertices);
|
||||
}
|
||||
|
||||
inline std::vector<dynamic_mesh_buffer::triangle_type>& dynamic_mesh_buffer::triangles()
|
||||
{
|
||||
return m_triangles;
|
||||
}
|
||||
|
||||
inline auto& dynamic_mesh_buffer::material_id()
|
||||
{
|
||||
return m_material_id;
|
||||
}
|
||||
|
||||
inline const std::vector<components::mesh_vertex::position>& dynamic_mesh_buffer::positions() const
|
||||
{
|
||||
return std::get<components::mesh_vertex::indices::position>(vertices);
|
||||
}
|
||||
|
||||
inline const std::vector<components::mesh_vertex::normal>& dynamic_mesh_buffer::normals() const
|
||||
{
|
||||
return std::get<components::mesh_vertex::indices::normal>(vertices);
|
||||
}
|
||||
|
||||
inline const std::vector<components::mesh_vertex::tex_coord>& dynamic_mesh_buffer::tex_coords() const
|
||||
{
|
||||
return std::get<components::mesh_vertex::indices::tex_coord>(vertices);
|
||||
}
|
||||
|
||||
inline const std::vector<components::mesh_vertex::color>& dynamic_mesh_buffer::colors() const
|
||||
{
|
||||
return std::get<components::mesh_vertex::indices::color>(vertices);
|
||||
}
|
||||
|
||||
inline const std::vector<components::mesh_vertex::reflectance>& dynamic_mesh_buffer::reflectances() const
|
||||
{
|
||||
return std::get<components::mesh_vertex::indices::reflectance>(vertices);
|
||||
}
|
||||
|
||||
inline const std::vector<dynamic_mesh_buffer::triangle_type>& dynamic_mesh_buffer::triangles() const
|
||||
{
|
||||
return m_triangles;
|
||||
}
|
||||
|
||||
inline const auto& dynamic_mesh_buffer::material_id() const
|
||||
{
|
||||
return m_material_id;
|
||||
}
|
||||
|
||||
inline void dynamic_mesh_buffer::clear()
|
||||
{
|
||||
clear_vertices();
|
||||
m_triangles.clear();
|
||||
m_material_id = {};
|
||||
}
|
||||
@@ -1,148 +0,0 @@
|
||||
#ifndef INCLUDE_DYNAMIC_MODEL_DATA_IMPLEMENTATION
|
||||
# error Never include this file directly include 'dynamic_vertex_buffer.hpp'
|
||||
#endif
|
||||
|
||||
#include "util/specialised_lambda.hpp"
|
||||
#include "opengl/type_utils.hpp"
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
C& dynamic_vertex_buffer<C, Ts...>::components()
|
||||
{
|
||||
return m_components;
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
const C& dynamic_vertex_buffer<C, Ts...>::components() const
|
||||
{
|
||||
return m_components;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
concept numeric_type = std::integral<T> or std::floating_point<T>;
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
void dynamic_vertex_buffer<C, Ts...>::build_vertex_buffer(
|
||||
std::vector<ztu::u8>& vertex_buffer,
|
||||
std::size_t& component_count,
|
||||
std::array<GLenum, sizeof...(Ts)>& component_types,
|
||||
std::array<GLint, sizeof...(Ts)>& component_lengths,
|
||||
GLsizei& stride
|
||||
) const {
|
||||
const auto for_all_components = [&]<typename T>(auto&& f, const T default_value)
|
||||
{
|
||||
return std::apply(
|
||||
[&](const auto&... component_buffer)
|
||||
{
|
||||
std::array<T, sizeof...(component_buffer)> results{};
|
||||
auto i = std::size_t{};
|
||||
(
|
||||
(
|
||||
results[i] = [&](const auto& buffer, const auto index) -> T
|
||||
{
|
||||
if ((m_components & C{ 1 << index }) != C{})
|
||||
{
|
||||
return f(buffer, index);
|
||||
}
|
||||
return default_value;
|
||||
}(component_buffer, i),
|
||||
++i
|
||||
),
|
||||
...
|
||||
);
|
||||
return results;
|
||||
},
|
||||
m_component_buffers
|
||||
);
|
||||
};
|
||||
|
||||
component_count = 0;
|
||||
component_types = for_all_components(
|
||||
ztu::specialised_lambda
|
||||
{
|
||||
[&component_count]<numeric_type Component, std::size_t Count>(const std::vector<std::array<Component, Count>>&, std::size_t)
|
||||
{
|
||||
++component_count;
|
||||
return zgl::type_utils::to_gl_type<Component>();
|
||||
},
|
||||
[&component_count]<numeric_type Component>(const std::vector<Component>&, std::size_t)
|
||||
{
|
||||
++component_count;
|
||||
return zgl::type_utils::to_gl_type<Component>();
|
||||
}
|
||||
},
|
||||
GLenum{ GL_INVALID_VALUE }
|
||||
);
|
||||
|
||||
const auto element_counts = for_all_components(
|
||||
[]<class Component>(const std::vector<Component>& buffer, std::size_t)
|
||||
{
|
||||
return buffer.size();
|
||||
},
|
||||
std::numeric_limits<std::size_t>::max()
|
||||
);
|
||||
|
||||
const auto minimum_element_count = std::ranges::min(element_counts);
|
||||
|
||||
component_lengths = for_all_components(
|
||||
ztu::specialised_lambda
|
||||
{
|
||||
[]<class Component>(const std::vector<Component>&, std::size_t)
|
||||
{
|
||||
return 1;
|
||||
},
|
||||
[]<class Component, std::size_t Count>(const std::vector<std::array<Component, Count>>&, std::size_t)
|
||||
{
|
||||
return Count;
|
||||
}
|
||||
},
|
||||
GLsizei{ 0 }
|
||||
);
|
||||
|
||||
auto component_sizes = std::array<GLsizei, sizeof...(Ts)>{};
|
||||
for (std::size_t i{}; i != component_sizes.size(); ++i)
|
||||
{
|
||||
component_sizes[i] = component_lengths[i] * zgl::type_utils::size_of(component_types[i]);
|
||||
}
|
||||
|
||||
const auto total_size = minimum_element_count * std::accumulate(
|
||||
component_sizes.begin(),
|
||||
component_sizes.end(),
|
||||
GLsizei{ 0 }
|
||||
);
|
||||
|
||||
vertex_buffer.resize(total_size);
|
||||
|
||||
// Calculate offsets and stride
|
||||
auto component_offsets = component_sizes;
|
||||
stride = 0;
|
||||
for (std::size_t i{}; i != component_offsets.size(); ++i) {
|
||||
component_offsets[i] = stride;
|
||||
stride += component_sizes[i];
|
||||
}
|
||||
|
||||
// Copy all the components over one by one
|
||||
for_all_components(
|
||||
[&]<class Component>(const std::vector<Component>& buffer, std::size_t index)
|
||||
{
|
||||
std::size_t pos = component_offsets[index];
|
||||
for (std::size_t i{}; i != minimum_element_count; ++i)
|
||||
{
|
||||
std::memcpy(
|
||||
&vertex_buffer[pos],
|
||||
buffer[i].data(),
|
||||
component_sizes[index]
|
||||
);
|
||||
pos += stride;
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
0
|
||||
);
|
||||
|
||||
// remove values of unused components
|
||||
std::ignore = std::ranges::remove(component_lengths, 0);
|
||||
std::ignore = std::ranges::remove(component_types, GL_INVALID_VALUE);
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
#ifndef INCLUDE_DYNAMIC_TEXTURE_DATA_IMPLEMENTATION
|
||||
# error Never include this file directly include 'dynamic_point_cloud_buffer.hpp'
|
||||
#endif
|
||||
#include "assets/components/point_cloud_vertex_components.hpp"
|
||||
|
||||
inline std::vector<components::point_cloud_vertex::position>& dynamic_point_cloud_buffer::positions()
|
||||
{
|
||||
return std::get<components::point_cloud_vertex::indices::position>(vertices);
|
||||
}
|
||||
|
||||
inline std::vector<components::point_cloud_vertex::normal>& dynamic_point_cloud_buffer::normals()
|
||||
{
|
||||
return std::get<components::point_cloud_vertex::indices::normal>(vertices);
|
||||
}
|
||||
|
||||
inline std::vector<components::point_cloud_vertex::color>& dynamic_point_cloud_buffer::colors()
|
||||
{
|
||||
return std::get<components::point_cloud_vertex::indices::color>(vertices);
|
||||
}
|
||||
|
||||
inline std::vector<components::point_cloud_vertex::reflectance>& dynamic_point_cloud_buffer::reflectances()
|
||||
{
|
||||
return std::get<components::point_cloud_vertex::indices::reflectance>(vertices);
|
||||
}
|
||||
|
||||
inline const std::vector<components::point_cloud_vertex::position>& dynamic_point_cloud_buffer::positions() const
|
||||
{
|
||||
return std::get<components::point_cloud_vertex::indices::position>(vertices);
|
||||
}
|
||||
|
||||
inline const std::vector<components::point_cloud_vertex::normal>& dynamic_point_cloud_buffer::normals() const
|
||||
{
|
||||
return std::get<components::point_cloud_vertex::indices::normal>(vertices);
|
||||
}
|
||||
|
||||
inline const std::vector<components::point_cloud_vertex::color>& dynamic_point_cloud_buffer::colors() const
|
||||
{
|
||||
return std::get<components::point_cloud_vertex::indices::color>(vertices);
|
||||
}
|
||||
|
||||
inline const std::vector<components::point_cloud_vertex::reflectance>& dynamic_point_cloud_buffer::reflectances() const
|
||||
{
|
||||
return std::get<components::point_cloud_vertex::indices::reflectance>(vertices);
|
||||
}
|
||||
|
||||
inline void dynamic_point_cloud_buffer::clear()
|
||||
{
|
||||
clear_vertices();
|
||||
}
|
||||
@@ -1,159 +0,0 @@
|
||||
#ifndef INCLUDE_DYNAMIC_TEXTURE_DATA_IMPLEMENTATION
|
||||
# error Never include this file directly include 'dynamic_texture_buffer.hpp'
|
||||
#endif
|
||||
|
||||
|
||||
inline dynamic_texture_buffer::dynamic_texture_buffer(
|
||||
std::unique_ptr<value_type>&& data,
|
||||
const dim_type width,
|
||||
const dim_type height,
|
||||
const components::texture::flags components
|
||||
) :
|
||||
m_data{ std::move(data) },
|
||||
m_width{ width },
|
||||
m_height{ height },
|
||||
m_components{ components }
|
||||
{};
|
||||
|
||||
inline dynamic_texture_buffer::dynamic_texture_buffer(const dynamic_texture_buffer& other) :
|
||||
m_data{ new value_type[other.component_count()] },
|
||||
m_width{ other.m_width },
|
||||
m_height{ other.m_height },
|
||||
m_components{ other.m_components }
|
||||
{
|
||||
std::copy_n(other.m_data.get(), other.m_width * other.m_height, this->m_data.get());
|
||||
}
|
||||
|
||||
inline dynamic_texture_buffer::dynamic_texture_buffer(dynamic_texture_buffer&& other) noexcept :
|
||||
m_data{ std::move(other.m_data) },
|
||||
m_width{ other.m_width },
|
||||
m_height{ other.m_height },
|
||||
m_components{ other.m_components }
|
||||
{
|
||||
other.m_width = 0;
|
||||
other.m_height = 0;
|
||||
other.m_components = components::texture::flags::none;
|
||||
}
|
||||
|
||||
inline dynamic_texture_buffer& dynamic_texture_buffer::operator=(const dynamic_texture_buffer& other)
|
||||
{
|
||||
if (this != &other) [[likely]]
|
||||
{
|
||||
|
||||
const auto m_size = this->component_count();
|
||||
const auto o_size = other.component_count();
|
||||
|
||||
if (o_size > m_size) {
|
||||
this->~dynamic_texture_buffer();
|
||||
this->m_data.reset(new value_type[o_size]);
|
||||
}
|
||||
|
||||
std::copy_n(other.m_data.get(), o_size, this->m_data.get());
|
||||
|
||||
this->m_width = other.m_width;
|
||||
this->m_height = other.m_height;
|
||||
this->m_components = other.m_components;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline dynamic_texture_buffer& dynamic_texture_buffer::operator=(dynamic_texture_buffer&& other) noexcept
|
||||
{
|
||||
if (this != &other) [[likely]]
|
||||
{
|
||||
this->~dynamic_texture_buffer();
|
||||
|
||||
this->m_data = std::move(other.m_data);
|
||||
this->m_width = other.m_width;
|
||||
this->m_height = other.m_height;
|
||||
|
||||
other.m_width = 0;
|
||||
other.m_height = 0;
|
||||
other.m_components = components::texture::flags::none;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline components::texture::flags dynamic_texture_buffer::components() const
|
||||
{
|
||||
return m_components;
|
||||
}
|
||||
|
||||
inline dynamic_texture_buffer::dim_type dynamic_texture_buffer::width() const
|
||||
{
|
||||
return m_width;
|
||||
}
|
||||
|
||||
inline dynamic_texture_buffer::dim_type dynamic_texture_buffer::height() const
|
||||
{
|
||||
return m_height;
|
||||
}
|
||||
|
||||
inline std::pair<dynamic_texture_buffer::dim_type, dynamic_texture_buffer::dim_type> dynamic_texture_buffer::dimensions() const
|
||||
{
|
||||
return { m_width, m_height };
|
||||
}
|
||||
|
||||
inline dynamic_texture_buffer::size_type dynamic_texture_buffer::pixel_count() const
|
||||
{
|
||||
return static_cast<size_type>(m_width) * static_cast<size_type>(m_height);
|
||||
}
|
||||
|
||||
inline dynamic_texture_buffer::size_type dynamic_texture_buffer::component_count() const
|
||||
{
|
||||
return std::popcount(static_cast<std::underlying_type_t<components::texture::flags>>(m_components));
|
||||
}
|
||||
|
||||
inline dynamic_texture_buffer::size_type dynamic_texture_buffer::size() const
|
||||
{
|
||||
return pixel_count() * component_count();
|
||||
}
|
||||
|
||||
inline dynamic_texture_buffer::const_pointer dynamic_texture_buffer::data() const
|
||||
{
|
||||
return m_data.get();
|
||||
}
|
||||
|
||||
inline dynamic_texture_buffer::pointer dynamic_texture_buffer::data()
|
||||
{
|
||||
return m_data.get();
|
||||
}
|
||||
|
||||
inline dynamic_texture_buffer::const_iterator dynamic_texture_buffer::begin() const
|
||||
{
|
||||
return data();
|
||||
}
|
||||
|
||||
inline dynamic_texture_buffer::iterator dynamic_texture_buffer::begin()
|
||||
{
|
||||
return data();
|
||||
}
|
||||
|
||||
inline dynamic_texture_buffer::const_iterator dynamic_texture_buffer::end() const
|
||||
{
|
||||
return begin() + component_count();
|
||||
}
|
||||
|
||||
inline dynamic_texture_buffer::iterator dynamic_texture_buffer::end()
|
||||
{
|
||||
return begin() + component_count();
|
||||
}
|
||||
|
||||
inline dynamic_texture_buffer::const_iterator dynamic_texture_buffer::cbegin() const
|
||||
{
|
||||
return const_cast<const_iterator>(begin());
|
||||
}
|
||||
|
||||
inline dynamic_texture_buffer::const_iterator dynamic_texture_buffer::cend() const
|
||||
{
|
||||
return const_cast<const_iterator>(begin());
|
||||
}
|
||||
|
||||
inline void dynamic_texture_buffer::clear()
|
||||
{
|
||||
m_data.reset();
|
||||
m_width = 0;
|
||||
m_height = 0;
|
||||
m_components = {};
|
||||
}
|
||||
@@ -251,21 +251,21 @@ std::error_code generic_3dtk_loader<Normal, Color, Reflectance>::read_point_file
|
||||
|
||||
constexpr auto expected_component_count = []()
|
||||
{
|
||||
auto count = std::tuple_size_v<components::point_cloud_vertex::position>;
|
||||
auto count = std::tuple_size_v<point_cloud_vertex_components::position>;
|
||||
|
||||
if (Normal)
|
||||
{
|
||||
count += std::tuple_size_v<components::point_cloud_vertex::normal>;
|
||||
count += std::tuple_size_v<point_cloud_vertex_components::normal>;
|
||||
}
|
||||
|
||||
if (Color)
|
||||
{
|
||||
count += std::tuple_size_v<components::point_cloud_vertex::color>;
|
||||
count += std::tuple_size_v<point_cloud_vertex_components::color>;
|
||||
}
|
||||
|
||||
if (Reflectance)
|
||||
{
|
||||
count += std::tuple_size_v<components::point_cloud_vertex::reflectance>;
|
||||
count += std::tuple_size_v<point_cloud_vertex_components::reflectance>;
|
||||
}
|
||||
|
||||
return count;
|
||||
@@ -293,7 +293,7 @@ std::error_code generic_3dtk_loader<Normal, Color, Reflectance>::read_point_file
|
||||
{
|
||||
auto line_view = std::string_view{ line };
|
||||
|
||||
components::point_cloud_vertex::position position;
|
||||
point_cloud_vertex_components::position position;
|
||||
if ((error = read_vector(line_view, position)))
|
||||
{
|
||||
return error;
|
||||
@@ -302,7 +302,7 @@ std::error_code generic_3dtk_loader<Normal, Color, Reflectance>::read_point_file
|
||||
|
||||
if constexpr (Normal)
|
||||
{
|
||||
components::point_cloud_vertex::normal normal;
|
||||
point_cloud_vertex_components::normal normal;
|
||||
if ((error = read_vector(line_view, normal)))
|
||||
{
|
||||
return error;
|
||||
@@ -312,7 +312,7 @@ std::error_code generic_3dtk_loader<Normal, Color, Reflectance>::read_point_file
|
||||
|
||||
if constexpr (Color)
|
||||
{
|
||||
components::point_cloud_vertex::color color;
|
||||
point_cloud_vertex_components::color color;
|
||||
if ((error = read_vector(line_view, color)))
|
||||
{
|
||||
return error;
|
||||
@@ -322,7 +322,7 @@ std::error_code generic_3dtk_loader<Normal, Color, Reflectance>::read_point_file
|
||||
|
||||
if constexpr (Reflectance)
|
||||
{
|
||||
components::point_cloud_vertex::reflectance reflectance;
|
||||
point_cloud_vertex_components::reflectance reflectance;
|
||||
if ((error = read_vector(line_view, reflectance)))
|
||||
{
|
||||
return error;
|
||||
@@ -431,7 +431,7 @@ std::error_code base_3dtk_loader::analyze_component_format(
|
||||
|
||||
|
||||
void base_3dtk_loader::transform_point_cloud(
|
||||
std::span<components::point_cloud_vertex::position::value_type> points,
|
||||
std::span<point_cloud_vertex_components::position::value_type> points,
|
||||
const glm::mat4& pose
|
||||
) {
|
||||
for (auto& [ x, y, z ] : points) {
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "assets/data_loaders/glsl_loader.hpp"
|
||||
#include "../../../include/assets/data_parsers"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "assets/data_loaders/kitti_loader.hpp"
|
||||
#include "../../../include/assets/data_parsers"
|
||||
|
||||
#include "glm/glm.hpp"
|
||||
|
||||
@@ -226,7 +226,7 @@ std::error_code kitti_loader::load(
|
||||
}
|
||||
|
||||
void kitti_loader::transform_point_cloud(
|
||||
std::span<components::point_cloud_vertex::position> points,
|
||||
std::span<point_cloud_vertex_components::position> points,
|
||||
const glm::mat4& pose
|
||||
) {
|
||||
for (auto& [ x, y, z ] : points) {
|
||||
@@ -266,7 +266,7 @@ std::error_code kitti_loader::load_point_file(
|
||||
return {};
|
||||
};
|
||||
|
||||
components::point_cloud_vertex::position position;
|
||||
point_cloud_vertex_components::position position;
|
||||
|
||||
auto& positions = point_cloud.positions();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "assets/data_loaders/kitti_pose_loader.hpp"
|
||||
#include "../../../include/assets/data_parsers"
|
||||
|
||||
#include "assets/dynamic_read_buffers/dynamic_pose_buffer.hpp"
|
||||
#include "../../../include/assets/read_buffers"
|
||||
#include <fstream>
|
||||
#include <glm/ext/matrix_transform.hpp>
|
||||
#include "util/logger.hpp"
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "assets/data_loaders/mtl_loader.hpp"
|
||||
#include "../../../include/assets/data_parsers"
|
||||
|
||||
#include <charconv>
|
||||
#include <fstream>
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "util/for_each.hpp"
|
||||
#include "util/line_parser.hpp"
|
||||
|
||||
#include "assets/dynamic_data_loaders/dynamic_texture_loader.hpp"
|
||||
#include "../../../include/assets/data_loaders"
|
||||
|
||||
namespace mtl_loader_error
|
||||
{
|
||||
@@ -290,7 +290,7 @@ std::error_code mtl_loader::prefetch(
|
||||
std::error_code mtl_loader::load_directory(
|
||||
dynamic_data_loader_ctx& ctx,
|
||||
dynamic_material_store& store,
|
||||
components::material::flags enabled_components,
|
||||
material_components::flags enabled_components,
|
||||
const std::filesystem::path& path,
|
||||
const bool pedantic
|
||||
) {
|
||||
@@ -332,16 +332,16 @@ std::error_code mtl_loader::load_directory(
|
||||
std::error_code mtl_loader::load(
|
||||
dynamic_data_loader_ctx& ctx,
|
||||
dynamic_material_store& store,
|
||||
components::material::flags enabled_components,
|
||||
material_components::flags enabled_components,
|
||||
const std::filesystem::path& filename,
|
||||
const bool pedantic
|
||||
) {
|
||||
using mtl_loader_error::codes;
|
||||
using mtl_loader_error::make_error_code;
|
||||
|
||||
using flags = components::material::flags;
|
||||
using flags = material_components::flags;
|
||||
|
||||
const auto component_disabled = [&](const components::material::flags component) {
|
||||
const auto component_disabled = [&](const material_components::flags component) {
|
||||
return (enabled_components & component) == flags::none;
|
||||
};
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#include "assets/data_loaders/obj_loader.hpp"
|
||||
#include "../../../include/assets/data_parsers"
|
||||
|
||||
#include <charconv>
|
||||
#include <fstream>
|
||||
#include <array>
|
||||
|
||||
#include "assets/components/mesh_vertex_components.hpp"
|
||||
#include "assets/dynamic_data_loaders/dynamic_material_loader.hpp"
|
||||
#include "../../../include/assets/data_loaders"
|
||||
|
||||
#include "util/logger.hpp"
|
||||
#include "util/for_each.hpp"
|
||||
@@ -397,7 +397,7 @@ std::error_code obj_loader::parse_file(
|
||||
pedantic,
|
||||
make_line_parser("v ", ztu::is_repeating, [&](const auto& param)
|
||||
{
|
||||
components::mesh_vertex::position position;
|
||||
mesh_vertex_components::position position;
|
||||
if (parse_numeric_vector(param, position) != std::errc{}) [[unlikely]]
|
||||
{
|
||||
return codes::malformed_vertex;
|
||||
@@ -409,7 +409,7 @@ std::error_code obj_loader::parse_file(
|
||||
}),
|
||||
make_line_parser("vt ", ztu::is_repeating, [&](const auto& param)
|
||||
{
|
||||
components::mesh_vertex::tex_coord coord;
|
||||
mesh_vertex_components::tex_coord coord;
|
||||
if (parse_numeric_vector(param, coord) != std::errc{}) [[unlikely]]
|
||||
{
|
||||
return codes::malformed_texture_coordinate;
|
||||
@@ -421,7 +421,7 @@ std::error_code obj_loader::parse_file(
|
||||
}),
|
||||
make_line_parser("vn ", ztu::is_repeating, [&](const auto& param)
|
||||
{
|
||||
components::mesh_vertex::normal normal;
|
||||
mesh_vertex_components::normal normal;
|
||||
if (parse_numeric_vector(param, normal) != std::errc{}) [[unlikely]]
|
||||
{
|
||||
return codes::malformed_normal;
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "assets/data_loaders/stl_loader.hpp"
|
||||
#include "../../../include/assets/data_parsers"
|
||||
|
||||
#include "util/binary_ifstream.hpp"
|
||||
#include "util/unroll_bool_template.hpp"
|
||||
@@ -8,8 +8,8 @@ template<bool Normals>
|
||||
std::error_code read_body(
|
||||
binary_ifstream& in,
|
||||
const std::uint32_t expected_triangle_count,
|
||||
std::vector<components::mesh_vertex::position>& positions,
|
||||
std::vector<components::mesh_vertex::normal>& normals,
|
||||
std::vector<mesh_vertex_components::position>& positions,
|
||||
std::vector<mesh_vertex_components::normal>& normals,
|
||||
std::vector<std::array<ztu::u32, 3>>& triangles
|
||||
) {
|
||||
|
||||
@@ -29,7 +29,7 @@ std::error_code read_body(
|
||||
|
||||
for (std::uint32_t i{}; i != expected_triangle_count; ++i) {
|
||||
|
||||
auto normal = components::mesh_vertex::normal{};
|
||||
auto normal = mesh_vertex_components::normal{};
|
||||
if constexpr (Normals)
|
||||
{
|
||||
if (const auto e = read_vector(normal))
|
||||
@@ -42,7 +42,7 @@ std::error_code read_body(
|
||||
|
||||
for (auto& index : triangle) {
|
||||
|
||||
auto position = components::mesh_vertex::position{};
|
||||
auto position = mesh_vertex_components::position{};
|
||||
if (const auto e = read_vector(position))
|
||||
{
|
||||
return e;
|
||||
@@ -92,7 +92,7 @@ std::error_code read_body(
|
||||
std::error_code stl_loader::read_directory(
|
||||
const std::filesystem::path& path,
|
||||
std::vector<dynamic_mesh_data>& meshes,
|
||||
components::mesh_vertex::flags enabled_components::mesh_vertexs,
|
||||
mesh_vertex_components::flags enabled_mesh_vertex_componentss,
|
||||
std::vector<dynamic_material_data>& materials,
|
||||
material_component::flags enabled_material_components,
|
||||
const ztu::u32 base_material_id,
|
||||
@@ -116,7 +116,7 @@ std::error_code stl_loader::read_directory(
|
||||
if (const auto e = read(
|
||||
file_path,
|
||||
meshes,
|
||||
enabled_components::mesh_vertexs,
|
||||
enabled_mesh_vertex_componentss,
|
||||
materials,
|
||||
enabled_material_components,
|
||||
base_material_id,
|
||||
@@ -138,7 +138,7 @@ std::error_code stl_loader::read_directory(
|
||||
std::error_code stl_loader::read(
|
||||
const std::filesystem::path& filename,
|
||||
std::vector<dynamic_mesh_data>& meshes,
|
||||
components::mesh_vertex::flags enabled_components::mesh_vertexs,
|
||||
mesh_vertex_components::flags enabled_mesh_vertex_componentss,
|
||||
std::vector<dynamic_material_data>&,
|
||||
material_component::flags,
|
||||
ztu::u32,
|
||||
@@ -212,7 +212,7 @@ std::error_code stl_loader::read(
|
||||
triangles.reserve(expected_triangle_count);
|
||||
|
||||
const auto normals_enabled = (
|
||||
(enabled_components::mesh_vertexs & components::mesh_vertex::flags::normal) != components::mesh_vertex::flags::none
|
||||
(enabled_mesh_vertex_componentss & mesh_vertex_components::flags::normal) != mesh_vertex_components::flags::none
|
||||
);
|
||||
|
||||
error = unroll_bool_function_template([&]<bool Normals>() {
|
||||
@@ -238,13 +238,13 @@ std::error_code stl_loader::read(
|
||||
|
||||
if (not positions.empty())
|
||||
{
|
||||
mesh.components() |= components::mesh_vertex::flags::position;
|
||||
mesh.components() |= mesh_vertex_components::flags::position;
|
||||
}
|
||||
|
||||
if (not normals.empty())
|
||||
{
|
||||
ztu::logger::debug("Enabling normals!!!");
|
||||
mesh.components() |= components::mesh_vertex::flags::normal;
|
||||
mesh.components() |= mesh_vertex_components::flags::normal;
|
||||
}
|
||||
|
||||
meshes.emplace_back(std::move(mesh));
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "assets/data_loaders/threedtk_pose_loader.hpp"
|
||||
#include "../../../include/assets/data_parsers"
|
||||
|
||||
#include "assets/dynamic_read_buffers/dynamic_pose_buffer.hpp"
|
||||
#include "../../../include/assets/read_buffers"
|
||||
|
||||
#include <fstream>
|
||||
#include <glm/ext/matrix_transform.hpp>
|
||||
@@ -4,9 +4,9 @@
|
||||
#include <algorithm>
|
||||
|
||||
void estimate_normals(
|
||||
std::span<const components::mesh_vertex::position> vertices,
|
||||
std::span<const mesh_vertex_components::position> vertices,
|
||||
std::span<const std::array<ztu::u32, 3>> triangles,
|
||||
std::vector<components::mesh_vertex::normal>& normals
|
||||
std::vector<mesh_vertex_components::normal>& normals
|
||||
) {
|
||||
|
||||
normals.resize(vertices.size());
|
||||
@@ -59,7 +59,7 @@ void estimate_normals(
|
||||
}
|
||||
}
|
||||
|
||||
using normal_component_type = components::mesh_vertex::normal::component_type;
|
||||
using normal_component_type = mesh_vertex_components::normal::component_type;
|
||||
constexpr auto epsilon = std::numeric_limits<normal_component_type>::epsilon();
|
||||
|
||||
for (auto& [ x, y, z ] : normals)
|
||||
|
||||
@@ -15,7 +15,7 @@ std::error_code zgl::mesh_data::build_from(
|
||||
const GLsizei stride,
|
||||
const std::span<const ztu::u32> index_buffer,
|
||||
const ztu::u32 material_id,
|
||||
const components::mesh_vertex::flags components,
|
||||
const mesh_vertex_components::flags components,
|
||||
mesh_data& data
|
||||
) {
|
||||
if (not std::ranges::all_of(component_types, type_utils::is_valid_type))
|
||||
|
||||
@@ -9,7 +9,7 @@ inline mesh_data::mesh_data(
|
||||
const GLuint index_vbo_id,
|
||||
const GLuint vao_id,
|
||||
const ztu::u32 material_id,
|
||||
const components::mesh_vertex::flags components,
|
||||
const mesh_vertex_components::flags components,
|
||||
const GLsizei index_count
|
||||
) :
|
||||
m_handle{
|
||||
@@ -38,7 +38,7 @@ inline mesh_data& mesh_data::operator=(mesh_data&& other) noexcept
|
||||
other.m_vertex_vbo_id = 0;
|
||||
other.m_index_vbo_id = 0;
|
||||
other.m_material_id = 0;
|
||||
other.m_component_types = components::mesh_vertex::flags::none;
|
||||
other.m_component_types = mesh_vertex_components::flags::none;
|
||||
}
|
||||
|
||||
return *this;
|
||||
@@ -56,7 +56,7 @@ inline mesh_data::mesh_data(mesh_data&& other) noexcept :
|
||||
other.m_vertex_vbo_id = 0;
|
||||
other.m_index_vbo_id = 0;
|
||||
other.m_material_id = 0;
|
||||
other.m_component_types = components::mesh_vertex::flags::none;
|
||||
other.m_component_types = mesh_vertex_components::flags::none;
|
||||
}
|
||||
|
||||
inline mesh_data::~mesh_data() {
|
||||
@@ -77,7 +77,7 @@ inline mesh_handle mesh_data::handle() const
|
||||
return m_handle;
|
||||
}
|
||||
|
||||
inline components::mesh_vertex::flags mesh_data::components() const
|
||||
inline mesh_vertex_components::flags mesh_data::components() const
|
||||
{
|
||||
return m_component_types;
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ inline point_cloud_handle point_cloud_data::handle() const
|
||||
return m_handle;
|
||||
}
|
||||
|
||||
inline components::point_cloud_vertex::flags point_cloud_data::components() const
|
||||
inline point_cloud_vertex_components::flags point_cloud_data::components() const
|
||||
{
|
||||
return m_component_types;
|
||||
}
|
||||
|
||||
106
source/opengl/data_managers/mesh_index_buffer_manager.cpp
Normal file
106
source/opengl/data_managers/mesh_index_buffer_manager.cpp
Normal file
@@ -0,0 +1,106 @@
|
||||
#include "opengl/data_managers/mesh_index_buffer_manager.hpp"
|
||||
|
||||
#include "util/logger.hpp"
|
||||
#include "opengl/error.hpp"
|
||||
#include "opengl/type_utils.hpp"
|
||||
|
||||
void zgl::mesh_index_buffer_manager::process(store_type& store)
|
||||
{
|
||||
for (const auto& [ id, mesh ] : store)
|
||||
{
|
||||
if (not m_resource_manager.has_resource(id))
|
||||
{
|
||||
m_mesh_buffer.emplace_back(id, mesh);
|
||||
}
|
||||
}
|
||||
|
||||
m_buffer_id_buffer.resize(m_mesh_buffer.size());
|
||||
|
||||
glGenBuffers(m_buffer_id_buffer.size(), m_buffer_id_buffer.data());
|
||||
if (const auto e = get_error())
|
||||
{
|
||||
ztu::logger::error("Error while creating % index buffers: %.", m_buffer_id_buffer.size(), e.message());
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto [ entry, buffer_id ] : std::ranges::views::zip(m_mesh_buffer, m_buffer_id_buffer))
|
||||
{
|
||||
auto [ store_id, mesh ] = entry;
|
||||
|
||||
const auto& [ components, indices, buffers ] = mesh;
|
||||
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer_id);
|
||||
if (const auto e = get_error())
|
||||
{
|
||||
ztu::logger::error("Error while binding index buffer %: %.", buffer_id, e.message());
|
||||
continue;
|
||||
}
|
||||
|
||||
glBufferData(
|
||||
GL_ELEMENT_ARRAY_BUFFER,
|
||||
static_cast<GLsizeiptr>(indices.size_bytes()), // TODO check count
|
||||
indices.data(),
|
||||
GL_STATIC_DRAW
|
||||
);
|
||||
if (const auto e = get_error())
|
||||
{
|
||||
ztu::logger::error("Error while setting index buffer data: %.", e.message());
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto meta = index_buffer_metadata{
|
||||
.count = static_cast<GLsizei>(indices.size()), // TODO check count
|
||||
.index_type = type_utils::to_gl_type<decltype(indices)::value_type>()
|
||||
};
|
||||
m_resource_manager.add_resource(store_id, buffer_id, meta);
|
||||
|
||||
buffer_id = {};
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
|
||||
const auto valid_buffer_ids = std::ranges::remove(
|
||||
m_buffer_id_buffer,
|
||||
0
|
||||
);
|
||||
|
||||
const auto invalid_buffer_count = m_buffer_id_buffer.size() - valid_buffer_ids.size();
|
||||
|
||||
glDeleteBuffers(
|
||||
invalid_buffer_count,
|
||||
m_buffer_id_buffer.data()
|
||||
);
|
||||
if (const auto e = get_error())
|
||||
{
|
||||
ztu::logger::error("Error while deleting % buffers: %.", invalid_buffer_count, e.message());
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<zgl::mesh_index_buffer_manager::handle_type> zgl::mesh_index_buffer_manager::get_handle(
|
||||
const store_id_type id
|
||||
) {
|
||||
return m_resource_manager
|
||||
.get_resource(id)
|
||||
.transform(
|
||||
[](auto& resource)
|
||||
{
|
||||
return *reinterpret_cast<handle_type*>(resource);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void zgl::mesh_index_buffer_manager::collect_garbage(const bool force)
|
||||
{
|
||||
m_resource_manager.collect_garbage();
|
||||
if (force or m_resource_manager.count_garbage() >= min_garbage_collection_count)
|
||||
{
|
||||
m_buffer_id_buffer.clear();
|
||||
m_resource_manager.extract_garbage(m_buffer_id_buffer);
|
||||
glDeleteBuffers(
|
||||
m_buffer_id_buffer.size(),
|
||||
m_buffer_id_buffer.data()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,133 +1,115 @@
|
||||
#include "opengl/data_managers/mesh_vertex_buffer_manager.hpp"
|
||||
|
||||
#include "util/logger.hpp"
|
||||
#include "opengl/error.hpp"
|
||||
#include "opengl/vertex_buffer_utils.hpp"
|
||||
|
||||
|
||||
void zgl::mesh_vertex_buffer_manager::process(store_type& store)
|
||||
{
|
||||
for (const auto& [ id, mesh ] : store)
|
||||
{
|
||||
// The ireator must reutrn a pair containing the components and a tuple of spans
|
||||
if (not m_resource_manager.has_resource(id))
|
||||
{
|
||||
m_mesh_buffer.emplace_back(id, mesh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
void dynamic_vertex_buffer<C, Ts...>::build_vertex_buffer(
|
||||
std::vector<ztu::u8>& vertex_buffer,
|
||||
std::size_t& component_count,
|
||||
std::array<GLenum, sizeof...(Ts)>& component_types,
|
||||
std::array<GLint, sizeof...(Ts)>& component_lengths,
|
||||
GLsizei& stride
|
||||
) const {
|
||||
const auto for_all_components = [&]<typename T>(auto&& f, const T default_value)
|
||||
m_buffer_id_buffer.resize(m_mesh_buffer.size());
|
||||
|
||||
glGenBuffers(m_buffer_id_buffer.size(), m_buffer_id_buffer.data());
|
||||
if (const auto e = get_error())
|
||||
{
|
||||
return std::apply(
|
||||
[&](const auto&... component_buffer)
|
||||
ztu::logger::error("Error while creating % vertex buffers: %.", m_buffer_id_buffer.size(), e.message());
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto [ entry, buffer_id ] : std::ranges::views::zip(m_mesh_buffer, m_buffer_id_buffer))
|
||||
{
|
||||
auto [ store_id, mesh ] = entry;
|
||||
|
||||
m_byte_buffer.clear();
|
||||
|
||||
std::apply(
|
||||
[&](const auto&... component_buffers)
|
||||
{
|
||||
std::array<T, sizeof...(component_buffer)> results{};
|
||||
auto i = std::size_t{};
|
||||
(
|
||||
(
|
||||
results[i] = [&](const auto& buffer, const auto index) -> T
|
||||
{
|
||||
if ((m_components & C{ 1 << index }) != C{})
|
||||
{
|
||||
return f(buffer, index);
|
||||
}
|
||||
return default_value;
|
||||
}(component_buffer, i),
|
||||
++i
|
||||
),
|
||||
...
|
||||
);
|
||||
return results;
|
||||
vertex_buffer_utils::interlace(m_byte_buffer, mesh.component_flags, component_buffers...);
|
||||
},
|
||||
m_component_buffers
|
||||
mesh.vertex_component_arrays
|
||||
);
|
||||
};
|
||||
|
||||
component_count = 0;
|
||||
component_types = for_all_components(
|
||||
ztu::specialised_lambda
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buffer_id);
|
||||
if (const auto e = get_error())
|
||||
{
|
||||
[&component_count]<numeric_type Component, std::size_t Count>(const std::vector<std::array<Component, Count>>&, std::size_t)
|
||||
{
|
||||
++component_count;
|
||||
return zgl::type_utils::to_gl_type<Component>();
|
||||
},
|
||||
[&component_count]<numeric_type Component>(const std::vector<Component>&, std::size_t)
|
||||
{
|
||||
++component_count;
|
||||
return zgl::type_utils::to_gl_type<Component>();
|
||||
}
|
||||
},
|
||||
GLenum{ GL_INVALID_VALUE }
|
||||
);
|
||||
ztu::logger::error("Error while binding vertex buffer %: %.", buffer_id, e.message());
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto element_counts = for_all_components(
|
||||
[]<class Component>(const std::vector<Component>& buffer, std::size_t)
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER,
|
||||
static_cast<GLsizeiptr>(m_byte_buffer.size()),
|
||||
m_byte_buffer.data(),
|
||||
GL_STATIC_DRAW
|
||||
);
|
||||
if (const auto e = get_error())
|
||||
{
|
||||
return buffer.size();
|
||||
},
|
||||
std::numeric_limits<std::size_t>::max()
|
||||
);
|
||||
ztu::logger::error("Error while setting vertex buffer data: %.", e.message());
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto minimum_element_count = std::ranges::min(element_counts);
|
||||
const auto meta = mesh_vertex_buffer_metadata{
|
||||
.component_flags = mesh.component_flags,
|
||||
.material_id = mesh.material_id
|
||||
};
|
||||
|
||||
component_lengths = for_all_components(
|
||||
ztu::specialised_lambda
|
||||
{
|
||||
[]<class Component>(const std::vector<Component>&, std::size_t)
|
||||
{
|
||||
return 1;
|
||||
},
|
||||
[]<class Component, std::size_t Count>(const std::vector<std::array<Component, Count>>&, std::size_t)
|
||||
{
|
||||
return Count;
|
||||
}
|
||||
},
|
||||
GLsizei{ 0 }
|
||||
);
|
||||
m_resource_manager.add_resource(store_id, buffer_id, meta);
|
||||
|
||||
auto component_sizes = std::array<GLsizei, sizeof...(Ts)>{};
|
||||
for (std::size_t i{}; i != component_sizes.size(); ++i)
|
||||
{
|
||||
component_sizes[i] = component_lengths[i] * zgl::type_utils::size_of(component_types[i]);
|
||||
buffer_id = {};
|
||||
}
|
||||
|
||||
const auto total_size = minimum_element_count * std::accumulate(
|
||||
component_sizes.begin(),
|
||||
component_sizes.end(),
|
||||
GLsizei{ 0 }
|
||||
);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
vertex_buffer.resize(total_size);
|
||||
|
||||
// Calculate offsets and stride
|
||||
auto component_offsets = component_sizes;
|
||||
stride = 0;
|
||||
for (std::size_t i{}; i != component_offsets.size(); ++i) {
|
||||
component_offsets[i] = stride;
|
||||
stride += component_sizes[i];
|
||||
}
|
||||
|
||||
// Copy all the components over one by one
|
||||
for_all_components(
|
||||
[&]<class Component>(const std::vector<Component>& buffer, std::size_t index)
|
||||
{
|
||||
std::size_t pos = component_offsets[index];
|
||||
for (std::size_t i{}; i != minimum_element_count; ++i)
|
||||
{
|
||||
std::memcpy(
|
||||
&vertex_buffer[pos],
|
||||
buffer[i].data(),
|
||||
component_sizes[index]
|
||||
);
|
||||
pos += stride;
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
const auto valid_buffer_ids = std::ranges::remove(
|
||||
m_buffer_id_buffer,
|
||||
0
|
||||
);
|
||||
|
||||
// remove values of unused components
|
||||
std::ignore = std::ranges::remove(component_lengths, 0);
|
||||
std::ignore = std::ranges::remove(component_types, GL_INVALID_VALUE);
|
||||
const auto invalid_buffer_count = m_buffer_id_buffer.size() - valid_buffer_ids.size();
|
||||
|
||||
glDeleteBuffers(
|
||||
invalid_buffer_count,
|
||||
m_buffer_id_buffer.data()
|
||||
);
|
||||
if (const auto e = get_error())
|
||||
{
|
||||
ztu::logger::error("Error while deleting % buffers: %.", invalid_buffer_count, e.message());
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<zgl::mesh_vertex_buffer_manager::handle_type> zgl::mesh_vertex_buffer_manager::get_handle(
|
||||
const store_id_type id
|
||||
) {
|
||||
return m_resource_manager
|
||||
.get_resource(id)
|
||||
.transform(
|
||||
[](auto& resource)
|
||||
{
|
||||
return *reinterpret_cast<handle_type*>(resource);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void zgl::mesh_vertex_buffer_manager::collect_garbage(const bool force)
|
||||
{
|
||||
m_resource_manager.collect_garbage();
|
||||
if (force or m_resource_manager.count_garbage() >= min_garbage_collection_count)
|
||||
{
|
||||
m_buffer_id_buffer.clear();
|
||||
m_resource_manager.extract_garbage(m_buffer_id_buffer);
|
||||
glDeleteBuffers(
|
||||
m_buffer_id_buffer.size(),
|
||||
m_buffer_id_buffer.data()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
#include "opengl/data_managers/point_cloud_vertex_buffer_manager.hpp"
|
||||
|
||||
#include "util/logger.hpp"
|
||||
#include "opengl/error.hpp"
|
||||
#include "opengl/vertex_buffer_utils.hpp"
|
||||
|
||||
|
||||
void zgl::point_cloud_vertex_buffer_manager::process(store_type& store)
|
||||
{
|
||||
for (const auto& [ id, point_cloud ] : store)
|
||||
{
|
||||
if (not m_resource_manager.has_resource(id))
|
||||
{
|
||||
m_point_cloud_buffer.emplace_back(id, point_cloud);
|
||||
}
|
||||
}
|
||||
|
||||
m_buffer_id_buffer.resize(m_point_cloud_buffer.size());
|
||||
|
||||
glGenBuffers(m_buffer_id_buffer.size(), m_buffer_id_buffer.data());
|
||||
if (const auto e = get_error())
|
||||
{
|
||||
ztu::logger::error("Error while creating % vertex buffers: %.", m_buffer_id_buffer.size(), e.message());
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto [ entry, buffer_id ] : std::ranges::views::zip(m_point_cloud_buffer, m_buffer_id_buffer))
|
||||
{
|
||||
auto [ store_id, point_cloud ] = entry;
|
||||
|
||||
const auto& [ components, buffers ] = point_cloud;
|
||||
|
||||
m_byte_buffer.clear();
|
||||
|
||||
const auto meta = std::apply(
|
||||
[&](const auto&... component_buffers)
|
||||
{
|
||||
vertex_buffer_utils::interlace(m_byte_buffer, components, component_buffers...);
|
||||
return vertex_buffer_utils::generate_metadata(components, component_buffers...);
|
||||
},
|
||||
buffers
|
||||
);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buffer_id);
|
||||
if (const auto e = get_error())
|
||||
{
|
||||
ztu::logger::error("Error while binding vertex buffer %: %.", buffer_id, e.message());
|
||||
continue;
|
||||
}
|
||||
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER,
|
||||
static_cast<GLsizeiptr>(m_byte_buffer.size()),
|
||||
m_byte_buffer.data(),
|
||||
GL_STATIC_DRAW
|
||||
);
|
||||
if (const auto e = get_error())
|
||||
{
|
||||
ztu::logger::error("Error while setting vertex buffer data: %.", e.message());
|
||||
continue;
|
||||
}
|
||||
|
||||
m_resource_manager.add_resource(store_id, buffer_id, meta);
|
||||
|
||||
buffer_id = {};
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
const auto valid_buffer_ids = std::ranges::remove(
|
||||
m_buffer_id_buffer,
|
||||
0
|
||||
);
|
||||
|
||||
const auto invalid_buffer_count = m_buffer_id_buffer.size() - valid_buffer_ids.size();
|
||||
|
||||
glDeleteBuffers(
|
||||
invalid_buffer_count,
|
||||
m_buffer_id_buffer.data()
|
||||
);
|
||||
if (const auto e = get_error())
|
||||
{
|
||||
ztu::logger::error("Error while deleting % buffers: %.", invalid_buffer_count, e.message());
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<zgl::point_cloud_vertex_buffer_manager::handle_type> zgl::point_cloud_vertex_buffer_manager::get_handle(
|
||||
const store_id_type id
|
||||
) {
|
||||
return m_resource_manager
|
||||
.get_resource(id)
|
||||
.transform(
|
||||
[](auto& resource)
|
||||
{
|
||||
return *reinterpret_cast<handle_type*>(resource);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void zgl::point_cloud_vertex_buffer_manager::collect_garbage(const bool force)
|
||||
{
|
||||
m_resource_manager.collect_garbage();
|
||||
if (force or m_resource_manager.count_garbage() >= min_garbage_collection_count)
|
||||
{
|
||||
m_buffer_id_buffer.clear();
|
||||
m_resource_manager.extract_garbage(m_buffer_id_buffer);
|
||||
glDeleteBuffers(
|
||||
m_buffer_id_buffer.size(),
|
||||
m_buffer_id_buffer.data()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -80,7 +80,7 @@ std::optional<std::pair<zgl::shader_metadata, zgl::shader_handle>> zgl::shader_m
|
||||
}
|
||||
|
||||
void zgl::shader_manager::get_handles(
|
||||
const dynamic_shader_source_store& shader_sources,
|
||||
const assets::shader_source_store& shader_sources,
|
||||
std::span<const shading::shader_set_requirements> requirements,
|
||||
std::span<shader_set_metadata> metadata,
|
||||
std::span<shader_handle_set> shader_sets
|
||||
@@ -258,7 +258,7 @@ bool zgl::shader_manager::compile_shader(
|
||||
}
|
||||
|
||||
void zgl::shader_manager::process(
|
||||
const dynamic_shader_source_store& shader_sources
|
||||
const assets::shader_source_store& shader_sources
|
||||
) {
|
||||
m_preprocessor.process(shader_sources);
|
||||
}
|
||||
@@ -25,13 +25,13 @@ struct prioritized_metadata_comparator
|
||||
};
|
||||
|
||||
void zgl::shader_program_manager::process(
|
||||
const dynamic_shader_source_store& shader_sources
|
||||
const assets::shader_source_store& shader_sources
|
||||
) {
|
||||
m_shader_manager.preprocess(shader_sources);
|
||||
}
|
||||
|
||||
void zgl::shader_program_manager::get_handles(
|
||||
const dynamic_shader_source_store& shader_sources,
|
||||
const assets::shader_source_store& shader_sources,
|
||||
std::span<const shading::shader_program_requirements> requirements,
|
||||
std::span<shader_program_metadata> metadata,
|
||||
std::span<shader_program_handle> shader_programs
|
||||
|
||||
@@ -77,7 +77,7 @@ private:
|
||||
|
||||
|
||||
void zgl::shader_source_manager::process(
|
||||
const dynamic_shader_source_store& shader_sources
|
||||
const assets::shader_source_store& shader_sources
|
||||
) {
|
||||
namespace language = shading::shader_metadata_language;
|
||||
|
||||
@@ -119,7 +119,7 @@ void zgl::shader_source_manager::process(
|
||||
}
|
||||
|
||||
void zgl::shader_source_manager::get_shader_sources(
|
||||
const dynamic_shader_source_store& shader_sources,
|
||||
const assets::shader_source_store& shader_sources,
|
||||
std::span<const shading::shader_source_requirements> requirements,
|
||||
std::span<preprocessed_shader_source_metadata> metadata,
|
||||
std::vector<const char*>& shader_strings
|
||||
@@ -152,7 +152,7 @@ void zgl::shader_source_manager::get_shader_sources(
|
||||
}
|
||||
);
|
||||
|
||||
dynamic_shader_source_store::id_type source_id{};
|
||||
assets::shader_source_store::id_type source_id{};
|
||||
shading::features::generic::type to_be_enabled{};
|
||||
|
||||
while (
|
||||
|
||||
@@ -33,7 +33,7 @@ void zgl::texture_manager::process(
|
||||
|
||||
GLenum format;
|
||||
switch (texture.components()) {
|
||||
using enum components::texture::flags;
|
||||
using enum texture_components::flags;
|
||||
case luminance:
|
||||
format = GL_LUMINANCE;
|
||||
break;
|
||||
@@ -56,7 +56,7 @@ void zgl::texture_manager::process(
|
||||
if (const auto e = get_error())
|
||||
{
|
||||
ztu::logger::error("Error while binding texture %: %.", texture_id, e.message());
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
|
||||
@@ -74,7 +74,7 @@ std::optional<mesh_batch_renderer::id_type> mesh_batch_renderer::add(
|
||||
|
||||
if (
|
||||
(
|
||||
requirement.vertex_requirements != components::mesh_vertex::flags::none and
|
||||
requirement.vertex_requirements != mesh_vertex_components::flags::none and
|
||||
(vertex_comps & requirement.vertex_requirements) == requirement.vertex_requirements
|
||||
)
|
||||
and
|
||||
@@ -271,7 +271,7 @@ void mesh_batch_renderer::render(
|
||||
const auto [ vertex_components, material_components ] = batch_components;
|
||||
|
||||
const auto textured = (
|
||||
(vertex_components & components::mesh_vertex::flags::tex_coord) != components::mesh_vertex::flags::none
|
||||
(vertex_components & mesh_vertex_components::flags::tex_coord) != mesh_vertex_components::flags::none
|
||||
and (material_components & material_component::flags::texture) != material_component::flags::none
|
||||
);
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ std::optional<point_cloud_batch_renderer::id_type> point_cloud_batch_renderer::a
|
||||
const auto& requirement = requirements::point_cloud::all[i];
|
||||
|
||||
if (
|
||||
(vertex_comps & requirement.vertex_requirements) != components::point_cloud_vertex::flags::none
|
||||
(vertex_comps & requirement.vertex_requirements) != point_cloud_vertex_components::flags::none
|
||||
) {
|
||||
base_requirements |= requirements::point_cloud::flags{ 1 << i };
|
||||
}
|
||||
@@ -208,7 +208,7 @@ void point_cloud_batch_renderer::render(
|
||||
|
||||
const auto& [ batch, vertex_components ] = m_batches[i];
|
||||
|
||||
const auto normals = static_cast<bool>(vertex_components & components::point_cloud_vertex::flags::normal);
|
||||
const auto normals = static_cast<bool>(vertex_components & point_cloud_vertex_components::flags::normal);
|
||||
|
||||
const auto& shader_program = m_shader_programs[i * m_render_mode_count + render_mode_index];
|
||||
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
namespace viewer
|
||||
{
|
||||
std::error_code asset_loader::init(
|
||||
components::mesh_vertex::flags enabled_mesh_components,
|
||||
mesh_vertex_components::flags enabled_mesh_components,
|
||||
material_component::flags enabled_material_components,
|
||||
components::point_cloud_vertex::flags enabled_point_cloud_components,
|
||||
point_cloud_vertex_components::flags enabled_point_cloud_components,
|
||||
const dynamic_material_data& default_material
|
||||
) {
|
||||
|
||||
@@ -393,8 +393,8 @@ std::error_code asset_loader::create_gl_materials()
|
||||
|
||||
void asset_loader::create_gl_meshes(std::span<const material_reference_entry_type> material_references)
|
||||
{
|
||||
auto component_type_buffer = std::array<GLenum, static_cast<std::size_t>(components::mesh_vertex::count)>{};
|
||||
auto component_length_buffer = std::array<GLint, static_cast<std::size_t>(components::mesh_vertex::count)>{};
|
||||
auto component_type_buffer = std::array<GLenum, static_cast<std::size_t>(mesh_vertex_components::count)>{};
|
||||
auto component_length_buffer = std::array<GLint, static_cast<std::size_t>(mesh_vertex_components::count)>{};
|
||||
|
||||
auto component_stride = GLsizei{};
|
||||
auto component_count = ztu::u32{};
|
||||
@@ -430,7 +430,7 @@ void asset_loader::create_gl_meshes(std::span<const material_reference_entry_typ
|
||||
}
|
||||
|
||||
// Add normals if missing
|
||||
if ((mesh_data.components() & components::mesh_vertex::flags::normal) == components::mesh_vertex::flags::none)
|
||||
if ((mesh_data.components() & mesh_vertex_components::flags::normal) == mesh_vertex_components::flags::none)
|
||||
{
|
||||
ztu::logger::warn("Model is missing normal vectors, so they are estimated!");
|
||||
estimate_normals(
|
||||
@@ -438,11 +438,11 @@ void asset_loader::create_gl_meshes(std::span<const material_reference_entry_typ
|
||||
mesh_data.triangles(),
|
||||
mesh_data.normals()
|
||||
);
|
||||
mesh_data.components() |= components::mesh_vertex::flags::normal;
|
||||
mesh_data.components() |= mesh_vertex_components::flags::normal;
|
||||
}
|
||||
|
||||
auto mesh_box = aabb{};
|
||||
mesh_box.add_points<components::mesh_vertex::normal::value_type>(mesh_data.positions());
|
||||
mesh_box.add_points<mesh_vertex_components::normal::value_type>(mesh_data.positions());
|
||||
|
||||
mesh_data.build_vertex_buffer(
|
||||
m_vertex_buffer,
|
||||
@@ -488,8 +488,8 @@ void asset_loader::create_gl_meshes(std::span<const material_reference_entry_typ
|
||||
|
||||
void asset_loader::create_gl_point_clouds()
|
||||
{
|
||||
auto component_type_buffer = std::array<GLenum, static_cast<std::size_t>(components::point_cloud_vertex::count)>{};
|
||||
auto component_length_buffer = std::array<GLint, static_cast<std::size_t>(components::point_cloud_vertex::count)>{};
|
||||
auto component_type_buffer = std::array<GLenum, static_cast<std::size_t>(point_cloud_vertex_components::count)>{};
|
||||
auto component_length_buffer = std::array<GLint, static_cast<std::size_t>(point_cloud_vertex_components::count)>{};
|
||||
auto component_stride = GLsizei{};
|
||||
auto component_count = ztu::u32{};
|
||||
|
||||
@@ -502,7 +502,7 @@ void asset_loader::create_gl_point_clouds()
|
||||
}
|
||||
|
||||
auto point_cloud_box = aabb{};
|
||||
point_cloud_box.add_points<components::mesh_vertex::normal::value_type>(point_cloud_data.positions());
|
||||
point_cloud_box.add_points<mesh_vertex_components::normal::value_type>(point_cloud_data.positions());
|
||||
|
||||
point_cloud_data.build_vertex_buffer(
|
||||
m_vertex_buffer,
|
||||
|
||||
@@ -83,7 +83,7 @@ void instance::set_background_color(const glm::vec4& color)
|
||||
std::optional<instance::asset_id> instance::add_mesh(
|
||||
const zgl::mesh_handle& mesh,
|
||||
const aabb& bounding_box,
|
||||
const components::mesh_vertex::flags mesh_components,
|
||||
const mesh_vertex_components::flags mesh_components,
|
||||
const zgl::material_handle& material,
|
||||
const material_component::flags material_components
|
||||
) {
|
||||
@@ -107,7 +107,7 @@ std::optional<instance::asset_id> instance::add_mesh(
|
||||
std::optional<instance::asset_id> instance::add_point_cloud(
|
||||
const zgl::point_cloud_handle& point_cloud,
|
||||
const aabb& bounding_box,
|
||||
const components::point_cloud_vertex::flags point_cloud_components
|
||||
const point_cloud_vertex_components::flags point_cloud_components
|
||||
) {
|
||||
const auto point_cloud_id = m_point_cloud_renderer.add(
|
||||
point_cloud_components,
|
||||
|
||||
Reference in New Issue
Block a user