34 "FieldOperator initialized with {} PointVertex", vertices.size());
43 "FieldOperator initialized with {} LineVertex", vertices.size());
52 "FieldOperator initialized with {} MeshVertex", vertices.size());
64 if (type_name ==
"PointVertex") {
66 }
else if (type_name ==
"LineVertex") {
68 }
else if (type_name ==
"MeshVertex") {
72 "FieldOperator::seed_from_upstream: unrecognized vertex type '{}', defaulting to LineVertex",
77 if (data.empty() || layout.stride_bytes == 0)
80 if (layout.stride_bytes !=
k_stride) {
82 "FieldOperator::seed_from_upstream: upstream stride {} != k_stride {}, skipping",
94 "FieldOperator seeded {} vertices from upstream '{}'",
107 if (
m_mode == FieldMode::ABSOLUTE) {
118 for (
size_t i = 0; i <
m_count; ++i) {
122 glm::vec3 displacement(0.0F);
124 displacement += field(pos);
130 glm::vec3 color(0.0F);
138 glm::vec3 normal(0.0F);
140 normal += field(pos);
142 float len = glm::length(normal);
147 glm::vec3 tangent(0.0F);
149 tangent += field(pos);
151 float len = glm::length(tangent);
168 *
reinterpret_cast<glm::vec2*
>(
182 if (!any_flag(target)) {
184 "bind: empty target mask");
190 "Cannot bind VectorField to mask {:#x}: unreached bits {:#x}. "
191 "SCALAR needs a SpatialField, UV needs a UVField, and targets this "
192 "operator does not implement are rejected. Nothing was bound.",
193 static_cast<uint16_t
>(target),
198 if (has_flag(target, FieldTarget::POSITION))
200 if (has_flag(target, FieldTarget::COLOR))
202 if (has_flag(target, FieldTarget::NORMAL))
204 if (has_flag(target, FieldTarget::TANGENT))
210 if (target != FieldTarget::SCALAR) {
212 "SpatialField binds only to FieldTarget::SCALAR, got mask {:#x}. "
213 "UV requires a UVField; vector targets require a VectorField.",
214 static_cast<uint16_t
>(target));
222 if (target != FieldTarget::UV) {
224 "UVField binds only to FieldTarget::UV, got mask {:#x}",
225 static_cast<uint16_t
>(target));
233 if (has_flag(target, FieldTarget::POSITION))
235 if (has_flag(target, FieldTarget::COLOR))
237 if (has_flag(target, FieldTarget::NORMAL))
239 if (has_flag(target, FieldTarget::TANGENT))
241 if (has_flag(target, FieldTarget::SCALAR))
243 if (has_flag(target, FieldTarget::UV))
334 return "PointVertex";
346 std::vector<PointVertex> result(
m_count);
353 std::vector<LineVertex> result(
m_count);
360 std::vector<MeshVertex> result(
m_count);
369 if (param ==
"mode") {
370 m_mode =
value > 0.5 ? FieldMode::ACCUMULATE : FieldMode::ABSOLUTE;
376 if (query ==
"point_count") {
377 return static_cast<double>(
m_count);
379 if (query ==
"field_count") {
380 return static_cast<double>(
389 std::string_view param,
390 const std::shared_ptr<NodeNetwork>& source)
#define MF_ERROR(comp, ctx,...)
#define MF_WARN(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
static constexpr size_t k_position_offset
size_t get_point_count() const override
Get source point count (before topology expansion)
std::vector< uint8_t > m_reference_data
void store_reference(const void *data, size_t count)
std::vector< Kinesis::VectorField > m_position_fields
std::vector< uint8_t > m_vertex_data
static constexpr size_t k_tangent_offset
size_t get_vertex_count() const override
Get number of vertices (may differ from point count for topology/path)
void seed_from_upstream(const GraphicsOperator *upstream) override
Seed vertex data from the upstream operator's current output.
void set_parameter(std::string_view param, double value) override
Set operator parameter.
static constexpr size_t k_normal_offset
bool is_vertex_data_dirty() const override
Check if geometry changed this frame.
void unbind_all()
Remove all bound fields.
std::vector< LineVertex > extract_line_vertices() const
std::vector< Kinesis::VectorField > m_tangent_fields
std::vector< Kinesis::SpatialField > m_scalar_fields
glm::vec3 & vec3_at(size_t i, size_t offset)
std::vector< Kinesis::VectorField > m_color_fields
Kakshya::VertexLayout get_vertex_layout() const override
Get vertex layout describing vertex structure.
std::span< const uint8_t > get_vertex_data_for_collection(uint32_t idx) const override
Get vertex data for specific collection (if multiple)
std::span< const uint8_t > get_vertex_data() const override
Get vertex data for GPU upload.
static constexpr size_t k_scalar_offset
void * get_data_at(size_t global_index) override
Get mutable access to point at global index.
std::vector< PointVertex > extract_point_vertices() const
void mark_vertex_data_clean() override
Clear dirty flag after GPU upload.
void unbind(FieldTarget target)
Remove all fields bound to a target.
void apply_one_to_one(std::string_view param, const std::shared_ptr< NodeNetwork > &source) override
Apply ONE_TO_ONE parameter mapping (per-point control)
std::vector< Kinesis::VectorField > m_normal_fields
std::optional< double > query_state(std::string_view query) const override
Query operator internal state.
void bind(FieldTarget target, Kinesis::VectorField field)
Bind a VectorField to a vec3 target.
float & float_at(size_t i, size_t offset)
static constexpr size_t k_stride
std::vector< Kinesis::UVField > m_uv_fields
static constexpr size_t k_color_offset
static constexpr size_t k_uv_offset
const char * get_vertex_type_name() const override
Get human-readable vertex type name (for validation/debugging)
std::vector< MeshVertex > extract_mesh_vertices() const
void process(float dt) override
Process for one batch cycle.
void initialize(const std::vector< PointVertex > &vertices)
Initialize from PointVertex data.
FieldOperator(FieldMode mode=FieldMode::ABSOLUTE)
glm::vec3 ref_position_at(size_t i) const
void apply_one_to_one(std::string_view param, const std::shared_ptr< NodeNetwork > &source) override
Apply ONE_TO_ONE parameter mapping.
virtual Kakshya::VertexLayout get_vertex_layout() const =0
Get vertex layout describing vertex structure.
virtual std::span< const uint8_t > get_vertex_data() const =0
Get vertex data for GPU upload.
virtual const char * get_vertex_type_name() const =0
Get human-readable vertex type name (for validation/debugging)
Operator that produces GPU-renderable geometry.
virtual std::string_view get_type_name() const =0
Type name for introspection.
@ NodeProcessing
Node graph processing (Nodes::NodeGraphManager)
@ Nodes
DSP Generator and Filter Nodes, graph pipeline, node management.
FieldTarget
What a Tendency drives when applied to a vertex record.
FieldMode
How a field result combines with the value already present.
constexpr FieldTarget k_vector_targets
Targets that accept a three-component field.
Kinesis::FieldTarget FieldTarget
uint32_t vertex_count
Total number of vertices in this buffer.
static VertexLayout for_lines(uint32_t stride=60)
Factory: layout for LineVertex (position, color, thickness, uv, normal, tangent)
static VertexLayout for_meshes(uint32_t stride=60)
Factory: layout for MeshVertex (position, color, weight, uv, normal, tangent)
static VertexLayout for_points(uint32_t stride=60)
Factory: layout for PointVertex (position, color, size, uv, normal, tangent)
Complete description of vertex data layout in a buffer.
Typed, composable, stateless callable from domain D to range R.