MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Locus.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "Agent.hpp"
4
6
7namespace MayaFlux::Buffers {
8class RenderProcessor;
9}
10
11namespace MayaFlux::Nexus {
12
13/**
14 * @class Locus
15 * @brief Agent that perceives the world from a navigation state and influences
16 * how the things it touches are viewed.
17 *
18 * An Agent already carries both a perception function and an influence
19 * function. Locus makes both concrete around a Kinesis::NavigationState:
20 *
21 * Perception is observation. The navigation state is the lens. Held movement
22 * flags, yaw, and pitch advance the eye; the perception path integrates that
23 * motion against elapsed time and produces the current ViewTransform. The
24 * Locus sees the world from wherever its navigation state currently sits, and
25 * its inherited Agent position follows the eye so the spatial index and any
26 * PerceptionContext observe the same point.
27 *
28 * Influence is re-viewing. A Locus holds a set of view targets: render
29 * processors whose view transform it drives. On each influence the current
30 * ViewTransform is pushed to every target. The same motion that determines
31 * what the Locus perceives determines how everything under its influence is
32 * seen. Multiple processors driven by one Locus share its viewpoint; multiple
33 * Loci over disjoint targets partition the scene into independently-viewed
34 * regions.
35 *
36 * The base perception and influence callables still fire. Locus layers its view
37 * behaviour on top: the user callables run, then the view is integrated and
38 * distributed. A user perception callable can read the freshly produced
39 * transform through the Locus; a user influence callable can add domain effects
40 * alongside the view push.
41 *
42 * The navigation state is plain data, mutated directly through nav() or via the
43 * Kinesis free functions (apply_mouse_delta, apply_scroll, snap_ortho). Wiring a
44 * Locus with every(1.0/60.0) drives the whole cycle each frame. Because the view
45 * push writes a render processor UBO, wire the Locus so its influence fires on
46 * the graphics thread when it drives view targets.
47 */
48class MAYAFLUX_API Locus : public Agent {
49public:
50 /**
51 * @brief Construct from a NavigationConfig with perception and influence functions.
52 * @param config Initial navigation configuration. eye seeds the position.
53 * @param query_radius Radius passed to the spatial index on each commit.
54 * @param perception User perception callable, fired before the view integrates.
55 * @param influence User influence callable, fired before the view is pushed.
56 */
57 Locus(const Kinesis::NavigationConfig& config,
58 float query_radius,
59 PerceptionFn perception,
60 InfluenceFn influence);
61
62 /**
63 * @brief Construct from a NavigationConfig with named perception and influence functions.
64 * @param config Initial navigation configuration. eye seeds the position.
65 * @param query_radius Radius passed to the spatial index on each commit.
66 * @param perception_fn_name Identifier for the perception function.
67 * @param perception User perception callable, fired before the view integrates.
68 * @param influence_fn_name Identifier for the influence function.
69 * @param influence User influence callable, fired before the view is pushed.
70 */
71 Locus(const Kinesis::NavigationConfig& config,
72 float query_radius,
73 std::string perception_fn_name, PerceptionFn perception,
74 std::string influence_fn_name, InfluenceFn influence);
75
76 // =========================================================================
77 // Navigation state
78 // =========================================================================
79
80 /**
81 * @brief Mutable access to the navigation lens.
82 *
83 * Movement flags, yaw, pitch, and tuning fields are mutated through this
84 * reference or via the Kinesis free functions. The eye advances on the next
85 * perceive(); the inherited position follows.
86 */
87 [[nodiscard]] Kinesis::NavigationState& nav() { return m_nav; }
88
89 /**
90 * @brief Read-only access to the navigation lens.
91 */
92 [[nodiscard]] const Kinesis::NavigationState& nav() const { return m_nav; }
93
94 /**
95 * @brief The ViewTransform produced by the most recent perceive().
96 *
97 * Valid after the first commit-driven or wired invocation. Before that it
98 * is the transform of the initial navigation state at unit aspect.
99 */
100 [[nodiscard]] const Kinesis::ViewTransform& current_view() const { return m_view; }
101
102 /**
103 * @brief Aspect ratio used when integrating the view.
104 *
105 * Defaults to 1. Set from the target window's framebuffer dimensions so the
106 * projection matches what is on screen.
107 */
108 void set_aspect(float aspect) { m_aspect = aspect; }
109
110 /** @brief Current aspect ratio. */
111 [[nodiscard]] float aspect() const { return m_aspect; }
112
113 // =========================================================================
114 // View targets — the processors this Locus re-views
115 // =========================================================================
116
117 /**
118 * @brief Add a render processor whose view transform this Locus drives.
119 *
120 * On each influence the processor receives the Locus's current
121 * ViewTransform. Adding the same processor twice is a no-op. The processor
122 * must outlive the Locus or be removed via remove_view_target().
123 *
124 * @param proc Render processor to drive. Ignored if null.
125 */
126 void add_view_target(std::shared_ptr<Buffers::RenderProcessor> proc);
127
128 /**
129 * @brief Stop driving a render processor's view transform.
130 * @param proc Processor previously added via add_view_target().
131 */
132 void remove_view_target(const std::shared_ptr<Buffers::RenderProcessor>& proc);
133
134 /**
135 * @brief All render processors currently driven by this Locus.
136 */
137 [[nodiscard]] const std::vector<std::shared_ptr<Buffers::RenderProcessor>>& view_targets() const
138 {
139 return m_view_targets;
140 }
141
142 // =========================================================================
143 // Perception and influence — Locus behaviour layered on the Agent path
144 // =========================================================================
145
146 /**
147 * @brief Perceive: run the user perception callable, then integrate the view.
148 *
149 * Fires the inherited perception callable with @p ctx, advances the eye by
150 * held movement flags scaled by elapsed time, mirrors the new eye into the
151 * inherited position, and stores the resulting ViewTransform. The Locus
152 * now sees the world from its updated state.
153 *
154 * @param ctx Perception context built by Fabric from the spatial snapshot.
155 */
156 void invoke_perception(const PerceptionContext& ctx) override;
157
158 /**
159 * @brief Influence: run the user influence callable, then push the current
160 * view to every view target.
161 *
162 * Fires the inherited influence callable with @p ctx and dispatches the
163 * Locus's audio and render sinks, then sets the stored ViewTransform on
164 * each render processor in view_targets(). Everything under this Locus's
165 * influence is seen from its viewpoint.
166 *
167 * @param ctx Influence context built by Fabric from the Locus's state.
168 */
169 void invoke_influence(const InfluenceContext& ctx) const override;
170
171private:
174 float m_aspect { 1.0F };
175 std::vector<std::shared_ptr<Buffers::RenderProcessor>> m_view_targets;
176};
177
178} // namespace MayaFlux::Nexus
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
const Kinesis::ViewTransform & current_view() const
The ViewTransform produced by the most recent perceive().
Definition Locus.hpp:100
Kinesis::NavigationState m_nav
Definition Locus.hpp:172
const std::vector< std::shared_ptr< Buffers::RenderProcessor > > & view_targets() const
All render processors currently driven by this Locus.
Definition Locus.hpp:137
const Kinesis::NavigationState & nav() const
Read-only access to the navigation lens.
Definition Locus.hpp:92
std::vector< std::shared_ptr< Buffers::RenderProcessor > > m_view_targets
Definition Locus.hpp:175
void set_aspect(float aspect)
Aspect ratio used when integrating the view.
Definition Locus.hpp:108
float aspect() const
Current aspect ratio.
Definition Locus.hpp:111
Kinesis::NavigationState & nav()
Mutable access to the navigation lens.
Definition Locus.hpp:87
Agent that perceives the world from a navigation state and influences how the things it touches are v...
Definition Locus.hpp:48
Tuning parameters for a first-person fly-navigation controller.
Mutable first-person navigation state.
View and projection matrices as a named push constant slot.
Data passed to an Emitter or Agent influence function on each commit.
Data passed to a Sensor or Agent perception function on each commit.