2#ifndef LIBSBX_MODELS_STATIC_MESH_MATERIAL_DRAW_LIST_HPP_
3#define LIBSBX_MODELS_STATIC_MESH_MATERIAL_DRAW_LIST_HPP_
7#include <unordered_set>
11#include <easy/profiler.h>
13#include <fmt/format.h>
15#include <range/v3/view/enumerate.hpp>
17#include <libsbx/utility/logger.hpp>
18#include <libsbx/utility/enum.hpp>
20#include <libsbx/containers/octree.hpp>
23#include <libsbx/math/vector3.hpp>
24#include <libsbx/math/matrix4x4.hpp>
25#include <libsbx/math/volume.hpp>
27#include <libsbx/utility/logger.hpp>
28#include <libsbx/utility/timer.hpp>
29#include <libsbx/utility/layout.hpp>
30#include <libsbx/utility/iterator.hpp>
32#include <libsbx/core/engine.hpp>
34#include <libsbx/graphics/graphics_module.hpp>
35#include <libsbx/graphics/subrenderer.hpp>
36#include <libsbx/graphics/draw_list.hpp>
38#include <libsbx/graphics/pipeline/pipeline.hpp>
39#include <libsbx/graphics/pipeline/graphics_pipeline.hpp>
41#include <libsbx/graphics/descriptor/descriptor_handler.hpp>
43#include <libsbx/graphics/buffers/uniform_handler.hpp>
44#include <libsbx/graphics/buffers/storage_handler.hpp>
45#include <libsbx/graphics/buffers/storage_buffer.hpp>
47#include <libsbx/graphics/images/image2d.hpp>
48#include <libsbx/graphics/images/separate_image2d_array.hpp>
49#include <libsbx/graphics/images/sampler_state.hpp>
51#include <libsbx/assets/assets_module.hpp>
53#include <libsbx/scenes/scenes_module.hpp>
54#include <libsbx/scenes/scene.hpp>
55#include <libsbx/scenes/node.hpp>
57#include <libsbx/scenes/components/static_mesh.hpp>
58#include <libsbx/scenes/components/id.hpp>
59#include <libsbx/scenes/components/camera.hpp>
60#include <libsbx/scenes/components/tag.hpp>
61#include <libsbx/scenes/components/point_light.hpp>
62#include <libsbx/scenes/components/global_transform.hpp>
64#include <libsbx/models/vertex3d.hpp>
65#include <libsbx/models/mesh.hpp>
66#include <libsbx/models/material.hpp>
67#include <libsbx/models/material_draw_list.hpp>
69#include <libsbx/sprites/sprites_module.hpp>
71namespace sbx::models {
77 std::uint32_t lod_level{0u};
80 template<
typename DarwList>
81 static auto create_shared_buffers([[maybe_unused]] DarwList& draw_list) ->
void {
85 template<
typename DarwList>
86 static auto destroy_shared_buffers([[maybe_unused]] DarwList& draw_list) ->
void {
90 template<
typename DarwList>
91 static auto update_shared_buffers([[maybe_unused]] DarwList& draw_list) ->
void {
95 template<
typename Callable>
96 static void for_each_submission(scenes::scene& scene, Callable&& callable) {
97 auto& assets_module = core::engine::get_module<assets::assets_module>();
98 auto& scenes_module = core::engine::get_module<scenes::scenes_module>();
100 auto& graph = scene.graph();
101 auto& environment = scene.environment();
103 auto& assets = scenes_module.asset_registry();
105 auto camera_node = environment.camera();
106 const auto camera_position = math::vector3{graph.world_position(camera_node)};
108 auto query = graph.query<
const scenes::static_mesh>();
110 for (
auto&& [
node, static_mesh] : query.each()) {
111 const auto transform_data = models::transform_data{graph.world_transform(
node), graph.world_normal(
node)};
112 const auto world_position = graph.world_position(
node);
114 const auto distance_sq = math::vector3::distance_squared(camera_position, world_position);
116 const auto& mesh_id = static_mesh.mesh_id();
118 const auto& mesh = assets_module.get_asset<models::mesh>(mesh_id);
120 for (
const auto& submesh : static_mesh.submeshes()) {
121 const auto base_index = mesh.find_base_submesh_index(submesh.index).value_or(submesh.index);
122 const auto lod = _select_lod(distance_sq, mesh.lod_count(base_index));
123 const auto actual_index = base_index + lod;
125 std::invoke(callable,
node, mesh_id, actual_index, submesh.material, transform_data, instance_payload{lod});
130 static auto make_instance_data(
const scenes::node
node,
const std::uint32_t transform_index, std::uint32_t material_index, [[maybe_unused]]
const instance_payload& payload) -> instance_data {
131 return instance_data{transform_index, material_index,
static_cast<std::uint32_t
>(
node), payload.lod_level};
134 template<
typename Mesh,
typename Emitter>
135 static auto build_draw_commands(
const Mesh& mesh, std::uint32_t submesh_index, std::vector<models::instance_data>&& instances, Emitter&& emitter) -> std::uint32_t {
136 if (instances.empty()) {
140 const auto& submesh = mesh.submesh(submesh_index);
142 auto command = VkDrawIndexedIndirectCommand{};
143 command.indexCount = submesh.index_count;
144 command.instanceCount =
static_cast<std::uint32_t
>(instances.size());
145 command.firstIndex = submesh.index_offset;
146 command.vertexOffset =
static_cast<std::int32_t
>(submesh.vertex_offset);
147 command.firstInstance = emitter.base_instance;
149 emitter.emit_instanced(command, std::move(instances));
151 return command.instanceCount;
156 static auto _select_lod(std::float_t distance_sq, std::uint32_t lod_count) -> std::uint32_t {
157 static constexpr auto thresholds = std::array<std::float_t, 4u>{
164 auto level = std::uint32_t{0u};
166 for (
auto i = std::uint32_t{0u}; i < static_cast<std::uint32_t>(thresholds.size()); ++i) {
167 if (distance_sq > thresholds[i]) {
172 return std::min(level, lod_count - 1u);
177using static_mesh_material_draw_list = basic_material_draw_list<static_mesh_traits>;
RGBA color representation and utilities.
Definition: static_mesh_material_draw_list.hpp:76
Definition: static_mesh_material_draw_list.hpp:73