MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Influence.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <glm/gtc/quaternion.hpp>
4#include <glm/vec2.hpp>
5#include <glm/vec3.hpp>
6
7namespace MayaFlux::Nexus {
8
9/**
10 * @struct InfluenceContext
11 * @brief Data passed to an Emitter or Agent influence function on each commit.
12 *
13 * Only the fields relevant to the active execution path are populated.
14 * Fields marked @note future are reserved for later domain expansions and
15 * are always default-initialised in the current implementation.
16 */
18 glm::vec3 position {}; ///< Position of the influence point in world space.
19
20 float intensity { 1.0F }; ///< Intensity of the influence, typically in the range [0, 1], but may exceed 1 for strong influences.
21
22 float radius { 1.0F }; ///< Radius of influence around the position, defining the area of effect for spatially-dependent influences.
23
24 std::optional<glm::vec3> color; ///< Optional color hint for the influence, may be used for visualisation or shader effects.
25
26 std::optional<float> size; ///< Optional size hint for the influence, may be used for visualisation or shader effects.
27
28 std::optional<glm::vec2> cursor_pos; ///< Optional cursor position for pending interactions, useful for real-time editing or previewing influence effects.
29
30 std::optional<glm::quat> orientation; ///< Optional orientation of the influencer. Local +Z is its forward direction.
31
32 // @note future: ShaderProcessor* shader_proc { nullptr };
33 // @note future: std::span<const double> audio_snapshot;
34};
35
36/**
37 * @struct InfluenceBlock
38 * @brief Host mirror of the Influence push constant block the library's lit shaders declare.
39 *
40 * Build it from a context with from() and push it with bind_push_constants.
41 * @code
42 * layout(push_constant) uniform Influence {
43 * vec3 position;
44 * float intensity;
45 * vec3 color;
46 * float radius;
47 * float size;
48 * };
49 * @endcode
50 */
51struct alignas(16) InfluenceBlock {
52 glm::vec3 position { 0.0F };
53 float intensity { 1.0F };
54 glm::vec3 color { 1.0F, 1.0F, 1.0F };
55 float radius { 1.0F };
56 float size { 1.0F };
57 float _pad[3] {};
58
59 /** @brief The block for @p ctx, with white and size 1 where the context has none. */
60 [[nodiscard]] static InfluenceBlock from(const InfluenceContext& ctx)
61 {
62 return {
63 .position = ctx.position,
64 .intensity = ctx.intensity,
65 .color = ctx.color.value_or(glm::vec3(1.0F)),
66 .radius = ctx.radius,
67 .size = ctx.size.value_or(1.0F),
68 };
69 }
70};
71
72static_assert(sizeof(InfluenceBlock) == 48);
73
74/**
75 * @class Influence
76 * @brief A value of any type, built from the influence context and handed to its targets.
77 *
78 * T is whatever the targets need: a struct for a shader block, a vector, a
79 * matrix, a Tendency, a DataVariant. A target is any callable taking const T&
80 * and decides what the value affects. On each invoke the producer runs once and
81 * every target gets the value, in the order they were added.
82 *
83 * How many targets an Influence may have is decided by its owner: an Emitter
84 * keeps one, an Agent keeps as many as are added.
85 *
86 * Context is what the producer reads. Emitter and Agent supply an
87 * InfluenceContext, an Expanse supplies a CrossingContext. Targets take only
88 * const T&, so one target works with either.
89 */
90template <typename T, typename Context = InfluenceContext>
91class Influence {
92public:
93 using Producer = std::function<T(const Context&)>;
94 using Target = std::function<void(const T&)>;
95
96 explicit Influence(Producer producer)
97 : m_producer(std::move(producer))
98 {
99 }
100
101 /** @brief Add a target. Returns this influence for chaining. */
103 {
104 m_targets.push_back(std::move(target));
105 return *this;
106 }
107
108 /** @brief Remove every target. */
109 void clear_targets() { m_targets.clear(); }
110
111 /** @brief Number of targets currently added. */
112 [[nodiscard]] size_t target_count() const { return m_targets.size(); }
113
114 /** @brief Build the value from @p ctx and hand it to every target. */
115 void invoke(const Context& ctx) const
116 {
117 if (!m_producer) {
118 return;
119 }
120 const T value = m_producer(ctx);
121 for (const auto& target : m_targets) {
122 target(value);
123 }
124 }
125
126private:
128 std::vector<Target> m_targets;
129};
130
131} // namespace MayaFlux::Nexus
glm::vec3 value
std::vector< Target > m_targets
void invoke(const Context &ctx) const
Build the value from ctx and hand it to every target.
std::function< T(const Context &)> Producer
Definition Influence.hpp:93
void clear_targets()
Remove every target.
Influence(Producer producer)
Definition Influence.hpp:96
Influence & add_target(Target target)
Add a target.
std::function< void(const T &)> Target
Definition Influence.hpp:94
size_t target_count() const
Number of targets currently added.
A value of any type, built from the influence context and handed to its targets.
Definition Influence.hpp:91
static InfluenceBlock from(const InfluenceContext &ctx)
The block for ctx, with white and size 1 where the context has none.
Definition Influence.hpp:60
Host mirror of the Influence push constant block the library's lit shaders declare.
Definition Influence.hpp:51
glm::vec3 position
Position of the influence point in world space.
Definition Influence.hpp:18
std::optional< glm::vec2 > cursor_pos
Optional cursor position for pending interactions, useful for real-time editing or previewing influen...
Definition Influence.hpp:28
std::optional< glm::vec3 > color
Optional color hint for the influence, may be used for visualisation or shader effects.
Definition Influence.hpp:24
std::optional< float > size
Optional size hint for the influence, may be used for visualisation or shader effects.
Definition Influence.hpp:26
float intensity
Intensity of the influence, typically in the range [0, 1], but may exceed 1 for strong influences.
Definition Influence.hpp:20
float radius
Radius of influence around the position, defining the area of effect for spatially-dependent influenc...
Definition Influence.hpp:22
std::optional< glm::quat > orientation
Optional orientation of the influencer. Local +Z is its forward direction.
Definition Influence.hpp:30
Data passed to an Emitter or Agent influence function on each commit.
Definition Influence.hpp:17