sandbox
Loading...
Searching...
No Matches
static_mesh_material_draw_list.hpp
1// SPDX-License-Identifier: MIT
2#ifndef LIBSBX_MODELS_STATIC_MESH_MATERIAL_DRAW_LIST_HPP_
3#define LIBSBX_MODELS_STATIC_MESH_MATERIAL_DRAW_LIST_HPP_
4
5#include <cstddef>
6#include <filesystem>
7#include <unordered_set>
8#include <ranges>
9#include <algorithm>
10
11#include <easy/profiler.h>
12
13#include <fmt/format.h>
14
15#include <range/v3/view/enumerate.hpp>
16
17#include <libsbx/utility/logger.hpp>
18#include <libsbx/utility/enum.hpp>
19
20#include <libsbx/containers/octree.hpp>
21
22#include <libsbx/math/color.hpp>
23#include <libsbx/math/vector3.hpp>
24#include <libsbx/math/matrix4x4.hpp>
25#include <libsbx/math/volume.hpp>
26
27#include <libsbx/utility/logger.hpp>
28#include <libsbx/utility/timer.hpp>
29#include <libsbx/utility/layout.hpp>
30#include <libsbx/utility/iterator.hpp>
31
32#include <libsbx/core/engine.hpp>
33
34#include <libsbx/graphics/graphics_module.hpp>
35#include <libsbx/graphics/subrenderer.hpp>
36#include <libsbx/graphics/draw_list.hpp>
37
38#include <libsbx/graphics/pipeline/pipeline.hpp>
39#include <libsbx/graphics/pipeline/graphics_pipeline.hpp>
40
41#include <libsbx/graphics/descriptor/descriptor_handler.hpp>
42
43#include <libsbx/graphics/buffers/uniform_handler.hpp>
44#include <libsbx/graphics/buffers/storage_handler.hpp>
45#include <libsbx/graphics/buffers/storage_buffer.hpp>
46
47#include <libsbx/graphics/images/image2d.hpp>
48#include <libsbx/graphics/images/separate_image2d_array.hpp>
49#include <libsbx/graphics/images/sampler_state.hpp>
50
51#include <libsbx/assets/assets_module.hpp>
52
53#include <libsbx/scenes/scenes_module.hpp>
54#include <libsbx/scenes/scene.hpp>
55#include <libsbx/scenes/node.hpp>
56
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>
63
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>
68
69#include <libsbx/sprites/sprites_module.hpp>
70
71namespace sbx::models {
72
74
75 using mesh_type = models::mesh;
77 std::uint32_t lod_level{0u};
78 };
79
80 template<typename DarwList>
81 static auto create_shared_buffers([[maybe_unused]] DarwList& draw_list) -> void {
82
83 }
84
85 template<typename DarwList>
86 static auto destroy_shared_buffers([[maybe_unused]] DarwList& draw_list) -> void {
87
88 }
89
90 template<typename DarwList>
91 static auto update_shared_buffers([[maybe_unused]] DarwList& draw_list) -> void {
92
93 }
94
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>();
99
100 auto& graph = scene.graph();
101 auto& environment = scene.environment();
102
103 auto& assets = scenes_module.asset_registry();
104
105 auto camera_node = environment.camera();
106 const auto camera_position = math::vector3{graph.world_position(camera_node)};
107
108 auto query = graph.query<const scenes::static_mesh>();
109
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);
113
114 const auto distance_sq = math::vector3::distance_squared(camera_position, world_position);
115
116 const auto& mesh_id = static_mesh.mesh_id();
117
118 const auto& mesh = assets_module.get_asset<models::mesh>(mesh_id);
119
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;
124
125 std::invoke(callable, node, mesh_id, actual_index, submesh.material, transform_data, instance_payload{lod});
126 }
127 }
128 }
129
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};
132 }
133
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()) {
137 return 0;
138 }
139
140 const auto& submesh = mesh.submesh(submesh_index);
141
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;
148
149 emitter.emit_instanced(command, std::move(instances));
150
151 return command.instanceCount;
152 }
153
154private:
155
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>{
158 900.0f, // LOD 0: < 30m
159 6400.0f, // LOD 1: < 80m
160 22500.0f, // LOD 2: < 150m
161 90000.0f // LOD 3: < 300m
162 };
163
164 auto level = std::uint32_t{0u};
165
166 for (auto i = std::uint32_t{0u}; i < static_cast<std::uint32_t>(thresholds.size()); ++i) {
167 if (distance_sq > thresholds[i]) {
168 level = i + 1u;
169 }
170 }
171
172 return std::min(level, lod_count - 1u);
173 }
174
175}; // static_mesh_traits
176
177using static_mesh_material_draw_list = basic_material_draw_list<static_mesh_traits>;
178
179} // namespace sbx::models
180
181#endif // LIBSBX_MODELS_STATIC_MESH_MATERIAL_DRAW_LIST_HPP_
Definition: tests.cpp:6
Definition: mesh.hpp:27
RGBA color representation and utilities.
Definition: static_mesh_material_draw_list.hpp:76
Definition: static_mesh_material_draw_list.hpp:73