9 Eigen::Index samples_per_segment,
10 size_t max_control_points,
14 , m_max_control_points(max_control_points)
15 , m_samples_per_segment(samples_per_segment)
24 layout.vertex_count = 0;
28 m_vertices.reserve(samples_per_segment * max_control_points);
31 "Created PathGeneratorNode with mode {}, {} samples per segment, capacity {}",
32 static_cast<int>(
mode), samples_per_segment, max_control_points);
37 Eigen::Index samples_per_segment,
38 size_t max_control_points)
40 , m_mode(Kinesis::InterpolationMode::CUSTOM)
41 , m_custom_func(
std::move(custom_func))
42 , m_max_control_points(max_control_points)
43 , m_samples_per_segment(samples_per_segment)
52 layout.vertex_count = 0;
56 m_vertices.reserve(samples_per_segment * max_control_points);
59 "Created PathGeneratorNode with custom function");
80 const std::vector<LineVertex>& curve_verts,
90 for (
size_t i = 0; i < span; ++i) {
91 const size_t c0 = start_idx + std::min((i * 3) / span,
size_t(3));
92 const size_t c1 = start_idx + std::min(((i + 1) * 3) / span,
size_t(3));
106 const std::vector<LineVertex>& curve_verts,
110 if (start_idx + 3 >= curve_verts.size()) {
116 for (
size_t i = 0; i < 4; ++i) {
117 const auto& pt = curve_verts[start_idx + i].position;
139 const double* x = curve->data();
140 const double* y = x +
count;
141 const double* z = y +
count;
148 const double* ty = tx +
count;
149 const double* tz = ty +
count;
151 const auto sample = [&](
size_t s) {
153 static_cast<float>(x[s]),
static_cast<float>(y[s]),
static_cast<float>(z[s])
157 const auto tangent = [&](
size_t s) {
159 static_cast<float>(tx[s]),
static_cast<float>(ty[s]),
static_cast<float>(tz[s])
163 for (
size_t i = 0; i <
count - 1; ++i) {
164 dst[i * 2].position = sample(i);
166 dst[i * 2 + 1].position = sample(i + 1);
177 for (
size_t i = 0; i < n; ++i) {
187 if (num_points == 0 ||
total < 2) {
190 for (
size_t i = 0; i <
total; ++i) {
191 const size_t ctrl_idx = std::min((i * (num_points - 1)) / (
total - 1), num_points - 1);
205 if (
m_vertices.size() < windows * per_window) {
209 for (
size_t w = 0; w < windows; ++w) {
217 std::vector<LineVertex>& output)
225 output.push_back({ .position = v0.
position, .color = color0, .thickness = thick0 });
226 output.push_back({ .position = v1.
position, .color = color1, .thickness = thick1 });
257 "PathGeneratorNode: {} control points exceed the capacity of {}, keeping the newest {}",
274 "Control point index {} out of range (count: {})",
287 const size_t first =
index >= 3 ?
index - 3 : 0;
288 const size_t last = std::min(
index, windows - 1);
310 "Control point index {} out of range (count: {})",
367 v.thickness = thickness;
370 v.thickness = thickness;
420 if (num_points < 2) {
446 .thickness = thickness });
457 for (Eigen::Index i = 0; i < total_samples; ++i) {
458 double t =
static_cast<double>(i) /
static_cast<double>(total_samples - 1);
460 auto ctrl_idx = std::min<size_t>(
static_cast<size_t>(t *
float(num_points - 1)), num_points - 1);
467 .thickness = thickness
482 m_vertices.resize(base + windows * per_window);
484 for (
size_t w = 0; w < windows; ++w) {
512 if (num_points < 4 ||
m_vertices.size() != (num_points - 3) * per_window) {
517 const size_t windows = num_points - 3;
518 last_window = std::min(last_window, windows - 1);
520 for (
size_t w = first_window; w <= last_window; ++w) {
564 "Not enough points in draw window to generate curve segment ({} points)",
582 for (
size_t w = 0; w < windows; ++w) {
586 for (
size_t i = windows + 1; i <
m_draw_window.size(); ++i) {
#define MF_ERROR(comp, ctx,...)
#define MF_WARN(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
void evaluate_planar(std::span< const double > control_points, size_t dim, Eigen::Index num_samples, std::vector< double > &out, std::vector< double > &tangents)
Evaluate a curve into coordinate-major position and tangent buffers.
void reparameterize_planar(std::span< const double > points, size_t dim, Eigen::Index point_count, Eigen::Index num_samples, std::vector< double > &out)
Resample a polyline to uniform arc length, coordinate-major.
void configure(InterpolationMode mode, double tension)
Re-resolve the kernel.
Portal::Graphics::PrimitiveTopology m_primitive_topology
std::optional< Kakshya::VertexLayout > get_vertex_layout() const
Get cached vertex layout.
void set_vertex_layout(const Kakshya::VertexLayout &layout)
Set cached vertex layout.
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.
Base class for nodes that generate 3D geometry data.
void generate_path_vertices()
void set_samples_per_segment(Eigen::Index samples)
Set samples per segment.
std::array< double, 12 > m_segment_controls
void compute_frame() override
Compute frame - generates interpolated vertices from control points.
std::vector< LineVertex > m_draw_window
size_t m_dirty_segment_start
void generate_custom_path()
void regenerate_geometry()
void refresh_attributes()
Rewrite colour and thickness over existing geometry, no curve evaluation.
size_t vertices_per_window() const
Vertices emitted per four-point window.
Kinesis::CurveEvaluator m_evaluator
Kinesis::InterpolationMode m_mode
PathGeneratorNode(Kinesis::InterpolationMode mode=Kinesis::InterpolationMode::QUADRATIC_BEZIER, Eigen::Index samples_per_segment=32, size_t max_control_points=64, double tension=0.5)
Create path generator with interpolation mode.
bool m_force_uniform_thickness
std::function< glm::vec3(std::span< const LineVertex >, double)> CustomPathFunction
void set_tension(double tension)
Set tension parameter (for Catmull-Rom)
void set_path_color(const glm::vec3 &color, bool force_uniform=true)
Set path color (applied to all generated vertices)
void write_curve_segment(const std::vector< LineVertex > &curve_verts, size_t start_idx, LineVertex *dst)
Evaluate one window and write its vertices.
std::vector< double > m_curve_tangents
std::vector< LineVertex > m_control_points
Control points, newest first: index 0 is the most recently added.
std::vector< double > m_curve_secondary
void force_uniform_color(bool should_force)
Set uniform color mode.
Eigen::Index m_samples_per_segment
bool m_arc_length_parameterization
glm::vec3 m_current_color
size_t m_dirty_segment_end
void complete()
Finish incremental drawing stroke.
float m_current_thickness
std::vector< LineVertex > m_completed_draws
CustomPathFunction m_custom_func
std::vector< LineVertex > m_vertices
void set_interpolation_mode(Kinesis::InterpolationMode mode)
Set interpolation mode.
void generate_direct_path()
void update_control_point(size_t index, const LineVertex &vertex)
Update specific control point with full LineVertex data.
std::vector< LineVertex > get_control_points() const
Get all control points as vector.
LineVertex get_control_point(size_t index) const
Get control point.
void set_path_thickness(float thickness, bool force_uniform=true)
Set path thickness (applied to all generated vertices)
void force_uniform_thickness(bool should_force)
Set uniform thickness mode.
void parameterize_arc_length(bool enable)
Enable/disable arc-length parameterization.
void regenerate_segment_range(size_t first_window, size_t last_window)
bool m_force_uniform_color
void set_control_points(const std::vector< LineVertex > &vertices)
Set all control points with full LineVertex data.
void add_control_point(const LineVertex &vertex)
Add control point with full LineVertex data.
void append_line_segment(const LineVertex &v0, const LineVertex &v1, std::vector< LineVertex > &output)
static constexpr size_t INVALID_SEGMENT
void clear_path()
Clear all control points and generated vertices.
std::vector< LineVertex > m_draw_vertices
std::vector< LineVertex > m_combined_cache
size_t m_max_control_points
void write_segment_attributes(const std::vector< LineVertex > &curve_verts, size_t start_idx, LineVertex *dst) const
Write colour and thickness for one window, leaving positions intact.
std::vector< double > m_curve_primary
void generate_interpolated_path()
void draw_to(const LineVertex &vertex)
Extend path with full LineVertex data.
@ NodeProcessing
Node graph processing (Nodes::NodeGraphManager)
@ Nodes
DSP Generator and Filter Nodes, graph pipeline, node management.
InterpolationMode
Mathematical interpolation methods.
void central_difference_tangents(std::span< const double > points, size_t dim, size_t count, std::vector< double > &tangents)
Tangents of a sampled curve by finite difference, coordinate-major.
Kakshya::LineVertex LineVertex
Vertex type for line primitives (LINE_LIST / LINE_STRIP topology)
static VertexLayout for_lines(uint32_t stride=60)
Factory: layout for LineVertex (position, color, thickness, uv, normal, tangent)