MayaFlux 0.5.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Geometry.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "Mapped.hpp"
4
6class Context;
7}
8
10
11/**
12 * @file Geometry.hpp
13 * @brief Illustrative geometry functions for common Mapped use cases.
14 *
15 * These are starting points for reading and understanding the GeometryFn
16 * contract, not the primary or idiomatic way to use Mapped in MayaFlux.
17 *
18 * The idiomatic use is a custom geometry function that writes from whatever
19 * data source makes sense: mouse pixel coordinates written directly as buffer
20 * data, microphone energy mapped to a spatial form, a node output driving
21 * vertex positions, a tendency field evaluated at runtime. The function
22 * receives a value and an output byte buffer — what it does with those is
23 * unconstrained.
24 *
25 * The helpers below demonstrate the pattern concretely. They are not
26 * privileged and carry no special status in the framework.
27 */
28
29/**
30 * @brief Write a vertex array into a GeometryFn output buffer.
31 * @param out Output buffer. Resized to fit @p verts exactly.
32 * @param verts Vertices to copy.
33 */
34template <typename V>
35void write_verts(std::vector<uint8_t>& out, const std::vector<V>& verts)
36{
37 out.resize(verts.size() * sizeof(V));
38 std::memcpy(out.data(), verts.data(), out.size());
39}
40
41/**
42 * @brief Write a contiguous range of trivially-copyable vertices into a GeometryFn output buffer.
43 */
44template <typename V>
45 requires std::ranges::contiguous_range<V>
46 && std::is_trivially_copyable_v<std::ranges::range_value_t<V>>
47void write_verts(std::vector<uint8_t>& out, const V& verts)
48{
49 const size_t n = std::ranges::size(verts) * sizeof(std::ranges::range_value_t<V>);
50 out.resize(n);
51 std::memcpy(out.data(), std::ranges::data(verts), n);
52}
53
54template <typename V>
55 requires std::is_trivially_copyable_v<V>
56 && (!std::ranges::range<V>)
57void write_verts(std::vector<uint8_t>& out, const V& v)
58{
59 out.resize(sizeof(v));
60 std::memcpy(out.data(), &v, sizeof(v));
61}
62
63/**
64 * @struct Form
65 * @brief A geometry function plus everything its realization requires.
66 *
67 * A geometry function alone is not enough to construct an element. Its
68 * topology is fixed by the vertex kind it writes, its capacity by the
69 * vertex count, and its interaction by the forward placement it performs.
70 * All three are knowledge the geometry factory already has and the call
71 * site would otherwise restate. Form carries them together.
72 *
73 * Nothing enumerates the set of Forms. Any function returning one
74 * participates on equal footing with those in FormFactory.hpp, including
75 * ones written by the caller. There is no dispatch and no registry.
76 *
77 * A bare GeometryFn converts implicitly, yielding default topology,
78 * default capacity, and no interaction.
79 *
80 * @tparam T MappedState value type driving the geometry.
81 */
82template <typename T>
83struct Form {
84 /// @brief Writes vertex bytes for the current value.
86
87 /// @brief Topology matching the vertex kind @c geometry writes.
89
90 /// @brief FormaBuffer capacity in bytes for the vertex count @c geometry writes.
91 size_t capacity { 4096 };
92
93 /**
94 * @brief Registers interaction against the realized element.
95 *
96 * Called once after the element is registered, with the Context that
97 * owns its callbacks, the element id, and the state to write. Empty
98 * for non-interactive geometry.
99 */
100 std::function<void(Context&, uint32_t, std::shared_ptr<MappedState<T>>)> wire;
101
102 Form() = default;
103
104 /**
105 * @brief Adopt a bare geometry function with default topology and
106 * capacity and no interaction.
107 */
109 : geometry(std::move(fn))
110 {
111 }
112
114 std::function<void(Context&, uint32_t, std::shared_ptr<MappedState<T>>)> w = {})
115 : geometry(std::move(fn))
116 , topology(topo)
117 , capacity(cap)
118 , wire(std::move(w))
119 {
120 }
121
122 /**
123 * @brief Implicit conversion to the underlying geometry function.
124 *
125 * This allows a Form to be passed directly to create_element, which
126 * accepts a GeometryFn. The default topology and capacity are used,
127 * and no interaction is registered.
128 */
129 operator const GeometryFn<T>&() const& { return geometry; }
130};
131
132/**
133 * @brief Call a bounds-taking factory with an anchor's region.
134 *
135 * Any factory whose first parameter is a Kinesis::AABB2D accepts any
136 * Kinesis::HasBounds object through this, including factories written by
137 * the caller. Nothing is enumerated and no geometry is privileged.
138 *
139 * Trailing factory defaults still apply; arguments passed here are
140 * forwarded in order after the derived bounds.
141 *
142 * @code
143 * auto fader = Forma::create(surface, Geometry::horizontal_fader(track, 0.04F), 0.5F);
144 * auto meter = Forma::create(surface, Geometry::at(fader, Geometry::level_meter), 0.F);
145 * @endcode
146 *
147 * @param anchor Any object exposing bounds().
148 * @param factory Factory taking Kinesis::AABB2D as its first parameter.
149 * @param args Remaining factory arguments.
150 */
151template <Kinesis::HasBounds B, typename F, typename... Args>
152[[nodiscard]] auto at(const B& anchor, F&& factory, Args&&... args)
153 -> decltype(std::forward<F>(factory)(Kinesis::bounds_of(anchor), std::forward<Args>(args)...))
154{
155 return std::forward<F>(factory)(Kinesis::bounds_of(anchor), std::forward<Args>(args)...);
156}
157
158} // namespace MayaFlux::Portal::Forma::Geometry
#define B(method_name, full_type_name)
Definition Creator.hpp:130
Event wiring between a Layer and a window surface.
Definition Context.hpp:40
Any type carrying a spatial footprint usable as a placement anchor.
Definition Bounds.hpp:608
Context
Execution contexts for log messages.
AABB2D bounds_of(const T &obj)
Extract the anchor region from any HasBounds object.
Definition Bounds.hpp:614
auto at(const B &anchor, F &&factory, Args &&... args) -> decltype(std::forward< F >(factory)(Kinesis::bounds_of(anchor), std::forward< Args >(args)...))
Call a bounds-taking factory with an anchor's region.
Definition Geometry.hpp:152
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
std::function< void(T value, std::vector< uint8_t > &out_bytes, Element &element)> GeometryFn
Geometry function signature.
Definition Mapped.hpp:64
PrimitiveTopology
Vertex assembly primitive topology.
Form(GeometryFn< T > fn)
Adopt a bare geometry function with default topology and capacity and no interaction.
Definition Geometry.hpp:108
GeometryFn< T > geometry
Writes vertex bytes for the current value.
Definition Geometry.hpp:85
size_t capacity
FormaBuffer capacity in bytes for the vertex count geometry writes.
Definition Geometry.hpp:91
std::function< void(Context &, uint32_t, std::shared_ptr< MappedState< T > >)> wire
Registers interaction against the realized element.
Definition Geometry.hpp:100
Form(GeometryFn< T > fn, Graphics::PrimitiveTopology topo, size_t cap, std::function< void(Context &, uint32_t, std::shared_ptr< MappedState< T > >)> w={})
Definition Geometry.hpp:113
Graphics::PrimitiveTopology topology
Topology matching the vertex kind geometry writes.
Definition Geometry.hpp:88
A geometry function plus everything its realization requires.
Definition Geometry.hpp:83
Value carrier for a Mapped primitive.
Definition Mapped.hpp:36