MayaFlux 0.3.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
GeometryWriterNode.cpp
Go to the documentation of this file.
2
4
6
7GeometryWriterNode::GeometryWriterNode(uint32_t initial_capacity)
8{
10
11 if (initial_capacity > 0 && m_vertex_stride == 0) {
12 m_vertex_stride = sizeof(glm::vec3);
13 }
14
15 if (initial_capacity > 0) {
16 m_vertex_buffer.resize(initial_capacity * m_vertex_stride / sizeof(float));
17 }
18}
19
20void GeometryWriterNode::resize_vertex_buffer(uint32_t vertex_count, bool preserve_data)
21{
22 if (m_vertex_stride == 0) {
24 "Cannot resize vertex buffer: stride is 0. Call set_vertex_stride() first");
25 return;
26 }
27
28 size_t new_size_bytes = static_cast<size_t>(vertex_count) * m_vertex_stride;
29
30 if (!preserve_data) {
31 m_vertex_buffer.clear();
32 m_vertex_buffer.resize(new_size_bytes, 0.0F);
33 } else if (m_vertex_buffer.size() < new_size_bytes) {
34 m_vertex_buffer.resize(new_size_bytes, 0.0F);
35 } else if (m_vertex_buffer.size() > new_size_bytes) {
36 m_vertex_buffer.resize(new_size_bytes);
37 }
38
39 m_vertex_count = vertex_count;
42
44 "GeometryWriterNode: Resized vertex buffer to {} vertices ({} bytes total)",
45 vertex_count, new_size_bytes * sizeof(float));
46}
47
48void GeometryWriterNode::set_vertex_data(const void* data, size_t size_bytes)
49{
50 if (!data || size_bytes == 0) {
52 "Cannot set vertex data: null data or zero size");
53 return;
54 }
55
56 if (m_vertex_stride == 0) {
58 "Cannot set vertex data: stride is 0");
59 return;
60 }
61
62 auto expected_vertex_count = static_cast<uint32_t>(size_bytes / m_vertex_stride);
63
64 if (size_bytes % m_vertex_stride != 0) {
66 "Vertex data size {} is not multiple of stride {}",
67 size_bytes, m_vertex_stride);
68 }
69
70 size_t required_floats = size_bytes / sizeof(float);
71 if (m_vertex_buffer.size() < required_floats) {
72 m_vertex_buffer.resize(required_floats);
73 }
74
75 std::memcpy(m_vertex_buffer.data(), data, size_bytes);
76 m_vertex_count = expected_vertex_count;
79
81 "GeometryWriterNode: Set vertex data ({} vertices, {} bytes)",
82 m_vertex_count, size_bytes);
83}
84
85void GeometryWriterNode::set_vertex(uint32_t vertex_index, const void* data, size_t size_bytes)
86{
87 if (!data || size_bytes == 0) {
89 "Cannot set vertex: null data or zero size");
90 return;
91 }
92
93 if (m_vertex_stride == 0) {
95 "Cannot set vertex: stride is 0");
96 return;
97 }
98
99 if (vertex_index >= m_vertex_count) {
101 "Vertex index {} out of range (count: {})",
102 vertex_index, m_vertex_count);
103 return;
104 }
105
106 if (size_bytes > m_vertex_stride) {
108 "Vertex data size {} exceeds stride {}; truncating",
109 size_bytes, m_vertex_stride);
110 size_bytes = m_vertex_stride;
111 }
112
113 size_t offset_floats = (static_cast<size_t>(vertex_index) * m_vertex_stride) / sizeof(float);
114
115 std::memcpy(
116 reinterpret_cast<uint8_t*>(m_vertex_buffer.data()) + (offset_floats * sizeof(float)),
117 data,
118 size_bytes);
119
121 "GeometryWriterNode: Set vertex {} ({} bytes)", vertex_index, size_bytes);
122
123 m_vertex_data_dirty = true;
124}
125
127{
128 return m_vertex_buffer.size();
129}
130
132{
133 m_vertex_stride = stride;
135}
136
137std::span<const uint8_t> GeometryWriterNode::get_vertex(uint32_t vertex_index) const
138{
139 if (m_vertex_stride == 0 || m_vertex_count == 0) {
140 return {};
141 }
142
143 if (vertex_index >= m_vertex_count) {
145 "Vertex index {} out of range (count: {})",
146 vertex_index, m_vertex_count);
147 return {};
148 }
149
150 size_t offset_floats = (static_cast<size_t>(vertex_index) * m_vertex_stride) / sizeof(float);
151 size_t stride_floats = m_vertex_stride / sizeof(float);
152
153 if (offset_floats + stride_floats > m_vertex_buffer.size()) {
154 return {};
155 }
156
157 return { m_vertex_buffer.data() + offset_floats, stride_floats };
158}
159
161{
162 std::ranges::fill(m_vertex_buffer, 0);
163
164 m_vertex_data_dirty = true;
165}
166
167void GeometryWriterNode::clear_and_resize(uint32_t vertex_count)
168{
169 resize_vertex_buffer(vertex_count, false);
170}
171
172std::vector<double> GeometryWriterNode::process_batch(unsigned int num_samples)
173{
175
176 return std::vector<double>(num_samples, 0.0);
177}
178
180{
181 GeometryState state;
186
187 m_saved_state = std::move(state);
188
190 "GeometryWriterNode: Saved state ({} vertices, {} bytes)",
191 m_vertex_count, m_vertex_buffer.size() * sizeof(uint8_t));
192}
193
195{
196 if (!m_saved_state.has_value()) {
198 "GeometryWriterNode: No saved state to restore");
199 return;
200 }
201
202 m_vertex_buffer = m_saved_state->vertex_buffer;
203 m_vertex_count = m_saved_state->vertex_count;
204 m_vertex_stride = m_saved_state->vertex_stride;
205 m_vertex_layout = m_saved_state->vertex_layout;
206
208
210 "GeometryWriterNode: Restored state ({} vertices, {} bytes)",
211 m_vertex_count, m_vertex_buffer.size() * sizeof(uint8_t));
212}
213
223
228
229#ifdef MAYAFLUX_PLATFORM_MACOS
230std::vector<LineVertex> GeometryWriterNode::expand_lines_to_triangles(
231 const std::vector<LineVertex>& line_segment)
232{
233 if (line_segment.size() < 2) {
234 return {};
235 }
236
237 std::vector<LineVertex> triangles;
238 triangles.reserve((line_segment.size() - 1) * 6);
239
240 for (size_t i = 0; i + 1 < line_segment.size(); ++i) {
241 const auto& v0 = line_segment[i];
242 const auto& v1 = line_segment[i + 1];
243
244 glm::vec2 p0_2d = glm::vec2(v0.position.x, v0.position.y);
245 glm::vec2 p1_2d = glm::vec2(v1.position.x, v1.position.y);
246
247 glm::vec2 dir = p1_2d - p0_2d;
248 float len = glm::length(dir);
249
250 if (len < 1e-6F) {
251 continue;
252 }
253
254 dir = dir / len;
255 glm::vec2 normal = glm::vec2(-dir.y, dir.x);
256
257 float t0 = v0.thickness * 0.005F;
258 float t1 = v1.thickness * 0.005F;
259
260 glm::vec3 p0_top = glm::vec3(p0_2d + normal * t0, v0.position.z);
261 glm::vec3 p0_bot = glm::vec3(p0_2d - normal * t0, v0.position.z);
262 glm::vec3 p1_top = glm::vec3(p1_2d + normal * t1, v1.position.z);
263 glm::vec3 p1_bot = glm::vec3(p1_2d - normal * t1, v1.position.z);
264
265 triangles.push_back({ p0_top, v0.color, v0.thickness,
266 glm::vec2(0.0F, 0.0F) });
267 triangles.push_back({ p0_bot, v0.color, v0.thickness,
268 glm::vec2(0.0F, 1.0F) });
269 triangles.push_back({ p1_top, v1.color, v1.thickness,
270 glm::vec2(1.0F, 0.0F) });
271
272 triangles.push_back({ p0_bot, v0.color, v0.thickness,
273 glm::vec2(0.0F, 1.0F) });
274 triangles.push_back({ p1_bot, v1.color, v1.thickness,
275 glm::vec2(1.0F, 1.0F) });
276 triangles.push_back({ p1_top, v1.color, v1.thickness,
277 glm::vec2(1.0F, 0.0F) });
278 }
279
280 return triangles;
281}
282#endif
283
284} // namespace MayaFlux::Nodes
#define MF_ERROR(comp, ctx,...)
#define MF_TRACE(comp, ctx,...)
#define MF_WARN(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
std::span< const uint8_t > m_gpu_data
GeometryWriterNode(uint32_t initial_capacity=1024)
Constructor.
void save_state() override
Save current geometry state.
std::span< const uint8_t > get_vertex(uint32_t vertex_index) const
Get a single vertex by index.
void restore_state() override
Restore saved geometry state.
std::vector< uint8_t > m_vertex_buffer
Vertex data buffer (flat array of bytes)
bool m_vertex_data_dirty
Flag: vertex data or layout changed since last GPU upload.
void clear()
Clear vertex buffer and reset count.
size_t get_vertex_buffer_size_bytes() const
Get vertex buffer size in bytes.
std::vector< double > process_batch(unsigned int num_samples) override
Process batch for geometry generation.
void clear_and_resize(uint32_t vertex_count)
Clear vertex buffer and resize to specified count.
size_t m_vertex_stride
Bytes per vertex (stride for vertex buffer binding)
std::optional< Kakshya::VertexLayout > m_vertex_layout
Cached vertex layout for descriptor binding.
NodeContext & get_last_context() override
Retrieves the last created context object.
void set_vertex_data(const void *data, size_t size_bytes)
Copy raw vertex data into buffer.
void resize_vertex_buffer(uint32_t vertex_count, bool preserve_data=false)
Resize vertex buffer to hold specified number of vertices.
void set_vertex_stride(size_t stride)
Set vertex stride (bytes per vertex)
bool m_needs_layout_update
Flag indicating if layout needs update.
void update_context(double value) override
Updates the context object with the current node state.
uint32_t m_vertex_count
Number of vertices in buffer.
void set_vertex(uint32_t vertex_index, const void *data, size_t size_bytes)
Set a single vertex by index.
virtual void compute_frame()=0
Compute GPU data for this frame.
double value
Current sample value.
Definition Node.hpp:40
Base context class for node callbacks.
Definition Node.hpp:30
uint8_t m_node_capability
Bitmask of capabilities declared by this node.
Definition Node.hpp:433
@ NodeProcessing
Node graph processing (Nodes::NodeGraphManager)
@ Nodes
DSP Generator and Filter Nodes, graph pipeline, node management.
@ STRUCTURED
Context also implements GpuStructuredData.
Definition NodeSpec.hpp:108