148 lines
3.4 KiB
C++
148 lines
3.4 KiB
C++
#ifndef INCLUDE_MESH_BATCH_IMPLEMENTATION
|
|
# error Never include this file directly include 'mesh_batch.hpp'
|
|
#endif
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
inline mesh_batch::id_type mesh_batch::add(
|
|
const zgl::mesh_handle& mesh,
|
|
const aabb& bounding_box,
|
|
const zgl::model_matrix_handle& transform,
|
|
const zgl::material_handle& material
|
|
) {
|
|
std::size_t index;
|
|
if (material.texture)
|
|
{
|
|
// Sort by texture id if possible, so meshes the same texture are rendered consecutively.
|
|
const auto texture_it = std::ranges::upper_bound(
|
|
m_textures,
|
|
*material.texture,
|
|
[](const auto& lhs, const auto& rhs)
|
|
{
|
|
return lhs.texture_id < rhs.texture_id;
|
|
}
|
|
);
|
|
index = texture_it - m_textures.begin();
|
|
}
|
|
else
|
|
{
|
|
// TODO inserting by vao might split up texture sequence, this needs more attention
|
|
// Otherwise, sort by vao, so meshes with the same vertices are rendered consecutively.
|
|
const auto mesh_it = std::ranges::upper_bound(
|
|
m_meshes,
|
|
mesh,
|
|
[](const auto& lhs, const auto& rhs)
|
|
{
|
|
return lhs.vao_id < rhs.vao_id;
|
|
}
|
|
);
|
|
index = mesh_it - m_meshes.begin();
|
|
}
|
|
|
|
m_meshes.insert(m_meshes.begin() + index, mesh);
|
|
m_bounding_boxes.insert(m_bounding_boxes.begin() + index, bounding_box);
|
|
m_transforms.insert(m_transforms.begin() + index, transform);
|
|
|
|
if (material.texture)
|
|
{
|
|
m_textures.insert(m_textures.begin() + index, *material.texture);
|
|
}
|
|
|
|
if (material.surface_properties)
|
|
{
|
|
m_surface_properties.insert(m_surface_properties.begin() + index, *material.surface_properties);
|
|
}
|
|
|
|
if (material.alpha)
|
|
{
|
|
m_alphas.insert(m_alphas.begin() + index, *material.alpha);
|
|
}
|
|
|
|
const auto mesh_id = m_next_mesh_id++;
|
|
|
|
m_id_lookup.insert(m_id_lookup.begin() + index, mesh_id);
|
|
|
|
return mesh_id;
|
|
}
|
|
|
|
std::optional<aabb> mesh_batch::bounding_box(id_type id)
|
|
{
|
|
const auto lookup_it = std::ranges::find(m_id_lookup, id);
|
|
|
|
if (lookup_it == m_id_lookup.end())
|
|
{
|
|
return std::nullopt;
|
|
}
|
|
|
|
const auto index = lookup_it - m_id_lookup.begin();
|
|
|
|
const auto& base_bounding_box = m_bounding_boxes[index];
|
|
const auto& transform = m_transforms[index];
|
|
|
|
return base_bounding_box.transformed(transform);
|
|
}
|
|
|
|
inline bool mesh_batch::remove(const id_type id)
|
|
{
|
|
const auto lookup_it = std::ranges::find(m_id_lookup, id);
|
|
|
|
if (lookup_it == m_id_lookup.end()) {
|
|
return false;
|
|
}
|
|
|
|
const auto index = lookup_it - m_id_lookup.begin();
|
|
|
|
m_id_lookup.erase(m_id_lookup.begin() + index);
|
|
m_meshes.erase(m_meshes.begin() + index);
|
|
m_bounding_boxes.erase(m_bounding_boxes.begin() + index);
|
|
m_transforms.erase(m_transforms.begin() + index);
|
|
|
|
if (not m_textures.empty())
|
|
{
|
|
m_textures.erase(m_textures.begin() + index);
|
|
}
|
|
|
|
if (not m_surface_properties.empty())
|
|
{
|
|
m_surface_properties.erase(m_surface_properties.begin() + index);
|
|
}
|
|
|
|
if (not m_alphas.empty())
|
|
{
|
|
m_alphas.erase(m_alphas.begin() + index);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
inline std::span<const zgl::mesh_handle> mesh_batch::meshes() const
|
|
{
|
|
return m_meshes;
|
|
}
|
|
|
|
inline std::span<const aabb> mesh_batch::bounding_boxes() const
|
|
{
|
|
return m_bounding_boxes;
|
|
}
|
|
|
|
inline std::span<const zgl::model_matrix_handle> mesh_batch::transforms() const
|
|
{
|
|
return m_transforms;
|
|
}
|
|
|
|
inline std::span<const zgl::texture_handle> mesh_batch::textures() const
|
|
{
|
|
return m_textures;
|
|
}
|
|
|
|
inline std::span<const zgl::surface_properties_handle> mesh_batch::surface_properties() const
|
|
{
|
|
return m_surface_properties;
|
|
}
|
|
|
|
inline std::span<const zgl::alpha_handle> mesh_batch::alphas() const
|
|
{
|
|
return m_alphas;
|
|
}
|