MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Presence.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "Agent.hpp"
4
5namespace MayaFlux::Nexus {
6
7/**
8 * @class Presence
9 * @brief Agent that affects its surroundings by being there.
10 *
11 * An Agent already carries both a perception function and an influence
12 * function plus a query radius. Presence makes both concrete around the act of
13 * radiating into nearby entities:
14 *
15 * Perception is sensing the neighborhood. The spatial query Fabric runs on
16 * each commit populates the perception context with the entities inside the
17 * query radius. Presence stores that result so the influence half can act on
18 * it, after the user perception callable runs.
19 *
20 * Influence is radiation. For every neighbor found, Presence computes a
21 * falloff weight from the neighbor's squared distance against the falloff
22 * radius, then invokes a per-neighbor callable with the neighbor's id and its
23 * weight. The user callable decides what being near this Presence does to that
24 * neighbor: a parameter written, a force applied, a value pushed, anything.
25 * The Presence does not know what a neighbor is, only how near it is.
26 *
27 * The falloff radius is independent of the query radius. The query radius
28 * decides who is a neighbor; the falloff radius decides how the weight decays
29 * across that neighborhood. By default the falloff radius tracks the query
30 * radius. The falloff curve is linear by default and replaceable.
31 *
32 * The base perception and influence callables still fire. Presence layers its
33 * neighborhood sensing and radiation on top: the user perception callable runs,
34 * then the result is captured; the user influence callable runs, then each
35 * neighbor is radiated into.
36 *
37 * Wiring a Presence with every(1.0/60.0) drives the whole cycle each frame. A
38 * Presence without a position senses an empty neighborhood and radiates into
39 * nothing.
40 */
41class MAYAFLUX_API Presence : public Agent {
42public:
43 /** @brief Built-in falloff curves that survive state encode/decode. */
44 enum class FalloffCurve : uint8_t { Linear,
45 Cosine,
46 Exponential,
47 InverseSquare };
48
49 /**
50 * @brief Falloff curve mapping normalized distance to weight.
51 *
52 * Receives distance / falloff_radius clamped to [0, 1] and returns the
53 * weight at that distance. The default is linear: 1 at the center, 0 at the
54 * radius.
55 */
56 using FalloffFn = std::function<float(float)>;
57
58 /**
59 * @brief Per-neighbor radiation callable.
60 *
61 * Invoked once per neighbor inside the falloff radius on each influence.
62 *
63 * @param id Neighbor entity id from the spatial snapshot.
64 * @param weight Falloff weight in [0, 1], 1 at the Presence center.
65 */
66 using RadiateFn = std::function<void(uint32_t id, float weight)>;
67
68 /**
69 * @brief Construct with perception, influence, and radiation functions.
70 * @param query_radius Radius passed to the spatial index on each commit.
71 * @param perception User perception callable, fired before the neighborhood is captured.
72 * @param influence User influence callable, fired before radiation.
73 * @param radiate Invoked per neighbor inside the falloff radius.
74 */
75 Presence(float query_radius,
76 PerceptionFn perception,
77 InfluenceFn influence,
78 RadiateFn radiate);
79
80 /**
81 * @brief Construct with all named callables.
82 * @param query_radius Radius passed to the spatial index on each commit.
83 * @param perception_fn_name Identifier for the perception function.
84 * @param perception User perception callable.
85 * @param influence_fn_name Identifier for the influence function.
86 * @param influence User influence callable.
87 * @param radiate_fn_name Identifier for the radiation function.
88 * @param radiate Invoked per neighbor inside the falloff radius.
89 */
90 Presence(float query_radius,
91 std::string perception_fn_name, PerceptionFn perception,
92 std::string influence_fn_name, InfluenceFn influence,
93 std::string radiate_fn_name, RadiateFn radiate);
94
95 // =========================================================================
96 // Falloff
97 // =========================================================================
98
99 /**
100 * @brief Set the falloff radius, the distance over which the weight decays.
101 *
102 * Independent of the query radius. If never set, the falloff radius tracks
103 * the query radius.
104 *
105 * @param r Falloff radius in world-space units.
106 */
107 void set_falloff_radius(float r) { m_falloff_radius = r; }
108
109 /**
110 * @brief Current falloff radius, or the query radius if none was set.
111 */
112 [[nodiscard]] float falloff_radius() const
113 {
114 return m_falloff_radius > 0.0F ? m_falloff_radius : query_radius();
115 }
116
117 /**
118 * @brief Replace the falloff curve.
119 * @param fn Maps normalized distance in [0, 1] to a weight.
120 */
121 void set_falloff(FalloffFn fn) { m_falloff = std::move(fn); }
122
123 /**
124 * @brief Replace the per-neighbor radiation callable.
125 * @param fn Invoked per neighbor on each influence.
126 */
127 void set_radiate(RadiateFn fn) { m_radiate = std::move(fn); }
128
129 /** @brief Identifier for the radiate callable, empty if anonymous. */
130 [[nodiscard]] const std::string& radiate_fn_name() const { return m_radiate_fn_name; }
131
132 /** @brief Set or replace the radiate callable identifier. */
133 void set_radiate_fn_name(std::string name) { m_radiate_fn_name = std::move(name); }
134
135 /**
136 * @brief Neighbors captured on the most recent perception, with weights.
137 *
138 * Each entry is the neighbor id paired with its falloff weight, valid after
139 * the first commit-driven or wired invocation.
140 */
141 [[nodiscard]] const std::vector<std::pair<uint32_t, float>>& neighbors() const
142 {
143 return m_neighbors;
144 }
145
146 /** @brief Set the falloff curve to a named built-in. */
147 void set_falloff_curve(FalloffCurve curve);
148
149 /** @brief Current named curve, or nullopt if a custom lambda was set via set_falloff(). */
150 [[nodiscard]] std::optional<FalloffCurve> falloff_curve() const { return m_falloff_curve; }
151
152 // =========================================================================
153 // Perception and influence — Presence behaviour layered on the Agent path
154 // =========================================================================
155
156 void invoke_perception(const PerceptionContext& ctx) override;
157
158 void invoke_influence(const InfluenceContext& ctx) const override;
159
160private:
161 float m_falloff_radius { 0.0F };
164
165 std::string m_radiate_fn_name;
166 std::optional<FalloffCurve> m_falloff_curve { FalloffCurve::Linear };
167 mutable std::vector<std::pair<uint32_t, float>> m_neighbors;
168};
169
170} // namespace MayaFlux::Nexus
double weight
std::function< void(const PerceptionContext &)> PerceptionFn
Definition Agent.hpp:31
std::function< void(const InfluenceContext &)> InfluenceFn
Definition Agent.hpp:30
Object that both perceives nearby entities and acts on MayaFlux objects.
Definition Agent.hpp:28
std::vector< std::pair< uint32_t, float > > m_neighbors
Definition Presence.hpp:167
std::function< float(float)> FalloffFn
Falloff curve mapping normalized distance to weight.
Definition Presence.hpp:56
void set_radiate_fn_name(std::string name)
Set or replace the radiate callable identifier.
Definition Presence.hpp:133
std::string m_radiate_fn_name
Definition Presence.hpp:165
void set_radiate(RadiateFn fn)
Replace the per-neighbor radiation callable.
Definition Presence.hpp:127
const std::string & radiate_fn_name() const
Identifier for the radiate callable, empty if anonymous.
Definition Presence.hpp:130
float falloff_radius() const
Current falloff radius, or the query radius if none was set.
Definition Presence.hpp:112
std::optional< FalloffCurve > falloff_curve() const
Current named curve, or nullopt if a custom lambda was set via set_falloff().
Definition Presence.hpp:150
FalloffCurve
Built-in falloff curves that survive state encode/decode.
Definition Presence.hpp:44
void set_falloff_radius(float r)
Set the falloff radius, the distance over which the weight decays.
Definition Presence.hpp:107
void set_falloff(FalloffFn fn)
Replace the falloff curve.
Definition Presence.hpp:121
const std::vector< std::pair< uint32_t, float > > & neighbors() const
Neighbors captured on the most recent perception, with weights.
Definition Presence.hpp:141
std::function< void(uint32_t id, float weight)> RadiateFn
Per-neighbor radiation callable.
Definition Presence.hpp:66
Agent that affects its surroundings by being there.
Definition Presence.hpp:41
Data passed to an Emitter or Agent influence function on each commit.
Data passed to a Sensor or Agent perception function on each commit.