MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Presence.cpp
Go to the documentation of this file.
1#include "Presence.hpp"
2
3#include <glm/gtc/constants.hpp>
4
5namespace MayaFlux::Nexus {
6
7namespace {
8
9 float linear_falloff(float t)
10 {
11 return 1.0F - std::clamp(t, 0.0F, 1.0F);
12 }
13
14} // namespace
15
16Presence::Presence(float query_radius,
17 PerceptionFn perception,
18 InfluenceFn influence,
19 RadiateFn radiate)
20 : Agent(query_radius, std::move(perception), std::move(influence))
21 , m_falloff(linear_falloff)
22 , m_radiate(std::move(radiate))
23{
24}
25
26Presence::Presence(float query_radius,
27 std::string perception_fn_name, PerceptionFn perception,
28 std::string influence_fn_name, InfluenceFn influence,
29 std::string radiate_fn_name, RadiateFn radiate)
30 : Agent(query_radius,
31 std::move(perception_fn_name), std::move(perception),
32 std::move(influence_fn_name), std::move(influence))
33 , m_falloff(linear_falloff)
34 , m_radiate_fn_name(std::move(radiate_fn_name))
35 , m_radiate(std::move(radiate))
36{
37}
38
40{
41 m_falloff_curve = curve;
42 switch (curve) {
44 m_falloff = [](float t) { return 1.0F - std::clamp(t, 0.0F, 1.0F); };
45 break;
47 m_falloff = [](float t) { return 0.5F * (1.0F + std::cos(std::clamp(t, 0.0F, 1.0F) * glm::pi<float>())); };
48 break;
50 m_falloff = [](float t) { return std::exp(-4.0F * std::clamp(t, 0.0F, 1.0F)); };
51 break;
53 m_falloff = [](float t) { const float c = std::clamp(t, 0.0F, 1.0F); return 1.0F / (1.0F + 16.0F * c * c); };
54 break;
55 }
56}
57
59{
61
62 m_neighbors.clear();
63
64 const float fr = falloff_radius();
65 const float fr_sq = fr * fr;
66
67 for (const auto& result : ctx.spatial_results) {
68 if (result.distance_sq > fr_sq) {
69 continue;
70 }
71 const float t = fr > 0.0F
72 ? std::sqrt(result.distance_sq) / fr
73 : 0.0F;
74 const float weight = m_falloff ? m_falloff(t) : linear_falloff(t);
75 m_neighbors.emplace_back(result.id, weight);
76 }
77}
78
80{
82
83 if (!m_radiate) {
84 return;
85 }
86
87 for (const auto& [id, weight] : m_neighbors) {
88 m_radiate(id, weight);
89 }
90}
91
92} // namespace MayaFlux::Nexus
double weight
virtual void invoke_influence(const InfluenceContext &ctx) const
Invoke the influence function with the supplied context.
Definition Agent.hpp:277
virtual void invoke_perception(const PerceptionContext &ctx)
Invoke the perception function with the supplied context.
Definition Agent.hpp:266
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
Presence(float query_radius, PerceptionFn perception, InfluenceFn influence, RadiateFn radiate)
Construct with perception, influence, and radiation functions.
Definition Presence.cpp:16
void invoke_perception(const PerceptionContext &ctx) override
Invoke the perception function with the supplied context.
Definition Presence.cpp:58
std::optional< FalloffCurve > m_falloff_curve
Definition Presence.hpp:166
float falloff_radius() const
Current falloff radius, or the query radius if none was set.
Definition Presence.hpp:112
FalloffCurve
Built-in falloff curves that survive state encode/decode.
Definition Presence.hpp:44
void invoke_influence(const InfluenceContext &ctx) const override
Invoke the influence function with the supplied context.
Definition Presence.cpp:79
void set_falloff_curve(FalloffCurve curve)
Set the falloff curve to a named built-in.
Definition Presence.cpp:39
std::function< void(uint32_t id, float weight)> RadiateFn
Per-neighbor radiation callable.
Definition Presence.hpp:66
Data passed to an Emitter or Agent influence function on each commit.
std::span< const Kinesis::QueryResult > spatial_results
Data passed to a Sensor or Agent perception function on each commit.