MayaFlux 0.5.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ stroke_slider()

MAYAFLUX_API Form< float > MayaFlux::Portal::Forma::Geometry::stroke_slider ( std::span< const glm::vec2 >  path,
std::shared_ptr< Buffers::FormaBuffer handle_buf,
float  half_thickness = 0.02F,
glm::vec3  track_color = glm::vec3(0.3F),
glm::vec3  fill_color = glm::vec3(0.2F, 0.6F, 1.0F),
glm::vec3  handle_color = glm::vec3(0.95F),
float  handle_size = 10.0F 
)

Geometry function for a value scrubber along an arbitrary polyline.

Value in [0, 1] maps to arc-length position along path. The full path is rendered as a LINE_LIST in track_color; the prefix from the path start to the handle position is rendered in fill_color. The handle itself is a PointVertex submitted to handle_buf each sync.

Parameters
pathOrdered polyline vertices in NDC. Copied into closure.
handle_bufPOINT_LIST FormaBuffer for the handle point. Must be registered and have setup_rendering called.
half_thicknessHit region half-thickness in NDC units.
track_colorColor of the full path.
fill_colorColor of the prefix segment up to the handle.
handle_colorColor of the handle point.
handle_sizeHandle point size in pixels.

Definition at line 155 of file FormFactory.cpp.

163{
164 std::vector<glm::vec2> pts(path.begin(), path.end());
165
166 std::vector<float> seg_lengths;
167 seg_lengths.reserve(pts.size() > 0 ? pts.size() - 1 : 0);
168 float total_len = 0.0F;
169 for (size_t i = 0; i + 1 < pts.size(); ++i) {
170 float l = glm::length(pts[i + 1] - pts[i]);
171 seg_lengths.push_back(l);
172 total_len += l;
173 }
174
175 Kinesis::AABB2D aabb { .min = pts.empty() ? glm::vec2(0.F) : pts[0],
176 .max = pts.empty() ? glm::vec2(0.F) : pts[0] };
177 for (const auto& p : pts) {
178 aabb.min = glm::min(aabb.min, p);
179 aabb.max = glm::max(aabb.max, p);
180 }
181 aabb = aabb.expanded(half_thickness);
182
183 auto project = Kinesis::path_fraction(path);
184 const size_t cap = pts.size() * 4 * sizeof(Kakshya::LineVertex);
185
186 GeometryFn<float> fn = [pts = std::move(pts),
187 seg_lengths = std::move(seg_lengths),
188 total_len,
189 aabb,
190 handle_buf = std::move(handle_buf),
191 half_thickness,
192 track_color,
193 fill_color,
194 handle_color,
195 handle_size](float v, std::vector<uint8_t>& out, Element& el) {
196 if (pts.size() < 2) {
197 out.clear();
198 return;
199 }
200
201 const float target = std::clamp(v, 0.0F, 1.0F) * total_len;
202
203 glm::vec2 handle_pos = pts.front();
204 float accumulated = 0.0F;
205 size_t split_seg = 0;
206 float split_t = 0.0F;
207 for (size_t i = 0; i < seg_lengths.size(); ++i) {
208 if (accumulated + seg_lengths[i] >= target || i + 1 == seg_lengths.size()) {
209 split_t = seg_lengths[i] > 0.0F
210 ? (target - accumulated) / seg_lengths[i]
211 : 0.0F;
212 split_t = std::clamp(split_t, 0.0F, 1.0F);
213 handle_pos = glm::mix(pts[i], pts[i + 1], split_t);
214 split_seg = i;
215 break;
216 }
217 accumulated += seg_lengths[i];
218 }
219
220 auto verts = Kinesis::polyline(pts, track_color);
221
222 auto fill = Kinesis::polyline(
223 std::span<const glm::vec2>(pts).subspan(0, split_seg + 1),
224 fill_color);
225 verts.insert(verts.end(), fill.begin(), fill.end());
226
227 if (split_t > 0.0F) {
228 verts.push_back({ .position = { pts[split_seg].x, pts[split_seg].y, 0.0F }, .color = fill_color });
229 verts.push_back({ .position = { handle_pos.x, handle_pos.y, 0.0F }, .color = fill_color });
230 }
231
232 write_verts(out, verts);
233
234 el.bounds_hint = aabb;
235 el.contains = Kinesis::stroke_bounds(pts, half_thickness);
236
237 if (handle_buf) {
238 Kakshya::PointVertex hv {
239 .position = { handle_pos.x, handle_pos.y, 0.0F },
240 .color = handle_color,
241 .size = handle_size,
242 };
243 std::vector<uint8_t> hbytes(sizeof(hv));
244 std::memcpy(hbytes.data(), &hv, sizeof(hv));
245 handle_buf->submit(hbytes);
246 }
247 };
248
249 return { std::move(fn),
250 Graphics::PrimitiveTopology::LINE_LIST,
251 cap,
252 drag_with<float>(std::move(project)) };
253}
AABB3D aabb(std::span< T > pts) noexcept
Axis-aligned bounding box of a PositionCarrying span.
void write_verts(std::vector< uint8_t > &out, const std::vector< V > &verts)
Write a vertex array into a GeometryFn output buffer.
Definition Geometry.hpp:35
Vertex type for line primitives (LINE_LIST / LINE_STRIP topology)
Axis-aligned bounding rectangle in a 2D coordinate space.
Definition Bounds.hpp:21
bool contains(const glm::vec3 &p) const noexcept
Definition Bounds.hpp:147
AABB3D expanded(float margin) const noexcept
Definition Bounds.hpp:170

References MayaFlux::Kinesis::AABB3D::contains(), MayaFlux::Kinesis::AABB3D::expanded(), MayaFlux::Portal::Graphics::LINE_LIST, MayaFlux::Kinesis::AABB3D::max, MayaFlux::Kinesis::AABB3D::min, MayaFlux::Kinesis::path_fraction(), MayaFlux::Kinesis::polyline(), MayaFlux::Kakshya::PointVertex::position, MayaFlux::Kinesis::stroke_bounds(), and write_verts().

+ Here is the call graph for this function: