Made assets::data_stores thread safe.

This commit is contained in:
zy4n
2025-03-31 20:13:26 +02:00
parent 144126ee7a
commit 0acfe36118
39 changed files with 1772 additions and 1069 deletions

View File

@@ -128,7 +128,7 @@ add_executable(z3d main.cpp
include/assets/data/generic/component_array_set.hpp
source/assets/data/texture_data.ipp
source/assets/data/point_cloud_data.ipp
include/assets/file_parsers/mtl_loader.hpp
include/assets/file_parsers/mtl_parser.hpp
include/assets/data_loaders/material_loader.hpp
include/util/id_type.hpp
include/assets/data_stores/generic/generic_basic_store.hpp
@@ -137,7 +137,7 @@ add_executable(z3d main.cpp
include/assets/data_stores/mesh_store.hpp
include/assets/data_stores/point_cloud_store.hpp
include/util/result.hpp
source/assets/file_parsers/mtl_loader.cpp
source/assets/file_parsers/mtl_parser.cpp
include/util/line_parser.hpp
include/assets/data_loaders/texture_loader.hpp
source/assets/data_loaders/texture_loader.cpp
@@ -247,6 +247,7 @@ add_executable(z3d main.cpp
include/assets/data/pose_list_data.hpp
include/assets/data_stores/pose_list_store.hpp
include/assets/data_views/pose_list_view.hpp
include/util/vector_replace_range.hpp
)
target_include_directories(z3d PRIVATE include)

View File

@@ -10,6 +10,8 @@ namespace assets::mesh_vertex_components
using position = z3d::vec3;
using normal = z3d::vec3;
using tangent = z3d::vec3;
using bi_tangent = z3d::vec3;
using tex_coord = z3d::vec2;
using color = z3d::vec3;
using reflectance = z3d::f32;
@@ -20,6 +22,8 @@ enum : z3d::size
{
position,
normal,
tangent,
bi_tangent,
tex_coord,
color,
reflectance
@@ -31,6 +35,8 @@ enum class flags : z3d::u8
none = 0,
position = 1 << indices::position,
normal = 1 << indices::normal,
tangent = 1 << indices::tangent,
bi_tangent = 1 << indices::bi_tangent,
tex_coord = 1 << indices::tex_coord,
color = 1 << indices::color,
reflectance = 1 << indices::reflectance

View File

@@ -4,16 +4,19 @@
namespace assets::detail {
template<typename T>
template<typename C, typename T>
class component_set {};
template<typename... Ts>
class component_set<z3d::structure<Ts...>>
template<typename C, typename... Ts>
class component_set<C, z3d::structure<Ts...>>
{
public:
component_set() = default;
C component_flags{};
z3d::structure<z3d::optional<Ts...>> components{};
protected:
void clear_components()
{
@@ -25,8 +28,6 @@ protected:
components
);
}
z3d::structure<z3d::optional<Ts...>> components{};
};
}

View File

@@ -6,8 +6,10 @@
namespace assets
{
struct material_data : detail::component_set<material_components::all>
{
struct material_data : public detail::component_set<
material_components::flags,
material_components::all
> {
material_data() = default;
@@ -16,9 +18,9 @@ struct material_data : detail::component_set<material_components::all>
[[nodiscard]] inline z3d::optional<material_components::specular_filter>& specular_filter();
[[nodiscard]] inline z3d::optional<material_components::shininess>& shininess();
[[nodiscard]] inline z3d::optional<material_components::alpha>& alpha();
[[nodiscard]] inline z3d::optional<material_components::ambient_filter_texture>& specular_filter_texture_id();
[[nodiscard]] inline z3d::optional<material_components::diffuse_filter_texture>& diffuse_filter_texture_id();
[[nodiscard]] inline z3d::optional<material_components::ambient_filter_texture>& ambient_filter_texture_id();
[[nodiscard]] inline z3d::optional<material_components::specular_filter_texture>& specular_filter_texture_id();
[[nodiscard]] inline z3d::optional<material_components::diffuse_filter_texture>& diffuse_filter_texture_id();
[[nodiscard]] inline z3d::optional<material_components::shininess_texture>& shininess_texture_id();
[[nodiscard]] inline z3d::optional<material_components::alpha_texture>& alpha_texture_id();
[[nodiscard]] inline z3d::optional<material_components::bump_texture>& bump_texture_id();
@@ -28,10 +30,9 @@ struct material_data : detail::component_set<material_components::all>
[[nodiscard]] inline const z3d::optional<material_components::specular_filter>& specular_filter() const;
[[nodiscard]] inline const z3d::optional<material_components::shininess>& shininess() const;
[[nodiscard]] inline const z3d::optional<material_components::alpha>& alpha() const;
[[nodiscard]] inline const z3d::optional<material_components::alpha>& transparency() const;
[[nodiscard]] inline const z3d::optional<material_components::ambient_filter_texture>& specular_filter_texture_id() const;
[[nodiscard]] inline const z3d::optional<material_components::diffuse_filter_texture>& diffuse_filter_texture_id() const;
[[nodiscard]] inline const z3d::optional<material_components::ambient_filter_texture>& ambient_filter_texture_id() const;
[[nodiscard]] inline const z3d::optional<material_components::specular_filter_texture>& specular_filter_texture_id() const;
[[nodiscard]] inline const z3d::optional<material_components::diffuse_filter_texture>& diffuse_filter_texture_id() const;
[[nodiscard]] inline const z3d::optional<material_components::shininess_texture>& shininess_texture_id() const;
[[nodiscard]] inline const z3d::optional<material_components::alpha_texture>& alpha_texture_id() const;
[[nodiscard]] inline const z3d::optional<material_components::bump_texture>& bump_texture_id() const;

View File

@@ -7,7 +7,7 @@
namespace assets
{
class mesh_data : detail::component_array_set<
class mesh_data : public detail::component_array_set<
mesh_vertex_components::flags,
mesh_vertex_components::all
> {
@@ -19,7 +19,7 @@ public:
[[nodiscard]] inline z3d::vector<mesh_vertex_components::color>& colors();
[[nodiscard]] inline z3d::vector<mesh_vertex_components::reflectance>& reflectances();
[[nodiscard]] inline z3d::vector<z3d::index_triangle>& triangles();
[[nodiscard]] inline auto& material();
[[nodiscard]] inline material_id& material();
[[nodiscard]] inline const z3d::vector<mesh_vertex_components::position>& positions() const;
[[nodiscard]] inline const z3d::vector<mesh_vertex_components::normal>& normals() const;
@@ -27,7 +27,7 @@ public:
[[nodiscard]] inline const z3d::vector<mesh_vertex_components::color>& colors() const;
[[nodiscard]] inline const z3d::vector<mesh_vertex_components::reflectance>& reflectances() const;
[[nodiscard]] inline const z3d::vector<z3d::index_triangle>& triangles() const;
[[nodiscard]] inline const auto& material() const;
[[nodiscard]] inline const material_id& material() const;
inline void clear();

View File

@@ -18,6 +18,8 @@ struct shader_source_data
shader_components::flags components{};
shader_components::flags static_enable{};
shader_components::flags dynamic_enable{};
bool operator==(const metadata& meta) const = default;
} meta;
void clear()

View File

@@ -9,7 +9,7 @@
#include "util/string_list.hpp"
#include "assets/file_parsers/mtl_loader.hpp"
#include "assets/file_parsers/mtl_parser.hpp"
// TODO not implemented?!?
namespace assets
@@ -17,7 +17,7 @@ namespace assets
class material_library_loader : public base_dynamic_loader<
material_components::flags,
mtl_loader
mtl_parser
> {
public:

View File

@@ -1,38 +1,135 @@
#pragma once
#include <vector>
#include <span>
#include <mutex>
#include <shared_mutex>
#include "util/uix.hpp"
#include "util/id_type.hpp"
namespace assets::detail {
template<typename ID, typename T>
class generic_basic_store;
template<typename ID, typename T>
class generic_basic_store_iterator
{
public:
using size_type = std::size_t;
using id_type = ID;
using data_type = T;
using value_type = std::pair<id_type, data_type>;
using id_iterator_type = const id_type*;
using data_iterator_type = data_type*;
using difference_type = std::ptrdiff_t;
using pointer = value_type*;
using reference = std::pair<id_type, data_type&>;
using iterator_category = std::random_access_iterator_tag;
private:
friend generic_basic_store<ID, T>;
generic_basic_store_iterator(
id_iterator_type ids,
data_iterator_type data,
std::size_t index
);
public:
constexpr generic_basic_store_iterator() noexcept = default;
constexpr generic_basic_store_iterator(const generic_basic_store_iterator&) noexcept = default;
constexpr generic_basic_store_iterator(generic_basic_store_iterator&&) noexcept = default;
constexpr generic_basic_store_iterator& operator=(const generic_basic_store_iterator&) noexcept = default;
constexpr generic_basic_store_iterator& operator=(generic_basic_store_iterator&&) noexcept = default;
reference operator*() const;
generic_basic_store_iterator& operator++();
generic_basic_store_iterator operator++(int);
generic_basic_store_iterator& operator--();
generic_basic_store_iterator operator--(int);
generic_basic_store_iterator& operator+=(difference_type n);
generic_basic_store_iterator& operator-=(difference_type n);
generic_basic_store_iterator operator+(difference_type n) const;
generic_basic_store_iterator operator-(difference_type n) const;
difference_type operator-(const generic_basic_store_iterator& other) const;
reference operator[](difference_type n) const;
bool operator==(const generic_basic_store_iterator& other) const;
bool operator!=(const generic_basic_store_iterator& other) const;
bool operator<(const generic_basic_store_iterator& other) const;
bool operator<=(const generic_basic_store_iterator& other) const;
bool operator>(const generic_basic_store_iterator& other) const;
bool operator>=(const generic_basic_store_iterator& other) const;
protected:
reference dereference() const;
private:
id_iterator_type m_ids{};
data_iterator_type m_data{};
size_type m_index{};
};
template<typename ID, typename T>
class generic_basic_store
{
public:
using id_type = ID;
using container_type = std::vector<T>;
using iterator_type = typename container_type::iterator;
using const_iterator = typename container_type::const_iterator;
using iterator = generic_basic_store_iterator<ID, T>;
using const_iterator = generic_basic_store_iterator<std::add_const_t<T>...>;
ID add(const T& data);
using size_type = std::size_t;
using data_type = T;
[[nodiscard]] std::pair<iterator_type, bool> find(ID id);
bool insert(ID id, const T& data);
[[nodiscard]] std::pair<const_iterator, bool> find(ID id) const;
bool insert(iterator it, id_type id, const data_type& data);
[[nodiscard]] std::span<T> data();
[[nodiscard]] std::pair<iterator, bool> find(id_type id);
[[nodiscard]] std::span<const T> data() const;
[[nodiscard]] std::pair<const_iterator, bool> find(id_type id) const;
void remove(iterator_type it);
void remove(iterator it);
void clear();
[[nodiscard]] inline std::shared_lock<std::shared_mutex> acquire_read_lock() const;
[[nodiscard]] inline std::unique_lock<std::shared_mutex> acquire_write_lock();
iterator begin();
iterator end();
const_iterator begin() const;
const_iterator end() const;
const_iterator cbegin() const;
const_iterator cend() const;
protected:
bool unsafe_insert(iterator it, ID id, const T& data);
[[nodiscard]] std::pair<iterator, bool> unsafe_find(ID id);
[[nodiscard]] std::pair<const_iterator, bool> unsafe_find(ID id) const;
private:
std::vector<T> m_data;
std::vector<ID> m_ids;
std::vector<T> m_data;
mutable std::shared_mutex m_mutex;
};
}
#define INCLUDE_GENERIC_BASIC_STORE_IMPLEMENTATION
#include "assets/data_stores/generic/generic_basic_store.ipp"
#undef INCLUDE_GENERIC_BASIC_STORE_IMPLEMENTATION

View File

@@ -3,12 +3,13 @@
#include "assets/components/material_components.hpp"
#include "assets/data/material_data.hpp"
#include "assets/data_views/material_view.hpp"
#include <mutex>
#include <shared_mutex>
namespace assets::detail
{
template<typename... Ts>
template<typename T>
class generic_material_store;
template<typename... Ts>
@@ -33,7 +34,7 @@ public:
using iterator_category = std::random_access_iterator_tag;
private:
friend generic_material_store<Ts...>;
friend generic_material_store<z3d::structure<Ts...>>;
generic_material_store_iterator(
id_iterator_type ids,
@@ -94,32 +95,37 @@ private:
template<typename... Ts>
class generic_material_store
class generic_material_store<z3d::structure<Ts...>>
{
public:
using size_type = std::size_t;
using count_type = ztu::u32;
using component_flag_type = material_components::flags;
using data_type = material_data;
using iterator_type = generic_material_store_iterator<Ts...>;
using iterator = generic_material_store_iterator<Ts...>;
using const_iterator = generic_material_store_iterator<std::add_const_t<Ts>...>;
using view_type = std::ranges::subrange<iterator_type>;
using const_view_type = std::ranges::subrange<const_iterator>;
using id_type = material_id;
id_type add(const material_data& material);
bool insert(id_type id, const data_type& data);
[[nodiscard]] std::pair<iterator_type, bool> find(id_type id);
bool insert(iterator it, id_type id, const data_type& data);
[[nodiscard]] std::pair<iterator, bool> find(id_type id);
[[nodiscard]] std::pair<const_iterator, bool> find(id_type id) const;
void remove(const iterator_type& it);
void remove(const iterator& it);
void clear();
iterator_type begin();
[[nodiscard]] inline std::shared_lock<std::shared_mutex> acquire_read_lock() const;
iterator_type end();
[[nodiscard]] inline std::unique_lock<std::shared_mutex> acquire_write_lock();
iterator begin();
iterator end();
const_iterator begin() const;
@@ -129,11 +135,13 @@ public:
const_iterator cend() const;
view_type view();
const_view_type view() const;
protected:
bool unsafe_insert(iterator it, id_type id, const data_type& data);
[[nodiscard]] std::pair<iterator, bool> unsafe_find(id_type id);
[[nodiscard]] std::pair<const_iterator, bool> unsafe_find(id_type id) const;
std::tuple<std::add_pointer_t<Ts>...> component_iterators();
std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> component_iterators() const;
@@ -144,6 +152,7 @@ private:
std::vector<id_type> m_ids;
std::tuple<std::vector<Ts>...> m_component_arrays;
std::vector<component_flag_type> m_component_flag_counts;
mutable std::shared_mutex m_mutex;
};
}

View File

@@ -1,5 +1,8 @@
#pragma once
#include <mutex>
#include <shared_mutex>
#include "assets/components/mesh_vertex_components.hpp"
#include "assets/data_stores/material_store.hpp"
#include "assets/data/mesh_data.hpp"
@@ -8,7 +11,7 @@
namespace assets::detail
{
template<typename... Ts>
template<typename T>
class generic_mesh_store;
template<typename... Ts>
@@ -17,7 +20,7 @@ class generic_mesh_store_iterator
public:
using size_type = std::size_t;
using count_type = ztu::u32;
using index_type = z3d::vertex_index;
using triangle_type = z3d::index_triangle;
using material_id_type = material_store::id_type;
using component_flag_type = mesh_vertex_components::flags;
using id_type = mesh_id;
@@ -26,7 +29,7 @@ public:
using id_iterator_type = id_type*;
using component_iterator_type = std::tuple<std::add_pointer_t<Ts>...>;
using index_iterator_type = index_type*;
using triangle_iterator_type = triangle_type*;
using flag_count_iterator_type = const flag_count_type*;
using material_id_iterator_type = material_id_type*;
@@ -37,11 +40,11 @@ public:
using iterator_category = std::random_access_iterator_tag;
private:
friend generic_mesh_store<Ts...>;
friend generic_mesh_store<z3d::structure<Ts...>>;
generic_mesh_store_iterator(
id_iterator_type ids,
index_iterator_type indices,
triangle_iterator_type triangles,
const component_iterator_type& components,
material_id_iterator_type material_ids,
flag_count_iterator_type flag_counts,
@@ -92,7 +95,7 @@ protected:
private:
id_iterator_type m_ids{};
index_iterator_type m_indices{};
triangle_iterator_type m_triangles{};
component_iterator_type m_components{};
material_id_iterator_type m_material_ids{};
flag_count_iterator_type m_flag_counts{};
@@ -102,34 +105,39 @@ private:
template<typename... Ts>
class generic_mesh_store
class generic_mesh_store<z3d::structure<Ts...>>
{
public:
using size_type = std::size_t;
using count_type = ztu::u32;
using index_type = z3d::vertex_index;
using triangle_type = z3d::index_triangle;
using component_flag_type = mesh_vertex_components::flags;
using material_id_type = material_store::id_type;
using iterator_type = generic_mesh_store_iterator<Ts...>;
using const_iterator = generic_mesh_store_iterator<std::add_const_t<Ts>...>;
using view_type = std::ranges::subrange<iterator_type>;
using const_view_type = std::ranges::subrange<const_iterator>;
using material_id_type = material_id;
using data_type = mesh_data;
using id_type = mesh_id;
id_type add(const mesh_data& mesh);
using iterator = generic_mesh_store_iterator<Ts...>;
using const_iterator = generic_mesh_store_iterator<std::add_const_t<Ts>...>;
[[nodiscard]] std::pair<iterator_type, bool> find(id_type id);
bool insert(id_type id, const data_type& data);
bool insert(iterator it, id_type id, const data_type& data);
[[nodiscard]] std::pair<iterator, bool> find(id_type id);
[[nodiscard]] std::pair<const_iterator, bool> find(id_type id) const;
void remove(const iterator_type& it);
void remove(const iterator& it);
void clear();
iterator_type begin();
[[nodiscard]] inline std::shared_lock<std::shared_mutex> acquire_read_lock() const;
iterator_type end();
[[nodiscard]] inline std::unique_lock<std::shared_mutex> acquire_write_lock();
iterator begin();
iterator end();
const_iterator begin() const;
@@ -139,11 +147,12 @@ public:
const_iterator cend() const;
view_type view();
const_view_type view() const;
protected:
bool unsafe_insert(iterator it, id_type id, const data_type& data);
[[nodiscard]] std::pair<iterator, bool> unsafe_find(id_type id);
[[nodiscard]] std::pair<const_iterator, bool> unsafe_find(id_type id) const;
std::tuple<std::add_pointer_t<Ts>...> component_iterators();
std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> component_iterators() const;
@@ -152,11 +161,11 @@ protected:
private:
std::vector<id_type> m_ids;
std::vector<index_type> m_indices;
std::tuple<std::vector<Ts>...> m_component_arrays;
std::vector<triangle_type> m_triangles;
std::vector<std::tuple<component_flag_type, count_type, count_type>> m_component_flag_counts;
std::tuple<std::vector<Ts>...> m_component_arrays;
std::vector<material_store::id_type> m_material_ids;
id_type m_next_data_id{ 1 };
mutable std::shared_mutex m_mutex{};
};
}

View File

@@ -1,19 +1,19 @@
#pragma once
#include <mutex>
#include <shared_mutex>
#include "util/uix.hpp"
#include "util/id_type.hpp"
#include "assets/components/point_cloud_vertex_components.hpp"
#include "assets/data/point_cloud_data.hpp"
#include "assets/data_views/point_cloud_view.hpp"
namespace assets
namespace assets::detail
{
template<typename... Ts>
template<typename T>
class generic_point_cloud_store;
namespace detail
{
template<typename... Ts>
class generic_point_cloud_store_iterator
@@ -37,13 +37,13 @@ public:
using iterator_category = std::random_access_iterator_tag;
private:
friend generic_point_cloud_store<Ts...>;
friend generic_point_cloud_store<z3d::structure<Ts...>>;
generic_point_cloud_store_iterator(
id_iterator_type ids,
const component_iterator_type& components,
flag_count_iterator_type flag_counts,
std::size_t index,
size_type index,
const offsets_type& offsets
);
@@ -98,31 +98,37 @@ private:
template<typename... Ts>
class generic_point_cloud_store
class generic_point_cloud_store<z3d::structure<Ts...>>
{
public:
using size_type = std::size_t;
using count_type = ztu::u32;
using component_flag_type = point_cloud_vertex_components::flags;
using data_type = point_cloud_data;
using iterator_type = generic_point_cloud_store_iterator<Ts...>;
using const_iterator = generic_point_cloud_store_iterator<std::add_const_t<Ts>...>;
using id_type = point_cloud_id;
using data_type = point_cloud_data;
id_type add(id_type id, const data_type& point_cloud);
using iterator = generic_point_cloud_store_iterator<Ts...>;
using const_iterator = generic_point_cloud_store_iterator<std::add_const_t<Ts>...>;
[[nodiscard]] std::pair<iterator_type, bool> find(id_type id);
bool insert(id_type id, const data_type& data);
bool insert(iterator it, id_type id, const data_type& data);
[[nodiscard]] std::pair<iterator, bool> find(id_type id);
[[nodiscard]] std::pair<const_iterator, bool> find(id_type id) const;
void remove(const iterator_type& it);
void remove(const iterator& it);
void clear();
iterator_type begin();
[[nodiscard]] inline std::shared_lock<std::shared_mutex> acquire_read_lock() const;
iterator_type end();
[[nodiscard]] inline std::unique_lock<std::shared_mutex> acquire_write_lock();
iterator begin();
iterator end();
const_iterator begin() const;
@@ -133,6 +139,12 @@ public:
const_iterator cend() const;
protected:
bool unsafe_insert(iterator it, id_type id, const data_type& data);
[[nodiscard]] std::pair<iterator, bool> unsafe_find(id_type id);
[[nodiscard]] std::pair<const_iterator, bool> unsafe_find(id_type id) const;
std::tuple<std::add_pointer_t<Ts>...> component_iterators();
std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> component_iterators() const;
@@ -143,12 +155,11 @@ private:
std::vector<id_type> m_ids;
std::tuple<std::vector<Ts>...> m_component_arrays;
std::vector<std::pair<component_flag_type, count_type>> m_component_flag_counts;
id_type m_next_data_id{ 1 };
mutable std::shared_mutex m_mutex;
};
}
}
#define INCLUDE_GENERIC_POINT_CLOUD_STORE_IMPLEMENTATION

View File

@@ -1,11 +1,12 @@
#pragma once
#include "generic/generic_basic_store.hpp"
#include "assets/identifiers.hpp"
#include "assets/data/material_library_data.hpp"
namespace assets
{
using material_library_store = generic_basic_store<material_library_data>;
using material_library_store = detail::generic_basic_store<material_library_id, material_library_data>;
}

View File

@@ -5,15 +5,6 @@
namespace assets
{
using material_store = detail::generic_material_store<
material_components::surface_properties,
material_components::alpha,
texture_store::id_type,
texture_store::id_type,
texture_store::id_type,
texture_store::id_type,
texture_store::id_type,
texture_store::id_type
>;
using material_store = detail::generic_material_store<material_components::all>;
}

View File

@@ -6,11 +6,7 @@ namespace assets
{
using mesh_store = detail::generic_mesh_store<
mesh_vertex_components::position,
mesh_vertex_components::normal,
mesh_vertex_components::tex_coord,
mesh_vertex_components::color,
mesh_vertex_components::reflectance
mesh_vertex_components::all
>;
}

View File

@@ -8,10 +8,7 @@ namespace assets
{
using point_cloud_store = detail::generic_point_cloud_store<
point_cloud_vertex_components::position,
point_cloud_vertex_components::normal,
point_cloud_vertex_components::color,
point_cloud_vertex_components::reflectance
point_cloud_vertex_components::all
>;
}

View File

@@ -1,6 +1,8 @@
#pragma once
#include "generic/generic_basic_store.hpp"
#include <mutex>
#include <shared_mutex>
#include "assets/identifiers.hpp"
#include "assets/data/pose_list_data.hpp"
#include "assets/data_views/pose_list_view.hpp"
@@ -75,7 +77,7 @@ protected:
void calc_offset(difference_type n);
reference dereference() const;
[[nodiscard]] reference dereference() const;
private:
id_iterator_type m_ids{};
@@ -92,28 +94,30 @@ public:
using size_type = std::size_t;
using count_type = ztu::u32;
using iterator_type = pose_list_store_iterator<char>;
using iterator = pose_list_store_iterator<char>;
using const_iterator = pose_list_store_iterator<const char>;
using data_type = pose_list_data;
using id_type = pose_list_id;
// TODO not storing metadata
inline id_type add(
id_type id,
const data_type& pose_list
);
bool insert(id_type id, const data_type& data);
[[nodiscard]] inline std::pair<iterator_type, bool> find(id_type id);
bool insert(iterator it, id_type id, const data_type& data);
[[nodiscard]] inline std::pair<const_iterator, bool> find(id_type id) const;
[[nodiscard]] std::pair<iterator, bool> find(id_type id);
inline void remove(const iterator_type& it);
[[nodiscard]] std::pair<const_iterator, bool> find(id_type id) const;
inline void remove(const iterator& it);
inline void clear();
[[nodiscard]] inline iterator_type begin();
[[nodiscard]] inline std::shared_lock<std::shared_mutex> acquire_read_lock() const;
[[nodiscard]] inline iterator_type end();
[[nodiscard]] inline std::unique_lock<std::shared_mutex> acquire_write_lock();
[[nodiscard]] inline iterator begin();
[[nodiscard]] inline iterator end();
[[nodiscard]] inline const_iterator begin() const;
@@ -123,11 +127,18 @@ public:
[[nodiscard]] inline const_iterator cend() const;
protected:
bool unsafe_insert(iterator it, id_type id, const data_type& data);
[[nodiscard]] std::pair<iterator, bool> unsafe_find(id_type id);
[[nodiscard]] std::pair<const_iterator, bool> unsafe_find(id_type id) const;
private:
std::vector<id_type> m_ids;
std::vector<char> m_poses;
std::vector<count_type> m_lengths;
mutable std::shared_mutex m_mutex;
};
}

View File

@@ -1,11 +1,12 @@
#pragma once
#include "generic/generic_basic_store.hpp"
#include "assets/identifiers.hpp"
#include "assets/data/pose_data.hpp"
namespace assets
{
using pose_store = generic_basic_store<pose_data>;
using pose_store = detail::generic_basic_store<pose_id, pose_data>;
}

View File

@@ -1,6 +1,7 @@
#pragma once
#include "generic/generic_basic_store.hpp"
#include <mutex>
#include <shared_mutex>
#include "assets/data/shader_source_data.hpp"
#include "assets/data_views/shader_source_view.hpp"
@@ -95,29 +96,33 @@ public:
using size_type = std::size_t;
using count_type = ztu::u32;
using iterator_type = shader_source_store_iterator<char>;
using iterator = shader_source_store_iterator<char>;
using const_iterator = shader_source_store_iterator<const char>;
using view_type = std::ranges::subrange<iterator_type>;
using view_type = std::ranges::subrange<iterator>;
using const_view_type = std::ranges::subrange<const_iterator>;
using id_type = shader_source_id;
using data_type = shader_source_data;
// TODO not storing metadata
inline id_type add(
shader_source_id id,
const shader_source_data& shader_source
);
bool insert(id_type id, const data_type& data);
[[nodiscard]] inline std::pair<iterator_type, bool> find(id_type id);
bool insert(iterator it, id_type id, const data_type& data);
[[nodiscard]] inline std::pair<const_iterator, bool> find(id_type id) const;
[[nodiscard]] std::pair<iterator, bool> find(id_type id);
inline void remove(const iterator_type& it);
[[nodiscard]] std::pair<const_iterator, bool> find(id_type id) const;
inline void remove(const iterator& it);
inline void clear();
[[nodiscard]] inline iterator_type begin();
[[nodiscard]] inline std::shared_lock<std::shared_mutex> acquire_read_lock() const;
[[nodiscard]] inline iterator_type end();
[[nodiscard]] inline std::unique_lock<std::shared_mutex> acquire_write_lock();
[[nodiscard]] inline iterator begin();
[[nodiscard]] inline iterator end();
[[nodiscard]] inline const_iterator begin() const;
@@ -127,12 +132,19 @@ public:
[[nodiscard]] inline const_iterator cend() const;
protected:
bool unsafe_insert(iterator it, id_type id, const data_type& data);
[[nodiscard]] std::pair<iterator, bool> unsafe_find(id_type id);
[[nodiscard]] std::pair<const_iterator, bool> unsafe_find(id_type id) const;
private:
std::vector<id_type> m_ids;
std::vector<char> m_strings;
std::vector<count_type> m_lengths;
std::vector<shader_source_data::metadata> m_metadata;
mutable std::shared_mutex m_mutex;
};
}

View File

@@ -1,12 +1,13 @@
#pragma once
#include "generic/generic_basic_store.hpp"
#include "assets/identifiers.hpp"
#include "assets/data/texture_data.hpp"
namespace assets
{
using texture_store = generic_basic_store<texture_data>;
using texture_store = detail::generic_basic_store<texture_id, texture_data>;
}

View File

@@ -1,8 +1,7 @@
#pragma once
#include <string_view>
#include "assets/model_geometry.hpp"
#include "assets/components/shader_components.hpp"
#include "assets/data/shader_source_data.hpp"
namespace assets
{
@@ -10,11 +9,7 @@ namespace assets
struct shader_source_view
{
std::string_view source;
model_geometry::types geometry_type;
shader_components::stage stage;
shader_components::flags components{};
shader_components::flags static_enable{};
shader_components::flags dynamic_enable{};
shader_source_data::metadata meta;
};
}

View File

@@ -1,60 +0,0 @@
#pragma once
#include <filesystem>
#include <system_error>
#include "assets/prefetch_lookup.hpp"
#include "assets/prefetch_queue.hpp"
#include "assets/data/material_data.hpp"
#include "assets/data/material_library_data.hpp"
#include "assets/data_stores/material_store.hpp"
#include "assets/data_stores/material_library_store.hpp"
#include "util/result.hpp"
namespace assets
{
namespace mtl_loader_error
{
enum class codes {
ok = 0,
cannot_open_file,
cannot_open_texture,
malformed_ambient_color,
malformed_diffuse_color,
malformed_specular_color,
malformed_specular_exponent,
malformed_dissolve,
unknown_line_begin
};
} // namespace mtl_loader_error
struct mtl_loader
{
static constexpr auto name = std::string_view("mtl");
[[nodiscard]] static std::error_code prefetch(
const file_dir_list& paths,
prefetch_queue& queue
);
// THis is not very elegant, but right now I do not see a better solution...
[[nodiscard]] static std::error_code load(
dynamic_material_library_buffer& material_library_buffer,
const file_dir_list& paths,
prefetch_lookup& id_lookup,
shader_source_store& store,
bool pedantic = false
);
protected:
static void find_textures(
std::span<char> buffer,
std::filesystem::path& path_buffer,
const std::filesystem::path& base_directory,
std::ifstream& in,
ztu::string_list& texture_filenames
);
};
}

View File

@@ -0,0 +1,96 @@
#pragma once
#include <filesystem>
#include <system_error>
#include "assets/data_stores.hpp"
#include "assets/path_id_lookups.hpp"
#include "assets/prefetch_lookup.hpp"
#include "assets/prefetch_queue.hpp"
#include "assets/data/material_data.hpp"
#include "assets/data/material_library_data.hpp"
#include "assets/data_stores/material_store.hpp"
#include "assets/data_stores/material_library_store.hpp"
#include "util/result.hpp"
namespace assets
{
namespace mtl_parser_error
{
enum class codes {
ok = 0,
cannot_open_file,
// TODO these are incomplete
cannot_open_texture,
malformed_ambient_color,
malformed_diffuse_color,
malformed_specular_color,
malformed_specular_exponent,
malformed_dissolve,
unknown_line_begin
};
} // namespace mtl_loader_error
struct mtl_parser
{
static constexpr auto name = std::string_view("mtl");
using data_type = material_library_data;
using store_type = material_library_store;
using lookup_type = material_library_id_lookup;
[[nodiscard]] std::error_code prefetch(
path_id_lookups& lookups
);
[[nodiscard]] std::error_code load(
path_id_lookups& lookups,
data_stores& stores,
bool pedantic = false
);
protected:
class parser_context
{
public:
parser_context(
const texture_id_lookup& texture_id_lookup,
material_id_lookup& material_id_lookup,
material_store& material_store,
store_type& store,
std::mutex& store_mutex
);
void operator()(lookup_type::const_pointer entry) noexcept;
protected:
void reset();
[[nodiscard]] std::optional<texture_id> fetch_texture_id(
const std::filesystem::path& mtl_dir,
std::string_view filename,
std::string_view texture_type_name
);
private:
const texture_id_lookup* m_texture_id_lookup;
material_id_lookup* m_material_id_lookup;
material_store* m_material_store;
store_type* m_store;
std::mutex* m_store_mutex;
data_type m_buffer{};
};
static void find_textures(
std::span<char> buffer,
std::filesystem::path& path_buffer,
const std::filesystem::path& base_directory,
std::ifstream& in,
ztu::string_list& texture_filenames
);
private:
std::vector<lookup_type::const_pointer> m_path_buffer;
};
}

View File

@@ -30,7 +30,7 @@ protected:
resource_manager_type m_resource_manager;
private:
std::vector<store_type::iterator_type::value_type> m_mesh_buffer;
std::vector<store_type::iterator::value_type> m_mesh_buffer;
std::vector<GLuint> m_buffer_id_buffer;
};
}

View File

@@ -31,7 +31,7 @@ protected:
resource_manager_type m_resource_manager;
private:
std::vector<store_type::iterator_type::value_type> m_mesh_buffer;
std::vector<store_type::iterator::value_type> m_mesh_buffer;
std::vector<GLuint> m_buffer_id_buffer;
std::vector<ztu::u8> m_byte_buffer;

View File

@@ -31,7 +31,7 @@ protected:
resource_manager_type m_resource_manager;
private:
std::vector<store_type::iterator_type::value_type> m_point_cloud_buffer;
std::vector<store_type::iterator::value_type> m_point_cloud_buffer;
std::vector<GLuint> m_buffer_id_buffer;
std::vector<ztu::u8> m_byte_buffer;
};

View File

@@ -1,18 +1,10 @@
#pragma once
#include "assets/model_geometry.hpp"
#include "assets/components/shader_components.hpp"
#include "assets/data/shader_source_data.hpp"
namespace zgl
{
struct shader_source_metadata
{
assets::model_geometry::types geometry_type;
assets::shader_components::stage stage;
assets::shader_components::flags components{};
assets::shader_components::flags static_enable{};
assets::shader_components::flags dynamic_enable{};
};
using shader_source_metadata = assets::shader_source_data::metadata;
}

View File

@@ -4,6 +4,8 @@
#include <filesystem>
#include <ranges>
#include <vector>
#include <mutex>
#include <shared_mutex>
template<typename ID>
class file_id_lookup
@@ -29,64 +31,107 @@ public:
using node_type = typename container_type::node_type;
using insert_return_type = typename container_type::insert_return_type;
std::pair<iterator, bool> try_emplace(const key_type& path)
{
std::unique_lock lock(m_mutex);
auto it = m_container.find(path);
const auto is_new = it == m_container.end();
if (is_new) {
it = m_container.emplace_hint(it, path, ID::next());
}
return { it, is_new };
}
[[nodiscard]] bool empty() const noexcept
{
std::shared_lock lock(m_mutex);
return m_container.empty();
}
[[nodiscard]] size_type size() const noexcept
{
std::shared_lock lock(m_mutex);
return m_container.size();
}
[[nodiscard]] size_type max_size() const noexcept
{
std::shared_lock lock(m_mutex);
return m_container.max_size();
}
void by_extension(const std::string_view extension, std::vector<const_pointer>& dst) const
{
std::shared_lock lock(m_mutex);
std::ranges::copy(
m_container |
std::views::filter([
&](const value_type& entry) {
return entry.first.extension() == extension;
}
) |
std::views::transform([
&](const value_type& entry) {
return &entry;
}
),
std::back_inserter(dst)
);
}
[[nodiscard]] bool contains(const key_type& key) const
{
std::shared_lock lock(m_mutex);
return m_container.contains(key);
}
[[nodiscard]] size_type count(const key_type& key) const
{
std::shared_lock lock(m_mutex);
return m_container.count(key);
}
[[nodiscard]] iterator find(const key_type& key)
{
std::shared_lock lock(m_mutex);
return m_container.find(key);
}
[[nodiscard]] const_iterator find(const key_type& key) const
{
std::shared_lock lock(m_mutex);
return m_container.find(key);
}
iterator erase(iterator pos)
{
std::unique_lock lock(m_mutex);
return m_container.erase(pos);
}
iterator erase(const_iterator pos)
{
std::unique_lock lock(m_mutex);
return m_container.erase(pos);
}
iterator erase(const_iterator first, const_iterator last)
{
std::unique_lock lock(m_mutex);
return m_container.erase(first, last);
}
size_type erase(const key_type& key)
{
std::unique_lock lock(m_mutex);
return m_container.erase(key);
}
void clear() noexcept
{
std::unique_lock lock(m_mutex);
m_container.clear();
}
[[nodiscard]] iterator begin() noexcept { return m_container.begin(); }
[[nodiscard]] const_iterator begin() const noexcept { return m_container.begin(); }
[[nodiscard]] const_iterator cbegin() const noexcept { return m_container.cbegin(); }
[[nodiscard]] iterator end() noexcept { return m_container.end(); }
[[nodiscard]] const_iterator end() const noexcept { return m_container.end(); }
[[nodiscard]] const_iterator cend() const noexcept { return m_container.cend(); }
[[nodiscard]] bool empty() const noexcept { return m_container.empty(); }
[[nodiscard]] size_type size() const noexcept { return m_container.size(); }
[[nodiscard]] size_type max_size() const noexcept { return m_container.max_size(); }
void by_extension(
const std::string_view extension,
std::vector<const_pointer>& dst
) const {
std::ranges::copy(
m_container |
std::views::filter(
[&](const value_type& entry)
{
return entry.first.extension() == extension;
}
) |
std::views::transform(
[&](const value_type& entry)
{
return &entry;
}
),
std::back_inserter(dst)
);
}
std::pair<iterator, bool> try_emplace(const key_type& path)
{
auto it = m_container.find(path);
const auto is_new = it == m_container.end();
if (not is_new)
{
it = m_container.emplace_hint(it, path, ID::next());
}
return { it, is_new };
}
[[nodiscard]] bool contains(const key_type& key) const { return m_container.contains(key); }
[[nodiscard]] size_type count(const key_type& key) const { return m_container.count(key); }
[[nodiscard]] iterator find(const key_type& key) { return m_container.find(key); }
[[nodiscard]] const_iterator find(const key_type& key) const { return m_container.find(key); }
iterator erase(iterator pos) { return m_container.erase(pos); }
iterator erase(const_iterator pos) { return m_container.erase(pos); }
iterator erase(const_iterator first, const_iterator last) { return m_container.erase(first, last); }
size_type erase(const key_type& key) { return m_container.erase(key); }
void clear() noexcept { m_container.clear(); }
private:
@@ -101,4 +146,5 @@ private:
}
container_type m_container;
std::shared_mutex m_mutex;
};

View File

@@ -0,0 +1,33 @@
#pragma once
#include <algorithm>
#include <vector>
namespace ztu
{
template<class T, class Allocator, class InputIt>
void replace_range(
std::vector<T, Allocator>& dst,
typename std::vector<T, Allocator>::iterator dst_begin,
typename std::vector<T, Allocator>::iterator dst_end,
InputIt src_begin,
InputIt src_end
) {
const auto dst_size = std::distance(dst_begin, dst_end);
const auto src_size = std::distance(src_begin, src_end);
if (dst_size < src_size)
{
dst.insert(dst_end, src_begin + dst_size, src_end);
}
else if (dst_size > src_size)
{
dst.erase(dst_begin + src_size, dst_end);
}
std::copy_n(src_begin, std::min(src_size, dst_size), dst_begin);
}
}

View File

@@ -2,17 +2,17 @@
# error Never include this file directly include 'material_data.hpp'
#endif
inline std::optional<assets::material_components::ambient_filter>& assets::material_data::specular_filter()
inline std::optional<assets::material_components::specular_filter>& assets::material_data::specular_filter()
{
return std::get<material_components::indices::ambient_filter>(components);
return std::get<material_components::indices::specular_filter>(components);
}
inline std::optional<assets::material_components::diffuse_filter>& assets::material_data::diffuse_filter()
{
return std::get<material_components::indices::diffuse_filter>(components);
}
inline std::optional<assets::material_components::specular_filter>& assets::material_data::specular_filter()
inline std::optional<assets::material_components::ambient_filter>& assets::material_data::ambient_filter()
{
return std::get<material_components::indices::specular_filter>(components);
return std::get<material_components::indices::ambient_filter>(components);
}
inline std::optional<assets::material_components::shininess>& assets::material_data::shininess()
{
@@ -23,17 +23,17 @@ inline std::optional<assets::material_components::alpha>& assets::material_data:
return std::get<material_components::indices::alpha>(components);
}
inline std::optional<assets::material_components::ambient_filter_texture>& assets::material_data::specular_filter_texture_id()
inline std::optional<assets::material_components::specular_filter_texture>& assets::material_data::specular_filter_texture_id()
{
return std::get<material_components::indices::ambient_filter_texture>(components);
return std::get<material_components::indices::specular_filter_texture>(components);
}
inline std::optional<assets::material_components::diffuse_filter_texture>& assets::material_data::diffuse_filter_texture_id()
{
return std::get<material_components::indices::diffuse_filter_texture>(components);
}
inline std::optional<assets::material_components::specular_filter_texture>& assets::material_data::specular_filter_texture_id()
inline std::optional<assets::material_components::ambient_filter_texture>& assets::material_data::ambient_filter_texture_id()
{
return std::get<material_components::indices::specular_filter_texture>(components);
return std::get<material_components::indices::ambient_filter_texture>(components);
}
inline std::optional<assets::material_components::shininess_texture>& assets::material_data::shininess_texture_id()
{
@@ -48,17 +48,17 @@ inline std::optional<assets::material_components::bump_texture>& assets::materia
return std::get<material_components::indices::bump_texture(components);
}
inline const std::optional<assets::material_components::ambient_filter>& assets::material_data::specular_filter() const
inline const std::optional<assets::material_components::specular_filter>& assets::material_data::specular_filter() const
{
return std::get<material_components::indices::ambient_filter>(components);
return std::get<material_components::indices::specular_filter>(components);
}
inline const std::optional<assets::material_components::diffuse_filter>& assets::material_data::diffuse_filter() const
{
return std::get<material_components::indices::diffuse_filter>(components);
}
inline const std::optional<assets::material_components::specular_filter>& assets::material_data::specular_filter() const
inline const std::optional<assets::material_components::ambient_filter>& assets::material_data::ambient_filter() const
{
return std::get<material_components::indices::specular_filter>(components);
return std::get<material_components::indices::ambient_filter>(components);
}
inline const std::optional<assets::material_components::shininess>& assets::material_data::shininess() const
{
@@ -69,9 +69,9 @@ inline const std::optional<assets::material_components::alpha>& assets::material
return std::get<material_components::indices::alpha>(components);
}
inline const std::optional<assets::material_components::ambient_filter_texture>& assets::material_data::specular_filter_texture_id() const
inline const std::optional<assets::material_components::specular_filter_texture>& assets::material_data::specular_filter_texture_id() const
{
return std::get<material_components::indices::ambient_filter_texture>(components);
return std::get<material_components::indices::specular_filter_texture>(components);
}
inline const std::optional<assets::material_components::diffuse_filter_texture>& assets::material_data::diffuse_filter_texture_id() const
@@ -79,9 +79,9 @@ inline const std::optional<assets::material_components::diffuse_filter_texture>&
return std::get<material_components::indices::diffuse_filter_texture>(components);
}
inline const std::optional<assets::material_components::specular_filter_texture>& assets::material_data::specular_filter_texture_id() const
inline const std::optional<assets::material_components::ambient_filter_texture>& assets::material_data::ambient_filter_texture_id() const
{
return std::get<material_components::indices::specular_filter_texture>(components);
return std::get<material_components::indices::ambient_filter_texture>(components);
}
inline const std::optional<assets::material_components::shininess_texture>& assets::material_data::shininess_texture_id() const

View File

@@ -3,61 +3,288 @@
#endif
#include <algorithm>
#include <mutex>
template<typename T>
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);
m_ids.emplace_back(id);
return id;
template<typename ID, typename T>
assets::detail::generic_basic_store_iterator<ID, T>::generic_basic_store_iterator(
id_iterator_type ids,
data_iterator_type data,
const size_type index
) :
m_ids{ ids },
m_data{ data },
m_index{ index } {}
template<typename ID, typename T>
typename assets::detail::generic_basic_store_iterator<ID, T>::reference assets::detail::generic_basic_store_iterator<ID, T>::operator*() const {
return dereference();
}
template<typename T>
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;
return { m_data.begin() + index, found };
template<typename ID, typename T>
assets::detail::generic_basic_store_iterator<ID, T>& assets::detail::generic_basic_store_iterator<ID, T>::operator++() {
++m_index;
return *this;
}
template<typename T>
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;
return { m_data.begin() + index, found };
template<typename ID, typename T>
assets::detail::generic_basic_store_iterator<ID, T> assets::detail::generic_basic_store_iterator<ID, T>::operator++(int) {
generic_basic_store_iterator tmp = *this;
++(*this);
return tmp;
}
template<typename T>
void generic_basic_store<T>::remove(iterator_type it)
template<typename ID, typename T>
assets::detail::generic_basic_store_iterator<ID, T>& assets::detail::generic_basic_store_iterator<ID, T>::operator--() {
--m_index;
return *this;
}
template<typename ID, typename T>
assets::detail::generic_basic_store_iterator<ID, T> assets::detail::generic_basic_store_iterator<ID, T>::operator--(int) {
auto tmp = *this;
--(*this);
return tmp;
}
template<typename ID, typename T>
assets::detail::generic_basic_store_iterator<ID, T>& assets::detail::generic_basic_store_iterator<ID, T>::operator+=(const difference_type n)
{
const auto index = it - m_data.begin();
m_data.erase(it);
m_index += n;
return *this;
}
template<typename ID, typename T>
assets::detail::generic_basic_store_iterator<ID, T>& assets::detail::generic_basic_store_iterator<ID, T>::operator-=(const difference_type n)
{
return (*this) += -n;
}
template<typename ID, typename T>
assets::detail::generic_basic_store_iterator<ID, T> assets::detail::generic_basic_store_iterator<ID, T>::operator+(const difference_type n) const
{
auto tmp = *this;
return tmp += n; // TODO clion says n is unused
}
template<typename ID, typename T>
assets::detail::generic_basic_store_iterator<ID, T> assets::detail::generic_basic_store_iterator<ID, T>::operator-(const difference_type n) const
{
auto tmp = *this;
return tmp -= n; // TODO clion says n is unused
}
template<typename ID, typename T>
typename assets::detail::generic_basic_store_iterator<ID, T>::difference_type
assets::detail::generic_basic_store_iterator<ID, T>::operator-(const generic_basic_store_iterator& other) const
{
return static_cast<difference_type>(m_index) - static_cast<difference_type>(other.m_index);
}
template<typename ID, typename T>
typename assets::detail::generic_basic_store_iterator<ID, T>::reference assets::detail::generic_basic_store_iterator<ID, T>::operator[](
const difference_type n
) const {
return *(*this + n);
}
template<typename ID, typename T>
bool assets::detail::generic_basic_store_iterator<ID, T>::operator==(const generic_basic_store_iterator& other) const
{
return m_ids == other.m_ids and m_index == other.m_index;
}
template<typename ID, typename T>
bool assets::detail::generic_basic_store_iterator<ID, T>::operator!=(const generic_basic_store_iterator& other) const
{
return not (*this == other);
}
template<typename ID, typename T>
bool assets::detail::generic_basic_store_iterator<ID, T>::operator<(const generic_basic_store_iterator& other) const
{
return m_index < other.m_index;
}
template<typename ID, typename T>
bool assets::detail::generic_basic_store_iterator<ID, T>::operator<=(const generic_basic_store_iterator& other) const
{
return m_index <= other.m_index;
}
template<typename ID, typename T>
bool assets::detail::generic_basic_store_iterator<ID, T>::operator>(const generic_basic_store_iterator& other) const
{
return m_index > other.m_index;
}
template<typename ID, typename T>
bool assets::detail::generic_basic_store_iterator<ID, T>::operator>=(const generic_basic_store_iterator& other) const
{
return m_index >= other.m_index;
}
template<typename ID, typename T>
typename assets::detail::generic_basic_store_iterator<ID, T>::reference
assets::detail::generic_basic_store_iterator<ID, T>::dereference() const
{
return {
m_ids[m_index],
m_data[m_index]
};
}
template<typename ID, typename T>
bool assets::detail::generic_basic_store<ID, T>::insert(const ID id, const T& data)
{
auto lock = std::unique_lock{ m_mutex };
const auto result = unsafe_find(id);
return unsafe_insert(result.first, id, data);
}
template<typename ID, typename T>
bool assets::detail::generic_basic_store<ID, T>::insert(iterator it, const ID id, const T& data)
{
auto lock = std::unique_lock{ m_mutex };
return unsafe_insert(it, id, data);
}
template<typename ID, typename T>
std::pair<typename assets::detail::generic_basic_store<ID, T>::iterator, bool> assets::detail::generic_basic_store<ID, T>::find(ID id)
{
auto lock = std::shared_lock{ m_mutex };
return unsafe_find(id);
}
template<typename ID, typename T>
std::pair<typename assets::detail::generic_basic_store<ID, T>::const_iterator, bool> assets::detail::generic_basic_store<ID, T>::find(ID id) const
{
auto lock = std::shared_lock{ m_mutex };
return unsafe_find(id);
}
template<typename ID, typename T>
bool assets::detail::generic_basic_store<ID, T>::unsafe_insert(iterator it, const ID id, const T& data)
{
const auto index = it.m_index;
if (index != m_ids.size() and m_ids[index] == id)
{
m_data[index] = data;
return false;
}
m_ids.insert(m_ids.begin() + index, id);
m_data.insert(m_data.begin() + index, data);
return true;
}
template<typename ID, typename T>
std::pair<typename assets::detail::generic_basic_store<ID, T>::iterator, bool> assets::detail::generic_basic_store<ID, T>::unsafe_find(ID id)
{
const auto it = std::ranges::lower_bound(m_ids, id);
const auto found = it != m_ids.end() and *it == id;
const auto index = std::distance(m_ids.begin(), it);
return { begin() + index, found };
}
template<typename ID, typename T>
std::pair<typename assets::detail::generic_basic_store<ID, T>::const_iterator, bool> assets::detail::generic_basic_store<ID, T>::unsafe_find(ID id) const
{
const auto it = std::ranges::lower_bound(m_ids, id);
const auto found = it != m_ids.end() and *it == id;
const auto index = std::distance(m_ids.begin(), it);
return { begin() + index, found };
}
template<typename ID, typename T>
void assets::detail::generic_basic_store<ID, T>::remove(iterator it)
{
auto lock = std::unique_lock{ m_mutex };
const auto index = it.m_index;
m_data.erase(m_data.begin() + index);
m_ids.erase(m_ids.begin() + index);
}
template<typename T>
void generic_basic_store<T>::clear()
template<typename ID, typename T>
void assets::detail::generic_basic_store<ID, T>::clear()
{
auto lock = std::unique_lock{ m_mutex };
m_data.clear();
m_ids.clear();
}
template<typename T>
std::span<T> generic_basic_store<T>::data()
{
return m_data;
template<typename ID, typename T>
std::shared_lock<std::shared_mutex> assets::detail::generic_basic_store<ID, T>::acquire_read_lock() const {
return std::shared_lock{ m_mutex };
}
template<typename T>
std::span<const T> generic_basic_store<T>::data() const
{
return m_data;
template<typename ID, typename T>
std::unique_lock<std::shared_mutex> assets::detail::generic_basic_store<ID, T>::acquire_write_lock() {
return std::unique_lock{ m_mutex };
}
template<typename ID, typename T>
typename assets::detail::generic_basic_store<ID, T>::iterator assets::detail::generic_basic_store<ID, T>::begin()
{
return iterator{
m_ids.data(),
m_data.begin(),
0
};
}
template<typename ID, typename T>
typename assets::detail::generic_basic_store<ID, T>::iterator assets::detail::generic_basic_store<ID, T>::end()
{
return iterator{
m_ids.data(),
m_data.begin(),
m_ids.size()
};
}
template<typename ID, typename T>
typename assets::detail::generic_basic_store<ID, T>::const_iterator assets::detail::generic_basic_store<ID, T>::begin() const
{
return const_iterator{
m_ids.data(),
m_data.begin(),
0
};
}
template<typename ID, typename T>
typename assets::detail::generic_basic_store<ID, T>::const_iterator assets::detail::generic_basic_store<ID, T>::end() const
{
return const_iterator{
m_ids.data(),
m_data.begin(),
m_ids.size()
};
}
template<typename ID, typename T>
typename assets::detail::generic_basic_store<ID, T>::const_iterator assets::detail::generic_basic_store<ID, T>::cbegin() const
{
return this->begin();
}
template<typename ID, typename T>
typename assets::detail::generic_basic_store<ID, T>::const_iterator assets::detail::generic_basic_store<ID, T>::cend() const
{
return this->end();
}

View File

@@ -3,7 +3,7 @@
#endif
#include <vector>
#include <span>
#include <mutex>
#include <tuple>
#include <cstddef>
#include <type_traits>
@@ -14,7 +14,7 @@ assets::detail::generic_material_store_iterator<Ts...>::generic_material_store_i
id_iterator_type ids,
const component_iterator_type& components,
flag_count_iterator_type flag_counts,
std::size_t index,
const size_type index,
const offsets_type& offsets
) :
m_ids{ ids },
@@ -195,7 +195,7 @@ assets::detail::generic_material_store_iterator<Ts...>::dereference(std::index_s
}
template<typename... Ts>
std::tuple<std::add_pointer_t<Ts>...> assets::detail::generic_material_store<Ts...>::component_iterators()
std::tuple<std::add_pointer_t<Ts>...> assets::detail::generic_material_store<z3d::structure<Ts...>>::component_iterators()
{
return [&]<auto... Is>(std::index_sequence<Is>)
{
@@ -205,7 +205,7 @@ std::tuple<std::add_pointer_t<Ts>...> assets::detail::generic_material_store<Ts.
}
template<typename... Ts>
std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> assets::detail::generic_material_store<Ts...>::component_iterators() const
std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> assets::detail::generic_material_store<z3d::structure<Ts...>>::component_iterators() const
{
return [&]<auto... Is>(std::index_sequence<Is>)
{
@@ -215,8 +215,8 @@ std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> assets::detail::generic_
}
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
std::array<typename assets::detail::generic_material_store<z3d::structure<Ts...>>::count_type, 1 + sizeof...(Ts)>
assets::detail::generic_material_store<z3d::structure<Ts...>>::array_counts() const
{
return [&]<auto... Is>(std::index_sequence<Is>)
{
@@ -228,84 +228,139 @@ assets::detail::generic_material_store<Ts...>::array_counts() const
}
template<typename... Ts>
typename assets::detail::generic_material_store<Ts...>::id_type assets::detail::generic_material_store<Ts...>::add(
const component_set& material
) {
bool assets::detail::generic_material_store<z3d::structure<Ts...>>::insert(const id_type id, const data_type& data)
{
auto lock = std::unique_lock{ m_mutex };
const auto id = id_type{ m_next_data_id.index++ };
m_ids.push_back(id);
const auto result = unsafe_find(id);
auto component_flags = component_flag_type{};
return unsafe_insert(result.first, id, data);
}
template<typename... Ts>
bool assets::detail::generic_material_store<z3d::structure<Ts...>>::insert(iterator it, const id_type id, const data_type& data)
{
auto lock = std::unique_lock{ m_mutex };
return unsafe_insert(it, id, data);
}
template<typename... Ts>
std::pair<typename assets::detail::generic_material_store<z3d::structure<Ts...>>::iterator, bool> assets::detail::generic_material_store<z3d::structure<Ts...>>::find(id_type id)
{
auto lock = std::shared_lock{ m_mutex };
return unsafe_find(id);
}
template<typename... Ts>
std::pair<typename assets::detail::generic_material_store<z3d::structure<Ts...>>::const_iterator, bool> assets::detail::generic_material_store<z3d::structure<Ts...>>::find(id_type id) const
{
auto lock = std::shared_lock{ m_mutex };
return unsafe_find(id);
}
template<typename... Ts>
bool assets::detail::generic_material_store<z3d::structure<Ts...>>::unsafe_insert(iterator it, const id_type id, const data_type& data)
{
const auto index = it.m_index;
const auto new_entry = index == m_ids.size() or m_ids[index] != id;
const auto src_component_flags = data.component_flags;
// TODO Can currently not trust the material components, that should change!
if (new_entry)
{
m_ids.insert(m_ids.begin() + index, id);
m_component_flag_counts.insert(m_component_flag_counts.begin() + index, src_component_flags);
}
auto& dst_component_flags = m_component_flag_counts[index];
[&]<auto... Is>(std::integer_sequence<Is...>)
{
if (const auto& component_opt = std::get<Is>(material.data))
const auto is_component_enabled = src_component_flags & component_flag_type{ 1 } << Is;
const auto was_component_enabled = (
new_entry
? static_cast<bool>(dst_component_flags & component_flag_type{ 1 } << Is)
: component_flag_type{}
);
const auto& src_component = std::get<Is>(data.components);
auto& dst_component_array = std::get<Is>(m_component_arrays);
const auto component_index = it.m_offsets[Is];
const auto dst_component_it = dst_component_array.begin() + component_index;
if (is_component_enabled)
{
std::get<Is>(material.data).push_back(*component_opt);
component_flags |= component_flag_type{ 1 } << Is;
if (was_component_enabled)
{
*dst_component_it = *src_component;
}
else
{
dst_component_array.insert(dst_component_it, *src_component);
}
}
else if (was_component_enabled)
{
dst_component_array.erase(dst_component_it);
}
}
(std::index_sequence_for<Ts...>{});
m_component_flag_counts.push_back(component_flags);
dst_component_flags = src_component_flags;
return id;
return new_entry;
}
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)
std::pair<typename assets::detail::generic_material_store<z3d::structure<Ts...>>::iterator, bool> assets::detail::generic_material_store<z3d::structure<Ts...>>::unsafe_find(id_type id)
{
const auto id_it = std::ranges::upper_bound(m_ids, id);
const auto it = std::ranges::lower_bound(m_ids, id);
const auto match = (
id_it != m_ids.begin() and
*std::prev(id_it) == id
);
const auto found = it != m_ids.end() and *it == id;
const auto index = std::distance(m_ids.begin(), it);
const auto index = id_it - m_ids.begin() - match;
return { begin() + index, found };
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
std::pair<typename assets::detail::generic_material_store<z3d::structure<Ts...>>::const_iterator, bool> assets::detail::generic_material_store<z3d::structure<Ts...>>::unsafe_find(id_type id) const
{
const auto id_it = std::ranges::upper_bound(m_ids, id);
const auto it = std::ranges::lower_bound(m_ids, id);
const auto match = (
id_it != m_ids.begin() and
*std::prev(id_it) == id
);
const auto found = it != m_ids.end() and *it == id;
const auto index = std::distance(m_ids.begin(), it);
const auto index = id_it - m_ids.begin() - match;
auto it = begin();
it += index;
return { it, match };
return { begin() + index, found };
}
template<typename... Ts>
void assets::detail::generic_material_store<Ts...>::remove(const iterator_type& it)
void assets::detail::generic_material_store<z3d::structure<Ts...>>::remove(const iterator& it)
{
auto lock = std::unique_lock{ m_mutex };
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]), ...);
auto& component_array = std::get<Is>(m_component_arrays);
(component_array.erase(component_array.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()
void assets::detail::generic_material_store<z3d::structure<Ts...>>::clear()
{
auto lock = std::unique_lock{ m_mutex };
m_ids.clear();
[&]<auto... Is>(std::index_sequence<Is>)
{
@@ -315,9 +370,19 @@ void assets::detail::generic_material_store<Ts...>::clear()
}
template<typename... Ts>
typename assets::detail::generic_material_store<Ts...>::iterator_type assets::detail::generic_material_store<Ts...>::begin()
std::shared_lock<std::shared_mutex> assets::detail::generic_material_store<z3d::structure<Ts...>>::acquire_read_lock() const {
return std::shared_lock{ m_mutex };
}
template<typename... Ts>
std::unique_lock<std::shared_mutex> assets::detail::generic_material_store<z3d::structure<Ts...>>::acquire_write_lock() {
return std::unique_lock{ m_mutex };
}
template<typename... Ts>
typename assets::detail::generic_material_store<z3d::structure<Ts...>>::iterator assets::detail::generic_material_store<z3d::structure<Ts...>>::begin()
{
return iterator_type{
return iterator{
m_ids.data(),
component_iterators(),
m_component_flag_counts.data(),
@@ -327,9 +392,9 @@ typename assets::detail::generic_material_store<Ts...>::iterator_type assets::de
}
template<typename... Ts>
typename assets::detail::generic_material_store<Ts...>::iterator_type assets::detail::generic_material_store<Ts...>::end()
typename assets::detail::generic_material_store<z3d::structure<Ts...>>::iterator assets::detail::generic_material_store<z3d::structure<Ts...>>::end()
{
return iterator_type{
return iterator{
m_ids.data(),
component_iterators(),
m_component_flag_counts.data(),
@@ -339,7 +404,7 @@ typename assets::detail::generic_material_store<Ts...>::iterator_type assets::de
}
template<typename... Ts>
typename assets::detail::generic_material_store<Ts...>::const_iterator assets::detail::generic_material_store<Ts...>::begin() const
typename assets::detail::generic_material_store<z3d::structure<Ts...>>::const_iterator assets::detail::generic_material_store<z3d::structure<Ts...>>::begin() const
{
return const_iterator{
m_ids.data(),
@@ -351,7 +416,7 @@ typename assets::detail::generic_material_store<Ts...>::const_iterator assets::d
}
template<typename... Ts>
typename assets::detail::generic_material_store<Ts...>::const_iterator assets::detail::generic_material_store<Ts...>::end() const
typename assets::detail::generic_material_store<z3d::structure<Ts...>>::const_iterator assets::detail::generic_material_store<z3d::structure<Ts...>>::end() const
{
return const_iterator{
m_ids.data(),
@@ -363,24 +428,13 @@ typename assets::detail::generic_material_store<Ts...>::const_iterator assets::d
}
template<typename... Ts>
typename assets::detail::generic_material_store<Ts...>::const_iterator assets::detail::generic_material_store<Ts...>::cbegin() const
typename assets::detail::generic_material_store<z3d::structure<Ts...>>::const_iterator assets::detail::generic_material_store<z3d::structure<Ts...>>::cbegin() const
{
return const_cast<const generic_material_store*>(this)->begin();
return this->begin();
}
template<typename... Ts>
typename assets::detail::generic_material_store<Ts...>::const_iterator assets::detail::generic_material_store<Ts...>::cend() const
typename assets::detail::generic_material_store<z3d::structure<Ts...>>::const_iterator assets::detail::generic_material_store<z3d::structure<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() };
return this->end();
}

View File

@@ -8,6 +8,8 @@
#include <cstddef>
#include <type_traits>
#include <algorithm>
#include <mutex>
#include "util/vector_replace_range.hpp"
template<typename... Ts>
assets::detail::generic_mesh_store_iterator<Ts...>::generic_mesh_store_iterator(
@@ -16,7 +18,7 @@ assets::detail::generic_mesh_store_iterator<Ts...>::generic_mesh_store_iterator(
const component_iterator_type& components,
material_id_iterator_type material_ids,
flag_count_iterator_type flag_counts,
std::size_t index,
const size_type index,
const offsets_type& offsets
) :
m_ids{ ids },
@@ -162,14 +164,14 @@ void assets::detail::generic_mesh_store_iterator<Ts...>::calc_offsets(
while (n--)
{
const auto& [ flags, index_count, component_count ] = m_flag_counts[m_index];
const auto& [ flags, triangle_count, component_count ] = m_flag_counts[m_index];
std::get<0>(m_offsets) += step * index_count;
std::get<0>(m_offsets) += step * difference_type{ triangle_count };
([&] {
if (is_component_enabled<Is>(flags))
{
std::get<1 + Is>(m_offsets) += step * component_count;
std::get<1 + Is>(m_offsets) += step * difference_type{ component_count };
}
}(), ...);
@@ -182,15 +184,15 @@ 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];
const auto& [ flags, triangle_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
.triangles = std::span(
&m_triangles[m_offsets[0]],
triangle_count
),
.vertex_component_arrays = std::make_tuple(
std::span(
@@ -205,7 +207,7 @@ assets::detail::generic_mesh_store_iterator<Ts...>::dereference(std::index_seque
}
template<typename... Ts>
std::tuple<std::add_pointer_t<Ts>...> assets::detail::generic_mesh_store<Ts...>::component_iterators()
std::tuple<std::add_pointer_t<Ts>...> assets::detail::generic_mesh_store<z3d::structure<Ts...>>::component_iterators()
{
return [&]<auto... Is>(std::index_sequence<Is>)
{
@@ -215,7 +217,7 @@ std::tuple<std::add_pointer_t<Ts>...> assets::detail::generic_mesh_store<Ts...>:
}
template<typename... Ts>
std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> assets::detail::generic_mesh_store<Ts...>::component_iterators() const
std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> assets::detail::generic_mesh_store<z3d::structure<Ts...>>::component_iterators() const
{
return [&]<auto... Is>(std::index_sequence<Is>)
{
@@ -225,13 +227,13 @@ std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> assets::detail::generic_
}
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
std::array<typename assets::detail::generic_mesh_store<z3d::structure<Ts...>>::count_type, 1 + sizeof...(Ts)>
assets::detail::generic_mesh_store<z3d::structure<Ts...>>::array_counts() const
{
return [&]<auto... Is>(std::index_sequence<Is>)
{
return std::array{
m_indices.size(),
m_triangles.size(),
std::get<Is>(m_component_arrays).size()...
};
}
@@ -239,129 +241,191 @@ assets::detail::generic_mesh_store<Ts...>::array_counts() const
}
template<typename... Ts>
typename assets::detail::generic_mesh_store<Ts...>::id_type assets::detail::generic_mesh_store<Ts...>::add(
const mesh_data& mesh
) {
bool assets::detail::generic_mesh_store<z3d::structure<Ts...>>::insert(const id_type id, const data_type& data)
{
auto lock = std::unique_lock{ m_mutex };
const auto id = id_type{ m_next_data_id.index++ };
m_ids.push_back(id);
const auto result = unsafe_find(id);
const auto& vertices = mesh.vertices;
const auto& triangles = mesh.triangles();
const auto indices = std::span(triangles.front().data(), triangles.size() * 3);
return unsafe_insert(result.first, id, data);
}
auto component_flags = component_flag_type{};
auto min_component_count = count_type{};
template<typename... Ts>
bool assets::detail::generic_mesh_store<z3d::structure<Ts...>>::insert(iterator it, const id_type id, const data_type& data)
{
auto lock = std::unique_lock{ m_mutex };
return unsafe_insert(it, id, data);
}
template<typename... Ts>
std::pair<typename assets::detail::generic_mesh_store<z3d::structure<Ts...>>::iterator, bool> assets::detail::generic_mesh_store<z3d::structure<Ts...>>::find(id_type id)
{
auto lock = std::shared_lock{ m_mutex };
return unsafe_find(id);
}
template<typename... Ts>
std::pair<typename assets::detail::generic_mesh_store<z3d::structure<Ts...>>::const_iterator, bool> assets::detail::generic_mesh_store<z3d::structure<Ts...>>::find(id_type id) const
{
auto lock = std::shared_lock{ m_mutex };
return unsafe_find(id);
}
template<typename... Ts>
bool assets::detail::generic_mesh_store<z3d::structure<Ts...>>::unsafe_insert(iterator it, const id_type id, const data_type& data)
{
const auto index = it.m_index;
const auto new_entry = index == m_ids.size() or m_ids[index] != id;
const auto src_component_flags = data.component_flags;
// TODO Can currently not trust the material components, that should change!
auto vertex_count = (
data.component_flags == component_flag_type{}
? count_type{}
: std::numeric_limits<count_type>::max()
);
// finding out correct component flags and count
[&]<auto... Is>(std::integer_sequence<Is...>)
{
const auto& component_array = std::get<Is>(vertices);
const auto& component_array = std::get<Is>(data.component_arrays);
if (not component_array.empty())
{
// TODO check count
const auto component_count = static_cast<count_type>(component_array.size());
if (min_component_count != 0 and component_count < min_component_count)
if (component_count != 0 and component_count < vertex_count)
{
min_component_count = component_count;
vertex_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());
auto dst_component_flags = component_flag_type{};
auto dst_index_count = count_type{};
auto dst_vertex_count = count_type{};
const auto src_component_flag_count = std::tuple<component_flag_type, count_type, count_type>{
src_component_flags,
data.triangles().size(),
vertex_count
};
if (new_entry) {
m_ids.insert(m_ids.begin() + index, id);
m_component_flag_counts.insert(
m_component_flag_counts.begin() + index,
src_component_flag_count
);
m_material_ids.insert(m_material_ids.begin() + index, data.material());
}
else
{
std::tie(dst_component_flags, dst_index_count, dst_vertex_count) = m_component_flag_counts[index];
m_component_flag_counts[index] = src_component_flag_count;
m_material_ids[index] = data.material();
}
// TODO check
const auto dst_triangle_it = m_triangles.begin() + it.m_offsets.front();
ztu::replace_range(
m_triangles,
dst_triangle_it,
dst_triangle_it + dst_index_count,
data.triangles().begin(),
data.triangles().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);
const auto is_component_enabled = src_component_flags & component_flag_type{ 1 } << Is;
const auto was_component_enabled = (
new_entry
? static_cast<bool>(dst_component_flags & component_flag_type{ 1 } << Is)
: component_flag_type{}
);
if (not src_array.empty())
{
dst_array.insert(dst_array.end(), src_array.begin(), src_array.begin() + min_component_count);
}
const auto& src_component_array = std::get<Is>(data.component_arrays);
auto& dst_component_array = std::get<Is>(m_component_arrays);
const auto component_index = it.m_offsets[1 + Is];
const auto dst_component_it = dst_component_array.begin() + component_index;
ztu::replace_range(
dst_component_array,
dst_component_it,
dst_component_it + dst_vertex_count,
src_component_array.begin(),
src_component_array.begin() + vertex_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;
return new_entry;
}
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)
std::pair<typename assets::detail::generic_mesh_store<z3d::structure<Ts...>>::iterator, bool> assets::detail::generic_mesh_store<z3d::structure<Ts...>>::unsafe_find(id_type id)
{
const auto id_it = std::ranges::upper_bound(m_ids, id);
const auto it = std::ranges::lower_bound(m_ids, id);
const auto match = (
id_it != m_ids.begin() and
*std::prev(id_it) == id
);
const auto found = it != m_ids.end() and *it == id;
const auto index = std::distance(m_ids.begin(), it);
const auto index = id_it - m_ids.begin() - match;
auto it = begin();
it += index;
return { it, match };
return { begin() + index, found };
}
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
std::pair<typename assets::detail::generic_mesh_store<z3d::structure<Ts...>>::const_iterator, bool> assets::detail::generic_mesh_store<z3d::structure<Ts...>>::unsafe_find(id_type id) const
{
const auto id_it = std::ranges::upper_bound(m_ids, id);
const auto it = std::ranges::lower_bound(m_ids, id);
const auto match = (
id_it != m_ids.begin() and
*std::prev(id_it) == id
);
const auto found = it != m_ids.end() and *it == id;
const auto index = std::distance(m_ids.begin(), it);
const auto index = id_it - m_ids.begin() - match;
auto it = begin();
it += index;
return { it, match };
return { begin() + index, found };
}
template<typename... Ts>
void assets::detail::generic_mesh_store<Ts...>::remove(const iterator_type& it)
void assets::detail::generic_mesh_store<z3d::structure<Ts...>>::remove(const iterator& it)
{
m_ids.erase(m_ids.begin() + it.m_index);
auto lock = std::unique_lock{ m_mutex };
m_indices.erase(m_indices.begin() + it.m_offsets[0]);
const auto index = it.m_index;
const auto [ component_flags, triangle_count, vertex_count ] = m_component_flag_counts[index];
m_ids.erase(m_ids.begin() + index);
m_triangles.erase(m_triangles.begin() + it.m_offsets[0], triangle_count);
m_component_flag_counts.erase(m_component_flag_counts.begin() + index);
[&]<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);
if ( component_flags & component_flag_type{ 1 } << Is)
{
auto& component_array = std::get<Is>(m_component_arrays);
const auto component_it = component_array.begin() + it.m_offsets[1 + Is];
component_array.erase(component_it, component_it + vertex_count);
}
}(), ...);
} (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);
m_material_ids.erase(m_material_ids.begin() + index);
}
template<typename... Ts>
void assets::detail::generic_mesh_store<Ts...>::clear()
void assets::detail::generic_mesh_store<z3d::structure<Ts...>>::clear()
{
auto lock = std::unique_lock{ m_mutex };
m_ids.clear();
m_indices.clear();
m_triangles.clear();
[&]<auto... Is>(std::index_sequence<Is>)
{
std::get<Is>(m_component_arrays).clear();
@@ -371,11 +435,21 @@ void assets::detail::generic_mesh_store<Ts...>::clear()
}
template<typename... Ts>
typename assets::detail::generic_mesh_store<Ts...>::iterator_type assets::detail::generic_mesh_store<Ts...>::begin()
std::shared_lock<std::shared_mutex> assets::detail::generic_mesh_store<z3d::structure<Ts...>>::acquire_read_lock() const {
return std::shared_lock{ m_mutex };
}
template<typename... Ts>
std::unique_lock<std::shared_mutex> assets::detail::generic_mesh_store<z3d::structure<Ts...>>::acquire_write_lock() {
return std::unique_lock{ m_mutex };
}
template<typename... Ts>
typename assets::detail::generic_mesh_store<z3d::structure<Ts...>>::iterator assets::detail::generic_mesh_store<z3d::structure<Ts...>>::begin()
{
return iterator_type{
return iterator{
m_ids.data(),
m_indices.data(),
m_triangles.data(),
component_iterators(),
m_material_ids.data(),
m_component_flag_counts.data(),
@@ -385,25 +459,25 @@ typename assets::detail::generic_mesh_store<Ts...>::iterator_type assets::detail
}
template<typename... Ts>
typename assets::detail::generic_mesh_store<Ts...>::iterator_type assets::detail::generic_mesh_store<Ts...>::end()
typename assets::detail::generic_mesh_store<z3d::structure<Ts...>>::iterator assets::detail::generic_mesh_store<z3d::structure<Ts...>>::end()
{
return iterator_type{
return iterator{
m_ids.data(),
m_indices.data(),
m_triangles.data(),
component_iterators(),
m_material_ids.data(),
m_component_flag_counts.data(),
m_component_flag_counts.size(),
m_ids.size(),
array_counts()
};
}
template<typename... Ts>
typename assets::detail::generic_mesh_store<Ts...>::const_iterator assets::detail::generic_mesh_store<Ts...>::begin() const
typename assets::detail::generic_mesh_store<z3d::structure<Ts...>>::const_iterator assets::detail::generic_mesh_store<z3d::structure<Ts...>>::begin() const
{
return const_iterator{
m_ids.data(),
m_indices.data(),
m_triangles.data(),
component_iterators(),
m_material_ids.data(),
m_component_flag_counts.data(),
@@ -413,11 +487,11 @@ typename assets::detail::generic_mesh_store<Ts...>::const_iterator assets::detai
}
template<typename... Ts>
typename assets::detail::generic_mesh_store<Ts...>::const_iterator assets::detail::generic_mesh_store<Ts...>::end() const
typename assets::detail::generic_mesh_store<z3d::structure<Ts...>>::const_iterator assets::detail::generic_mesh_store<z3d::structure<Ts...>>::end() const
{
return const_iterator{
m_ids.data(),
m_indices.data(),
m_triangles.data(),
component_iterators(),
m_material_ids.data(),
m_component_flag_counts.data(),
@@ -427,24 +501,13 @@ typename assets::detail::generic_mesh_store<Ts...>::const_iterator assets::detai
}
template<typename... Ts>
typename assets::detail::generic_mesh_store<Ts...>::const_iterator assets::detail::generic_mesh_store<Ts...>::cbegin() const
typename assets::detail::generic_mesh_store<z3d::structure<Ts...>>::const_iterator assets::detail::generic_mesh_store<z3d::structure<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
typename assets::detail::generic_mesh_store<z3d::structure<Ts...>>::const_iterator assets::detail::generic_mesh_store<z3d::structure<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() };
}

View File

@@ -13,8 +13,8 @@ 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,
flag_count_iterator_type flag_counts,
const size_type index,
const offsets_type& offsets
) :
m_ids{ ids },
@@ -196,7 +196,7 @@ assets::detail::generic_point_cloud_store_iterator<Ts...>::dereference(std::inde
}
template<typename... Ts>
std::tuple<std::add_pointer_t<Ts>...> assets::detail::generic_point_cloud_store<Ts...>::component_iterators()
std::tuple<std::add_pointer_t<Ts>...> assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::component_iterators()
{
return [&]<auto... Is>(std::index_sequence<Is>)
{
@@ -206,7 +206,7 @@ std::tuple<std::add_pointer_t<Ts>...> assets::detail::generic_point_cloud_store<
}
template<typename... Ts>
std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> assets::detail::generic_point_cloud_store<Ts...>::component_iterators() const
std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::component_iterators() const
{
return [&]<auto... Is>(std::index_sequence<Is>)
{
@@ -216,8 +216,8 @@ std::tuple<std::add_pointer_t<std::add_const_t<Ts>>...> assets::detail::generic_
}
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
std::array<typename assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::count_type, 1 + sizeof...(Ts)>
assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::array_counts() const
{
return [&]<auto... Is>(std::index_sequence<Is>)
{
@@ -229,113 +229,163 @@ assets::detail::generic_point_cloud_store<Ts...>::array_counts() const
}
template<typename... Ts>
typename assets::detail::generic_point_cloud_store<Ts...>::id_type assets::detail::generic_point_cloud_store<Ts...>::add(
const id_type id,
const data_type& point_cloud
) {
bool assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::insert(const id_type id, const data_type& data)
{
auto lock = std::unique_lock{ m_mutex };
m_ids.push_back(id);
const auto result = unsafe_find(id);
const auto& vertices = point_cloud.component_arrays;
return unsafe_insert(result.first, id, data);
}
auto component_flags = component_flag_type{};
auto min_component_count = count_type{};
template<typename... Ts>
std::pair<typename assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::iterator, bool> assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::find(id_type id)
{
auto lock = std::shared_lock{ m_mutex };
return unsafe_find(id);
}
template<typename... Ts>
std::pair<typename assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::const_iterator, bool> assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::find(id_type id) const
{
auto lock = std::shared_lock{ m_mutex };
return unsafe_find(id);
}
template<typename... Ts>
bool assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::unsafe_insert(iterator it, const id_type id, const data_type& data)
{
const auto index = it.m_index;
const auto new_entry = index == m_ids.size() or m_ids[index] != id;
const auto src_component_flags = data.component_flags;
// TODO Can currently not trust the material components, that should change!
auto vertex_count = (
data.component_flags == component_flag_type{}
? count_type{}
: std::numeric_limits<count_type>::max()
);
// finding out correct component flags and count
[&]<auto... Is>(std::integer_sequence<Is...>)
{
const auto& component_array = std::get<Is>(vertices);
const auto& component_array = std::get<Is>(data.component_arrays);
if (not component_array.empty())
{
// TODO check count
const auto component_count = static_cast<count_type>(component_array.size());
if (min_component_count != 0 and component_count < min_component_count)
if (component_count != 0 and component_count < vertex_count)
{
min_component_count = component_count;
vertex_count = component_count;
}
component_flags |= component_flag_type{ 1 } << Is;
}
}
(std::index_sequence_for<Ts...>{});
// Insert vertex components
auto dst_component_flags = component_flag_type{};
auto dst_index_count = count_type{};
auto dst_vertex_count = count_type{};
const auto src_component_flag_count = std::tuple<component_flag_type, count_type>{
src_component_flags,
vertex_count
};
if (new_entry) {
m_ids.insert(m_ids.begin() + index, id);
m_component_flag_counts.insert(
m_component_flag_counts.begin() + index,
src_component_flag_count
);
}
else
{
std::tie(dst_component_flags, dst_index_count, dst_vertex_count) = m_component_flag_counts[index];
m_component_flag_counts[index] = src_component_flag_count;
}
[&]<auto... Is>(std::integer_sequence<Is...>)
{
const auto& src_array = std::get<Is>(vertices);
auto& dst_array = std::get<Is>(m_component_arrays);
const auto is_component_enabled = src_component_flags & component_flag_type{ 1 } << Is;
const auto was_component_enabled = (
new_entry
? static_cast<bool>(dst_component_flags & component_flag_type{ 1 } << Is)
: component_flag_type{}
);
if (not src_array.empty())
{
dst_array.insert(dst_array.end(), src_array.begin(), src_array.begin() + min_component_count);
}
const auto& src_component_array = std::get<Is>(data.component_arrays);
auto& dst_component_array = std::get<Is>(m_component_arrays);
const auto component_index = it.m_offsets[1 + Is];
const auto dst_component_it = dst_component_array.begin() + component_index;
ztu::replace_range(
dst_component_array,
dst_component_it,
dst_component_it + dst_vertex_count,
src_component_array.begin(),
src_component_array.begin() + vertex_count
);
}
(std::index_sequence_for<Ts...>{});
// TODO check count
m_component_flag_counts.emplace_back(
point_cloud.component_flags,
min_component_count
);
return id;
return new_entry;
}
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)
std::pair<typename assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::iterator, bool> assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::unsafe_find(id_type id)
{
const auto id_it = std::ranges::upper_bound(m_ids, id);
const auto it = std::ranges::lower_bound(m_ids, id);
const auto match = (
id_it != m_ids.begin() and
*std::prev(id_it) == id
);
const auto found = it != m_ids.end() and *it == id;
const auto index = std::distance(m_ids.begin(), it);
const auto index = id_it - m_ids.begin() - match;
auto it = begin();
it += index;
return { it, match };
return { begin() + index, found };
}
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
std::pair<typename assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::const_iterator, bool> assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::unsafe_find(id_type id) const
{
const auto id_it = std::ranges::upper_bound(m_ids, id);
const auto it = std::ranges::lower_bound(m_ids, id);
const auto match = (
id_it != m_ids.begin() and
*std::prev(id_it) == id
);
const auto found = it != m_ids.end() and *it == id;
const auto index = std::distance(m_ids.begin(), it);
const auto index = id_it - m_ids.begin() - match;
auto it = begin();
it += index;
return { it, match };
return { begin() + index, found };
}
template<typename... Ts>
void assets::detail::generic_point_cloud_store<Ts...>::remove(const iterator_type& it)
void assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::remove(const iterator& it)
{
auto lock = std::unique_lock{ m_mutex };
const auto index = it.m_index;
const auto [ component_flags, triangle_count, vertex_count ] = m_component_flag_counts[index];
m_ids.erase(m_ids.begin() + index);
m_component_flag_counts.erase(m_component_flag_counts.begin() + index);
[&]<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);
if ( component_flags & component_flag_type{ 1 } << Is)
{
auto& component_array = std::get<Is>(m_component_arrays);
const auto component_it = component_array.begin() + it.m_offsets[1 + Is];
component_array.erase(component_it, component_it + vertex_count);
}
}(), ...);
} (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()
void assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::clear()
{
auto lock = std::unique_lock{ m_mutex };
m_ids.clear();
[&]<auto... Is>(std::index_sequence<Is>)
{
@@ -345,9 +395,19 @@ void assets::detail::generic_point_cloud_store<Ts...>::clear()
}
template<typename... Ts>
typename assets::detail::generic_point_cloud_store<Ts...>::iterator_type assets::detail::generic_point_cloud_store<Ts...>::begin()
std::shared_lock<std::shared_mutex> assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::acquire_read_lock() const {
return std::shared_lock{ m_mutex };
}
template<typename... Ts>
std::unique_lock<std::shared_mutex> assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::acquire_write_lock() {
return std::unique_lock{ m_mutex };
}
template<typename... Ts>
typename assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::iterator assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::begin()
{
return iterator_type{
return iterator{
m_ids.data(),
component_iterators(),
m_component_flag_counts.data(),
@@ -357,9 +417,9 @@ typename assets::detail::generic_point_cloud_store<Ts...>::iterator_type assets:
}
template<typename... Ts>
typename assets::detail::generic_point_cloud_store<Ts...>::iterator_type assets::detail::generic_point_cloud_store<Ts...>::end()
typename assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::iterator assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::end()
{
return iterator_type{
return iterator{
m_ids.data(),
component_iterators(),
m_component_flag_counts.data(),
@@ -369,7 +429,7 @@ typename assets::detail::generic_point_cloud_store<Ts...>::iterator_type assets:
}
template<typename... Ts>
typename assets::detail::generic_point_cloud_store<Ts...>::const_iterator assets::detail::generic_point_cloud_store<Ts...>::begin() const
typename assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::const_iterator assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::begin() const
{
return const_iterator{
m_ids.data(),
@@ -381,7 +441,7 @@ typename assets::detail::generic_point_cloud_store<Ts...>::const_iterator assets
}
template<typename... Ts>
typename assets::detail::generic_point_cloud_store<Ts...>::const_iterator assets::detail::generic_point_cloud_store<Ts...>::end() const
typename assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::const_iterator assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::end() const
{
return const_iterator{
m_ids.data(),
@@ -393,13 +453,13 @@ typename assets::detail::generic_point_cloud_store<Ts...>::const_iterator assets
}
template<typename... Ts>
typename assets::detail::generic_point_cloud_store<Ts...>::const_iterator assets::detail::generic_point_cloud_store<Ts...>::cbegin() const
typename assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::const_iterator assets::detail::generic_point_cloud_store<z3d::structure<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
typename assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::const_iterator assets::detail::generic_point_cloud_store<z3d::structure<Ts...>>::cend() const
{
return const_cast<const generic_point_cloud_store*>(this)->end();
}

View File

@@ -15,7 +15,7 @@ assets::pose_list_store_iterator<Char>::pose_list_store_iterator(
id_iterator_type ids,
pose_iterator_type poses,
length_iterator_type lengths,
std::size_t index,
const size_type index,
const offset_type& offset
) :
m_ids{ ids },
@@ -169,62 +169,94 @@ assets::pose_list_store_iterator<Char>::dereference() const
);
}
assets::pose_list_store::id_type assets::pose_list_store::add(
const pose_list_id id,
const pose_list_data& pose_list
) {
inline bool assets::pose_list_store::insert(const id_type id, const data_type& data)
{
auto lock = std::unique_lock{ m_mutex };
m_ids.push_back(id);
const auto result = find(id);
m_poses.insert(m_poses.end(), pose_list.begin(), pose_list.end());
m_lengths.push_back(pose_list.size());
return id;
return insert(result.first, id, data);
}
std::pair<assets::pose_list_store::iterator_type, bool> assets::pose_list_store::find(id_type id)
inline std::pair<assets::pose_list_store::iterator, bool> assets::pose_list_store::find(id_type id)
{
const auto id_it = std::ranges::upper_bound(m_ids, id);
auto lock = std::shared_lock{ m_mutex };
const auto match = (
id_it != m_ids.begin() and
*std::prev(id_it) == id
return unsafe_find(id);
}
inline std::pair<assets::pose_list_store::const_iterator, bool> assets::pose_list_store::find(id_type id) const
{
auto lock = std::shared_lock{ m_mutex };
return unsafe_find(id);
}
inline bool assets::pose_list_store::unsafe_insert(iterator it, const id_type id, const data_type& data)
{
const auto index = it.m_index;
const auto new_entry = index == m_ids.size() or m_ids[index] != id;
// TODO Can currently not trust the material components, that should change!
auto dst_pose_count = count_type{};
const auto src_pose_count = data.size();
if (new_entry) {
m_ids.insert(m_ids.begin() + index, id);
m_lengths.insert(m_lengths.begin() + index, src_pose_count);
}
else
{
dst_pose_count = m_lengths[index];
m_lengths[index] = src_pose_count;
}
const auto dst_pose_it = m_poses.begin() + it.m_offset;
ztu::replace_range(
m_poses,
dst_pose_it,
dst_pose_it + dst_pose_count,
data.begin(),
data.begin() + src_pose_count
);
const auto index = id_it - m_ids.begin() - match;
auto it = begin();
it += index;
return { it, match };
return new_entry;
}
std::pair<assets::pose_list_store::const_iterator, bool> assets::pose_list_store::find(id_type id) const
inline std::pair<assets::pose_list_store::iterator, bool> assets::pose_list_store::unsafe_find(id_type id)
{
const auto id_it = std::ranges::upper_bound(m_ids, id);
const auto it = std::ranges::lower_bound(m_ids, id);
const auto match = (
id_it != m_ids.begin() and
*std::prev(id_it) == id
);
const auto found = it != m_ids.end() and *it == id;
const auto index = std::distance(m_ids.begin(), it);
const auto index = id_it - m_ids.begin() - match;
auto it = begin();
it += index;
return { it, match };
return { begin() + index, found };
}
void assets::pose_list_store::remove(const iterator_type& it)
inline std::pair<assets::pose_list_store::const_iterator, bool> assets::pose_list_store::unsafe_find(id_type id) const
{
m_ids.erase(m_ids.begin() + it.m_index);
const auto it = std::ranges::lower_bound(m_ids, id);
const auto begin = m_poses.begin() + it.m_offset;
const auto end = begin + it.m_lengths[it.m_index];
m_poses.erase(begin, end);
const auto found = it != m_ids.end() and *it == id;
const auto index = std::distance(m_ids.begin(), it);
m_lengths.erase(m_lengths.begin() + it.m_index);
return { begin() + index, found };
}
void assets::pose_list_store::remove(const iterator& it)
{
const auto index = it.m_index;
m_ids.erase(m_ids.begin() + index);
const auto poses_it = m_poses.begin() + it.m_offset;
m_poses.erase(poses_it, poses_it + m_lengths[index]);
m_lengths.erase(m_lengths.begin() + index);
}
void assets::pose_list_store::clear()
@@ -234,9 +266,17 @@ void assets::pose_list_store::clear()
m_lengths.clear();
}
assets::pose_list_store::iterator_type assets::pose_list_store::begin()
std::shared_lock<std::shared_mutex> assets::pose_list_store::acquire_read_lock() const {
return std::shared_lock{ m_mutex };
}
std::unique_lock<std::shared_mutex> assets::pose_list_store::acquire_write_lock() {
return std::unique_lock{ m_mutex };
}
assets::pose_list_store::iterator assets::pose_list_store::begin()
{
return iterator_type{
return iterator{
m_ids.data(),
m_poses.data(),
m_lengths.data(),
@@ -245,9 +285,9 @@ assets::pose_list_store::iterator_type assets::pose_list_store::begin()
};
}
assets::pose_list_store::iterator_type assets::pose_list_store::end()
assets::pose_list_store::iterator assets::pose_list_store::end()
{
return iterator_type{
return iterator{
m_ids.data(),
m_poses.data(),
m_lengths.data(),

View File

@@ -17,7 +17,7 @@ assets::shader_source_store_iterator<Char>::shader_source_store_iterator(
string_iterator_type strings,
length_iterator_type lengths,
metadata_iterator_type metadata,
std::size_t index,
const size_type index,
const offset_type& offset
) :
m_ids{ ids },
@@ -172,65 +172,90 @@ assets::shader_source_store_iterator<Char>::dereference() const
);
}
assets::shader_source_store::id_type assets::shader_source_store::add(
const shader_source_id id,
const shader_source_data& shader_source
) {
bool assets::shader_source_store::insert(const id_type id, const data_type& data)
{
auto lock = std::unique_lock{ m_mutex };
m_ids.push_back(id);
const auto result = find(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());
m_metadata.push_back(shader_source.meta);
return id;
return insert(result.first, id, data);
}
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
template<typename... Ts>
bool assets::shader_source_store::insert(iterator it, const id_type id, const data_type& data)
{
auto lock = std::unique_lock{ m_mutex };
const auto index = it.m_index;
const auto new_entry = index == m_ids.size() or m_ids[index] != id;
auto dst_source_length = count_type{};
const auto src_source_length = data.source.size();
if (new_entry) {
m_ids.insert(m_ids.begin() + index, id);
m_lengths.insert(m_lengths.begin() + index, src_source_length);
m_metadata.insert(m_metadata.begin() + index, data.meta);
}
else
{
dst_source_length = m_lengths[index];
m_lengths[index] = src_source_length;
m_metadata[index] = data.meta;
}
const auto dst_string_it = m_strings.begin() + it.m_offset;
ztu::replace_range(
m_strings,
dst_string_it,
dst_string_it + dst_source_length,
data.source.begin(),
data.source.end()
);
const auto index = id_it - m_ids.begin() - match;
if (new_entry)
{
m_strings.insert(m_strings.begin() + it.m_offset + src_source_length, '\0');
}
auto it = begin();
it += index;
return { it, match };
return new_entry;
}
std::pair<assets::shader_source_store::const_iterator, bool> assets::shader_source_store::find(id_type id) const
inline std::pair<assets::shader_source_store::iterator, bool> assets::shader_source_store::find(id_type id)
{
const auto id_it = std::ranges::upper_bound(m_ids, id);
auto lock = std::shared_lock{ m_mutex };
const auto match = (
id_it != m_ids.begin() and
*std::prev(id_it) == id
);
const auto it = std::ranges::lower_bound(m_ids, id);
const auto index = id_it - m_ids.begin() - match;
const auto found = it != m_ids.end() and *it == id;
const auto index = std::distance(m_ids.begin(), it);
auto it = begin();
it += index;
return { it, match };
return { begin() + index, found };
}
void assets::shader_source_store::remove(const iterator_type& it)
inline std::pair<assets::shader_source_store::const_iterator, bool> assets::shader_source_store::find(id_type id) const
{
auto lock = std::shared_lock{ m_mutex };
const auto it = std::ranges::lower_bound(m_ids, id);
const auto found = it != m_ids.end() and *it == id;
const auto index = std::distance(m_ids.begin(), it);
return { begin() + index, found };
}
void assets::shader_source_store::remove(const iterator& it)
{
auto lock = std::unique_lock{ m_mutex };
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);
const auto strings_begin = m_strings.begin() + it.m_offset;
const auto strings_end = begin + it.m_lengths[it.m_index] + sizeof('\0');
m_strings.erase(strings_begin, strings_end);
m_lengths.erase(m_lengths.begin() + it.m_index);
m_metadata.erase(m_metadata.begin() + it.m_index);
@@ -238,15 +263,25 @@ void assets::shader_source_store::remove(const iterator_type& it)
void assets::shader_source_store::clear()
{
auto lock = std::unique_lock{ m_mutex };
m_ids.clear();
m_strings.clear();
m_lengths.clear();
m_metadata.clear();
}
assets::shader_source_store::iterator_type assets::shader_source_store::begin()
std::shared_lock<std::shared_mutex> assets::shader_source_store::acquire_read_lock() const {
return std::shared_lock{ m_mutex };
}
std::unique_lock<std::shared_mutex> assets::shader_source_store::acquire_write_lock() {
return std::unique_lock{ m_mutex };
}
assets::shader_source_store::iterator assets::shader_source_store::begin()
{
return iterator_type{
return iterator{
m_ids.data(),
m_strings.data(),
m_lengths.data(),
@@ -256,9 +291,9 @@ assets::shader_source_store::iterator_type assets::shader_source_store::begin()
};
}
assets::shader_source_store::iterator_type assets::shader_source_store::end()
assets::shader_source_store::iterator assets::shader_source_store::end()
{
return iterator_type{
return iterator{
m_ids.data(),
m_strings.data(),
m_lengths.data(),

View File

@@ -72,6 +72,35 @@ namespace assets::language
};
}
std::error_code assets::glsl_parser::prefetch(
path_id_lookups&
) {
// Nothing to prefetch
return {};
}
std::error_code assets::glsl_parser::load(
const path_id_lookups& lookups,
shader_source_store& store,
bool
) {
m_path_buffer.clear();
lookups.shader_sources.by_extension(".glsl", m_path_buffer);
auto store_mutex = std::mutex{};
std::for_each(
std::execution::parallel_unsequenced_policy{},
m_path_buffer.begin(),
m_path_buffer.end(),
parser_context{ store, store_mutex }
);
return {};
}
assets::glsl_parser::parser_context::parser_context(
store_type& m_store,
std::mutex& m_store_mutex
@@ -115,7 +144,7 @@ void assets::glsl_parser::parser_context::operator()(lookup_type::const_pointer
{
auto lock = std::lock_guard{ *m_store_mutex };
m_store->add(id, m_buffer);
m_store->insert(id, m_buffer);
}
}
@@ -322,35 +351,6 @@ std::error_code assets::glsl_parser::read_file(
return {};
}
std::error_code assets::glsl_parser::prefetch(
path_id_lookups&
) {
// Nothing to prefetch
return {};
}
std::error_code assets::glsl_parser::load(
const path_id_lookups& lookups,
shader_source_store& store,
bool
) {
namespace fs = std::filesystem;
m_path_buffer.clear();
lookups.shader_sources.by_extension(".glsl", m_path_buffer);
auto store_mutex = std::mutex{};
std::for_each(
std::execution::parallel_unsequenced_policy{},
m_path_buffer.begin(),
m_path_buffer.end(),
parser_context{ store, store_mutex }
);
return {};
}
bool assets::glsl_parser::parse_geometry_declaration(
const std::span<const std::string_view> values,
model_geometry::types& geometry_type

View File

@@ -28,7 +28,7 @@ assets::kitti_parser::parser_context::parser_context(
m_buffer.normals().reserve(8192);
m_buffer.colors().reserve(8192);
}
5
void assets::kitti_parser::parser_context::reset()
{
m_buffer.clear();
@@ -85,7 +85,7 @@ void assets::kitti_parser::parser_context::operator()(lookup_type::const_pointer
{
auto lock = std::lock_guard{ *m_store_mutex };
m_store->add(id, m_buffer);
m_store->insert(id, m_buffer);
}
}

View File

@@ -1,4 +1,4 @@
#include "assets/file_parsers/mtl_loader.hpp"
#include "assets/file_parsers/mtl_parser.hpp"
#include <charconv>
#include <fstream>
@@ -7,20 +7,20 @@
#include "util/logger.hpp"
#include "util/for_each.hpp"
#include "util/line_parser.hpp"
#include <execution>
#include "../../../include/assets/data_loaders"
namespace mtl_loader_error
namespace assets::mtl_parser_error
{
struct category : std::error_category
{
[[nodiscard]] const char* name() const noexcept override
{
return "mtl_loader";
return "mtl_parser";
}
[[nodiscard]] std::string message(int ev) const override
{
// TODO these are incomplete
switch (static_cast<codes>(ev))
{
using enum codes;
@@ -47,27 +47,360 @@ struct category : std::error_category
}
};
} // namespace mesh_loader_error
} // namespace mtl_parser_error
inline std::error_category& connector_error_category()
inline std::error_category& mtl_parser_error_category()
{
static mtl_loader_error::category category;
static assets::mtl_parser_error::category category;
return category;
}
namespace mtl_loader_error
namespace assets::mtl_parser_error
{
inline std::error_code make_error_code(codes e)
{
return { static_cast<int>(e), mtl_parser_error_category() };
}
} // namespace mtl_loader_error
std::error_code assets::mtl_parser::prefetch(
path_id_lookups& lookups
) {
namespace fs = std::filesystem;
using mtl_parser_error::codes;
using mtl_parser_error::make_error_code;
auto buffer = std::vector<char>(8 * 1024, '\0');
auto in = std::ifstream{};
auto path_buffer = fs::path{};
auto filename_buffer = fs::path{};
const auto process_file = [&]()
{
in.open(filename_buffer);
if (not in.is_open()) {
ztu::logger::error("Could not open .mtl file '%'", filename_buffer);
return;
}
filename_buffer.remove_filename();
find_textures(buffer, path_buffer, filename_buffer, in, queue.texture.files);
in.close();
};
// TODO properly extract
for (const auto file : paths.files)
{
filename_buffer.assign(file);
process_file();
}
for (const auto directory : paths.directories)
{
for (const auto& file : fs::directory_iterator{ directory }) {
filename_buffer.assign(file.path());
// Avoid heap allocation of .extension()
if (not std::string_view(filename_buffer.c_str()).ends_with(".obj"))
{
continue;
}
process_file();
}
}
return {};
}
std::error_code assets::mtl_parser::load(
path_id_lookups& lookups,
data_stores& stores,
bool pedantic
) {
m_path_buffer.clear();
lookups.material_libraries.by_extension(".mtl", m_path_buffer);
auto store_mutex = std::mutex{};
// TODO who protects the material id lookup
// TODO who protects the material store
std::for_each(
std::execution::parallel_unsequenced_policy{},
m_path_buffer.begin(),
m_path_buffer.end(),
parser_context{
lookups.textures,
lookups.materials,
stores.materials,
stores.material_libraries,
store_mutex
}
);
return {};
}
inline std::error_category& connector_error_category()
{
static assets::mtl_parser_error::category category;
return category;
}
namespace assets::mtl_parser_error
{
inline std::error_code make_error_code(const codes e)
{
return { static_cast<int>(e), connector_error_category() };
}
} // namespace mtl_loader_error
assets::mtl_parser::parser_context::parser_context(
const texture_id_lookup& texture_id_lookup,
material_id_lookup& material_id_lookup,
material_store& material_store,
store_type& store,
std::mutex& store_mutex
) :
m_texture_id_lookup{ &texture_id_lookup },
m_material_id_lookup{ &material_id_lookup },
m_material_store{ &material_store },
m_store{ &store },
m_store_mutex{ &store_mutex }
{
m_buffer.reserve(32);
}
void assets::mtl_parser::parser_context::reset()
{
m_buffer.clear();
}
void assets::mtl_parser::parser_context::operator()(lookup_type::const_pointer entry) noexcept
{
using mtl_parser_error::codes;
using mtl_parser_error::make_error_code;
namespace fs = std::filesystem;
const auto& [ filename, id ] = *entry;
// TODO unroll stuff
auto in = std::ifstream{ filename };
if (not in.is_open())
{
ztu::logger::warn("Cannot open mtl file %.", filename);
return;
}
const auto base_dir = fs::canonical(fs::path(filename).parent_path());
auto name = std::string{};
auto material = material_data{};
const auto push_material = [&]()
{
if (not name.empty())
{
const auto [ id_it, is_new ] = m_material_id_lookup->try_emplace(filename / name);
const auto material_id = id_it->second;
m_material_store->emplace(id, material);
m_buffer.emplace(name, material_id);
}
name = {};
material = {};
};
const auto ec = ztu::parse_lines<codes>(
in,
pedantic,
ztu::make_line_parser("newmtl ", ztu::is_not_repeating, [&](const auto& param)
{
push_material();
name = param;
return codes::ok;
}),
ztu::make_line_parser("Ka ", ztu::is_not_repeating, [&](const auto& param)
{
material_components::ambient_filter ambient_filter;
if (parse_numeric_vector(param, ambient_filter) != std::errc{}) [[unlikely]]
{
return codes::malformed_ambient_color; // TODO rename to filter
}
material.ambient_filter() = ambient_filter;
material.component_flags |= material_components::flags::ambient_filter;
return codes::ok;
}),
ztu::make_line_parser("Kd ", ztu::is_not_repeating, [&](const auto& param)
{
material_components::diffuse_filter diffuse_filter;
if (parse_numeric_vector(param, diffuse_filter) != std::errc{}) [[unlikely]]
{
return codes::malformed_diffuse_color;
}
material.diffuse_filter() = diffuse_filter;
material.component_flags |= material_components::flags::diffuse_filter;
return codes::ok;
}),
ztu::make_line_parser("Ks ", ztu::is_not_repeating, [&](const auto& param)
{
material_components::specular_filter specular_filter;
if (parse_numeric_vector(param, specular_filter) != std::errc{}) [[unlikely]]
{
return codes::malformed_specular_color;
}
material.specular_filter() = specular_filter;
material.component_flags |= material_components::flags::specular_filter;
return codes::ok;
}),
ztu::make_line_parser("Ns ", ztu::is_not_repeating, [&](const auto& param)
{
z3d::vec<1, material_components::shininess> shininess;
if (parse_numeric_vector(param, shininess) != std::errc{}) [[unlikely]]
{
return codes::malformed_specular_exponent;
}
material.shininess() = shininess[0];
material.component_flags |= material_components::flags::shininess;
return codes::ok;
}),
ztu::make_line_parser("d ", ztu::is_not_repeating, [&](const auto& param)
{
z3d::vec<1, material_components::alpha> alpha{};
if (parse_numeric_vector(param, alpha) != std::errc{}) [[unlikely]]
{
return codes::malformed_dissolve;
}
material.alpha() = alpha[0];
material.component_flags |= material_components::flags::alpha;
return codes::ok;
}),
ztu::make_line_parser("map_Ka ", ztu::is_not_repeating, [&](const auto& param)
{
if (const auto texture_id = fetch_texture_id(param, "ambient filter"))
{
material.ambient_filter_texture_id() = *texture_id;
material.component_flags |= material_components::flags::ambient_filter_texture;
}
return codes::ok;
}),
ztu::make_line_parser("map_Kd ", ztu::is_not_repeating, [&](const auto& param)
{
if (const auto texture_id = fetch_texture_id(param, "diffuse filter"))
{
material.diffuse_filter_texture_id() = *texture_id;
material.component_flags |= material_components::flags::diffuse_filter_texture;
}
return codes::ok;
}),
ztu::make_line_parser("map_Ks ", ztu::is_not_repeating, [&](const auto& param)
{
if (const auto texture_id = fetch_texture_id(param, "specular filter"))
{
material.specular_filter_texture_id() = *texture_id;
material.component_flags |= material_components::flags::specular_filter_texture;
}
return codes::ok;
}),
ztu::make_line_parser("map_Ns ", ztu::is_not_repeating, [&](const auto& param)
{
if (const auto texture_id = fetch_texture_id(param, "shininess"))
{
material.shininess_texture_id() = *texture_id;
material.component_flags |= material_components::flags::shininess_texture;
}
return codes::ok;
}),
ztu::make_line_parser("map_d ", ztu::is_not_repeating, [&](const auto& param)
{
if (const auto texture_id = fetch_texture_id(param, "alpha"))
{
material.alpha_texture_id() = *texture_id;
material.component_flags |= material_components::flags::alpha_texture;
}
return codes::ok;
}),
ztu::make_line_parser("bump ", ztu::is_not_repeating, [&](const auto& param)
{
if (const auto texture_id = fetch_texture_id(param, "bump"))
{
material.bump_texture_id() = *texture_id;
material.component_flags |= material_components::flags::bump_texture;
}
return codes::ok;
})
);
if (ec != codes::ok)
{
const auto e = make_error_code(ec);
ztu::logger::error("Error while parsing mtl file %: %", filename, e.message());
}
push_material();
}
std::optional<assets::texture_id> assets::mtl_parser::parser_context::fetch_texture_id(
const std::filesystem::path& mtl_dir,
std::string_view filename,
std::string_view texture_type_name
) {
auto texture_filename = std::filesystem::path(filename);
if (texture_filename.is_relative())
{
texture_filename = mtl_dir / texture_filename;
}
const auto texture_id_it = m_texture_id_lookup->find(texture_filename);
if (texture_id_it == m_texture_id_lookup->end())
{
ztu::logger::warn(
"%-texture at % has not been registered and can therefor not be used.",
texture_type_name,
texture_filename
);
return std::nullopt;
}
return texture_id_it->second;
}
template<typename T, std::size_t Count>
std::errc parse_numeric_vector(std::string_view param, std::array<T, Count>& values)
{
auto it = param.begin(), end = param.end();
const auto end = param.end();
auto it = param.begin();
for (auto& value : values)
{
@@ -90,7 +423,9 @@ std::errc parse_numeric_vector(std::string_view param, std::array<T, Count>& val
};
void mtl_loader::find_textures(
void assets::mtl_parser::find_textures(
std::span<char> buffer,
std::filesystem::path& path_buffer,
const std::filesystem::path& base_directory,
@@ -230,356 +565,3 @@ void mtl_loader::find_textures(
}
} while (not in.eof());
}
std::error_code mtl_loader::prefetch(
const file_dir_list& paths,
prefetch_queue& queue
) {
namespace fs = std::filesystem;
using mtl_loader_error::codes;
using mtl_loader_error::make_error_code;
auto buffer = std::vector<char>(8 * 1024, '\0');
auto in = std::ifstream{};
auto path_buffer = fs::path{};
auto filename_buffer = fs::path{};
const auto process_file = [&]()
{
in.open(filename_buffer);
if (not in.is_open()) {
ztu::logger::error("Could not open .mtl file '%'", filename_buffer);
return;
}
filename_buffer.remove_filename();
find_textures(buffer, path_buffer, filename_buffer, in, queue.texture.files);
in.close();
};
for (const auto file : paths.files)
{
filename_buffer.assign(file);
process_file();
}
for (const auto directory : paths.directories)
{
for (const auto& file : fs::directory_iterator{ directory }) {
filename_buffer.assign(file.path());
// Avoid heap allocation of .extension()
if (not std::string_view(filename_buffer.c_str()).ends_with(".obj"))
{
continue;
}
process_file();
}
}
return {};
}
std::error_code mtl_loader::load_directory(
dynamic_data_loader_ctx& ctx,
dynamic_material_store& store,
material_components::flags enabled_components,
const std::filesystem::path& path,
const bool pedantic
) {
namespace fs = std::filesystem;
if (not fs::exists(path))
{
return make_error_code(std::errc::no_such_file_or_directory);
}
for (const auto& file : fs::directory_iterator{ path })
{
const auto& file_path = file.path();
if (file_path.extension() != ".obj")
{
continue;
}
if (const auto e = load(
ctx,
store,
enabled_components,
path,
pedantic
)) {
ztu::logger::error(
"Error while loading obj file '%': [%] %",
file_path,
e.category().name(),
e.message()
);
}
}
return {};
}
std::error_code mtl_loader::load(
dynamic_data_loader_ctx& ctx,
dynamic_material_store& store,
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 = material_components::flags;
const auto component_disabled = [&](const material_components::flags component) {
return (enabled_components & component) == flags::none;
};
// TODO unroll stuff
const auto textures_disabled = component_disabled(flags::ambient_filter_texture);
const auto surface_properties_disabled = component_disabled(flags::surface_properties);
const auto transparencies_disabled = component_disabled(flags::transparency);
auto in = std::ifstream{ filename };
if (not in.is_open()) {
return make_error_code(codes::cannot_open_file);
}
namespace fs = std::filesystem;
const auto directory = fs::canonical(fs::path(filename).parent_path());
auto name = std::string{};
auto material = dynamic_material_data{};
const auto push_material = [&]()
{
if (not name.empty())
{
const auto id = store.add(std::move(material));
m_id_lookup.emplace(std::move(name), id);
}
name = std::string{};
material = dynamic_material_data{};
};
const auto load_texture = [&](
const std::string_view path,
std::string_view texture_type_name,
auto&& f
) {
auto texture_filename = fs::path(path);
if (texture_filename.is_relative())
{
texture_filename = directory / texture_filename;
}
const auto extension = texture_filename.extension().string();
auto texture_type = std::string_view{ extension };
if (not texture_type.empty() and texture_type.front() == '.')
{
texture_type = texture_type.substr(1);
}
if (const auto loader_id = ctx.texture_loader.find_loader(texture_type))
{
if (auto res = ctx.texture_loader.read(
ctx,
*loader_id,
texture_filename,
pedantic
)) {
f(*res);
}
else
{
const auto error = res.error();
ztu::logger::warn(
"Error while loading % texture '%': [%] %",
texture_type_name,
path,
error.category().name(),
error.message()
);
}
}
else
{
ztu::logger::warn(
"Failed to load % texture '%' because extension is not supported.",
texture_type_name,
path
);
}
};
const auto ec = ztu::parse_lines<codes>(
in,
pedantic,
ztu::make_line_parser("newmtl ", ztu::is_not_repeating, [&](const auto& param)
{
push_material();
name = param;
return codes::ok;
}),
ztu::make_line_parser("Ka ", ztu::is_not_repeating, [&](const auto& param)
{
material_components::ambient_filter ambient_filter;
if (parse_numeric_vector(param, ambient_filter) != std::errc{}) [[unlikely]]
{
return codes::malformed_ambient_color; // TODO rename to filter
}
material.ambient_filter = mbient_filter;
material.components() |= flags::ambient_filter;
return codes::ok;
}),
ztu::make_line_parser("Kd ", ztu::is_not_repeating, [&](const auto& param)
{
if (surface_properties_disabled) return codes::ok;
auto& properties = material.initialized_surface_properties();
if (parse_numeric_vector(param, properties.diffuse_filter) != std::errc{}) [[unlikely]]
{
return codes::malformed_diffuse_color;
}
material.components() |= flags::surface_properties;
return codes::ok;
}),
ztu::make_line_parser("Ks ", ztu::is_not_repeating, [&](const auto& param)
{
if (surface_properties_disabled) return codes::ok;
auto& properties = material.initialized_surface_properties();
if (parse_numeric_vector(param, properties.specular_filter) != std::errc{}) [[unlikely]]
{
return codes::malformed_specular_color;
}
material.components() |= flags::surface_properties;
return codes::ok;
}),
ztu::make_line_parser("Ns ", ztu::is_not_repeating, [&](const auto& param)
{
if (surface_properties_disabled) return codes::ok;
auto& properties = material.initialized_surface_properties();
std::array<float, 1> shininess{};
if (parse_numeric_vector(param, shininess) != std::errc{}) [[unlikely]]
{
return codes::malformed_specular_exponent;
}
properties.shininess = shininess.front();
material.components() |= flags::surface_properties;
return codes::ok;
}),
ztu::make_line_parser("d ", ztu::is_not_repeating, [&](const auto& param)
{
if (transparencies_disabled) return codes::ok;
std::array<float, 1> transparency{};
if (parse_numeric_vector(param, transparency) != std::errc{}) [[unlikely]]
{
return codes::malformed_dissolve;
}
material.transparency().emplace(transparency.front());
material.components() |= flags::transparency;
return codes::ok;
}),
ztu::make_line_parser("map_Ka ", ztu::is_not_repeating, [&](const auto& param)
{
if (textures_disabled) return codes::ok;
load_texture(param, "ambient color", [&](const auto id) {
material.specular_filter_texture_id() = id;
material.components() |= flags::ambient_filter_texture;
});
return codes::ok;
}),
ztu::make_line_parser("map_Kd ", ztu::is_not_repeating, [&](const auto& param)
{
if (textures_disabled) return codes::ok;
load_texture(param, "diffuse color", [&](const auto id) {
material.diffuse_filter_texture_id() = id;
material.components() |= flags::diffuse_filter_texture;
});
return codes::ok;
}),
ztu::make_line_parser("map_Ks ", ztu::is_not_repeating, [&](const auto& param)
{
if (textures_disabled) return codes::ok;
load_texture(param, "specular color", [&](const auto id) {
material.specular_filter_texture_id() = id;
material.components() |= flags::specular_filter_texture;
});
return codes::ok;
}),
ztu::make_line_parser("map_Ns ", ztu::is_not_repeating, [&](const auto& param)
{
if (textures_disabled) return codes::ok;
load_texture(param, "shininess", [&](const auto id) {
material.shininess_texture_id() = id;
material.components() |= flags::shininess_texture;
});
return codes::ok;
}),
ztu::make_line_parser("map_d ", ztu::is_not_repeating, [&](const auto& param)
{
if (textures_disabled) return codes::ok;
load_texture(param, "alpha", [&](const auto id) {
material.alpha_texture_id() = id;
material.components() |= flags::alpha_texture;
});
return codes::ok;
}),
ztu::make_line_parser("bump ", ztu::is_not_repeating, [&](const auto& param)
{
if (textures_disabled) return codes::ok;
load_texture(param, "bump", [&](const auto id) {
material.bump_texture_id() = id;
material.components() |= flags::bump_texture;
});
return codes::ok;
})
);
if (ec != codes::ok)
{
return make_error_code(ec);
}
push_material();
return {};
}

View File

@@ -68,28 +68,21 @@ void zgl::shader_source_manager::process(const store_type& shader_sources)
for (const auto& [ id, shader_source ] : shader_sources)
{
const auto meta = metadata_type{
.stage = shader_source.stage,
.components = shader_source.components,
.static_enable = shader_source.static_enable,
.dynamic_enable = shader_source.dynamic_enable
};
// Sorted insert should be faster than std::sort and std::unique
// for small numbers of elements and high numbers of duplicates.
const auto it = std::ranges::upper_bound(
m_shader_source_lookup,
meta,
shader_source.meta,
prioritized_metadata_comparator{},
&entry_type::first
);
if (it != m_shader_source_lookup.end() and it->first == meta)
if (it != m_shader_source_lookup.end() and it->first == shader_source.meta)
{
continue;
}
m_shader_source_lookup.emplace(it, meta, id);
m_shader_source_lookup.emplace(it, shader_source.meta, id);
}
}
@@ -132,7 +125,7 @@ void zgl::shader_source_manager::fetch(
while (
source_it != m_shader_source_lookup.end() and
source_it->first.geometry == req.geometry_type and
source_it->first.geometry_type == req.geometry_type and
source_it->first.stage == req.stage
) {
const auto& [ meta, id ] = *source_it;
@@ -146,7 +139,7 @@ void zgl::shader_source_manager::fetch(
to_be_enabled = req.components & meta.static_enable;
source_id = id;
res.static_enabled = meta.commponents & ~meta.dynamic_enable & ~unwanted_components;
res.static_enabled = meta.components & ~meta.dynamic_enable & ~unwanted_components;
res.dynamic_enable = meta.dynamic_enable;
break;