Unravel Engine C++ Reference
Loading...
Searching...
No Matches
batch_instance.cpp
Go to the documentation of this file.
1#include "batch_instance.h"
2
3#include <sstream>
4#include <iomanip>
5#include <cassert>
6
7namespace unravel
8{
9
10// batch_instance implementation
11
12batch_instance::batch_instance(const math::mat4* world_transform_ptr)
13 : world_transform_ptr(world_transform_ptr)
14{
15}
16
17batch_instance::batch_instance(const math::mat4* world_transform_ptr, const math::vec3& lod_params)
18 : world_transform_ptr(world_transform_ptr)
19 , lod_params(lod_params)
20{
21}
22
23auto batch_instance::is_valid() const -> bool
24{
25 return world_transform_ptr != nullptr;
26}
27
28auto batch_instance::to_string() const -> std::string
29{
30 std::ostringstream oss;
31 oss << std::fixed << std::setprecision(3);
32 oss << "batch_instance{";
33
35 {
36 const auto& transform = *world_transform_ptr;
37 oss << "transform=[" << transform[0][0] << "," << transform[0][1] << "," << transform[0][2] << "," << transform[0][3] << "; ";
38 oss << transform[1][0] << "," << transform[1][1] << "," << transform[1][2] << "," << transform[1][3] << "; ";
39 oss << transform[2][0] << "," << transform[2][1] << "," << transform[2][2] << "," << transform[2][3] << "; ";
40 oss << transform[3][0] << "," << transform[3][1] << "," << transform[3][2] << "," << transform[3][3] << "], ";
41 }
42 else
43 {
44 oss << "transform=null, ";
45 }
46
47 oss << "lod=[" << lod_params.x << "," << lod_params.y << "," << lod_params.z << "]}";
48 return oss.str();
49}
50
51// instance_vertex_data implementation
52
54 : world_matrix(instance.world_transform_ptr ? *instance.world_transform_ptr : math::mat4(1.0f))
55{
56 // Pack LOD parameter into matrix[3][3] position (normally 1.0 for homogeneous coordinates)
57 world_matrix[3][3] = instance.lod_params.x;
58}
59
61{
62 world_matrix[3][3] = lod_param;
63}
64
66{
67 return world_matrix[3][3];
68}
69
71{
72 // Check all matrix components for finite values
73 for (int i = 0; i < 4; ++i)
74 {
75 for (int j = 0; j < 4; ++j)
76 {
77 if (!std::isfinite(world_matrix[i][j]))
78 {
79 return false;
80 }
81 }
82 }
83
84 return true;
85}
86
87auto instance_vertex_data::to_string() const -> std::string
88{
89 std::ostringstream oss;
90 oss << std::fixed << std::setprecision(3);
91 oss << "instance_vertex_data{";
92 oss << "matrix=[";
93 for (int i = 0; i < 4; ++i)
94 {
95 if (i > 0)
96 {
97 oss << "; ";
98 }
99 oss << "[" << world_matrix[i][0] << "," << world_matrix[i][1] << "," << world_matrix[i][2] << "," << world_matrix[i][3] << "]";
100 }
101 oss << "], lod=" << get_lod_param() << "}";
102 return oss.str();
103}
104
105// batch_instance_collection implementation
106
108{
109 instances_.reserve(count);
110}
111
113{
114 instances_.push_back(instance);
115}
116
117void batch_instance_collection::add_instance(const math::mat4& world_transform)
118{
119 instances_.emplace_back(&world_transform);
120}
121
123{
124 instances_.clear();
125}
126
128{
129 return instances_.size();
130}
131
133{
134 return instances_.empty();
135}
136
138{
139 return instances_[index];
140}
141
143{
144 return instances_[index];
145}
146
148{
149 return instances_.begin();
150}
151
153{
154 return instances_.end();
155}
156
158{
159 return instances_.begin();
160}
161
163{
164 return instances_.end();
165}
166
168{
169 std::vector<instance_vertex_data> vertex_data;
170 vertex_data.reserve(instances_.size());
171
172 for (const auto& instance : instances_)
173 {
174 vertex_data.emplace_back(instance);
175 }
176
177 return vertex_data;
178}
179
181{
182 return instances_.size() * sizeof(instance_vertex_data);
183}
184
185// Utility functions
186
188{
189 return instance_vertex_data(instance);
190}
191
193 math::mat4& out_transform,
194 math::vec3& out_lod_params)
195{
196 // Direct matrix copy
197 out_transform = vertex_data.world_matrix;
198
199 // Extract LOD parameter from matrix[3][3] and restore homogeneous coordinate
200 out_lod_params.x = vertex_data.get_lod_param();
201 out_transform[3][3] = 1.0f; // Restore homogeneous coordinate
202
203 // Set default values for other LOD parameters
204 out_lod_params.y = -1.0f;
205 out_lod_params.z = 0.0f;
206}
207
208auto pack_instances_bulk(const std::vector<batch_instance>& instances) -> std::vector<instance_vertex_data>
209{
210 std::vector<instance_vertex_data> vertex_data;
211 vertex_data.reserve(instances.size());
212
213 for (const auto& instance : instances)
214 {
215 vertex_data.emplace_back(instance);
216 }
217
218 return vertex_data;
219}
220
222{
223 // Verify structure sizes and alignment
224 static_assert(sizeof(instance_vertex_data) == sizeof(math::mat4),
225 "instance_vertex_data must be exactly one mat4");
226
227 static_assert(alignof(instance_vertex_data) >= alignof(math::mat4),
228 "instance_vertex_data must be properly aligned for mat4");
229
230 // Runtime checks
231 bool size_check = sizeof(instance_vertex_data) == 64; // 4 * 16 bytes (mat4)
232 bool alignment_check = (sizeof(instance_vertex_data) % 16) == 0;
233
234 return size_check && alignment_check;
235}
236
237} // namespace unravel
container_type::const_iterator const_iterator
auto begin() -> iterator
Get iterator to beginning.
void reserve(size_t count)
Reserve space for instances.
auto size() const -> size_t
Get number of instances.
container_type::iterator iterator
auto empty() const -> bool
Check if collection is empty.
auto operator[](size_t index) -> batch_instance &
Get instance by index.
auto end() -> iterator
Get iterator to end.
auto to_vertex_data() const -> std::vector< instance_vertex_data >
Convert all instances to GPU vertex data.
auto get_gpu_memory_size() const -> size_t
Get memory size required for GPU data.
void add_instance(const batch_instance &instance)
Add an instance to the collection.
void clear()
Clear all instances.
Definition bbox.cpp:5
Hash specialization for batch_key to enable use in std::unordered_map.
auto pack_instances_bulk(const std::vector< batch_instance > &instances) -> std::vector< instance_vertex_data >
Pack multiple instances into GPU vertex data.
auto pack_instance_data(const batch_instance &instance) -> instance_vertex_data
Pack batch instance data into GPU vertex format.
void unpack_instance_data(const instance_vertex_data &vertex_data, math::mat4 &out_transform, math::vec3 &out_lod_params)
Unpack GPU vertex data back to transform matrix and LOD params.
auto validate_instance_data_layout() -> bool
Validate that instance data is properly aligned and sized.
Instance data for a single object in a batch.
auto to_string() const -> std::string
Get string representation for debugging.
auto is_valid() const -> bool
Check if this instance has valid data.
const math::mat4 * world_transform_ptr
Pointer to world transformation matrix for this instance (valid only during frame processing)
batch_instance()=default
Default constructor.
math::vec3 lod_params
LOD blending parameters (x = current blend factor, y = target blend, z = transition time)
GPU-friendly vertex data for instancing.
auto is_valid() const -> bool
Check if the vertex data is valid.
auto get_lod_param() const -> float
Get the LOD parameter (from matrix[3][3])
math::mat4 world_matrix
World transformation matrix with LOD parameter packed in [3][3] (i_data0, i_data1,...
instance_vertex_data()=default
Default constructor.
void set_lod_param(float lod_param)
Set the LOD parameter (stored in matrix[3][3])
auto to_string() const -> std::string
Get string representation for debugging.