MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
NavigationState.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "ViewTransform.hpp"
4
5namespace MayaFlux::Kinesis {
6
7/**
8 * @struct NavigationConfig
9 * @brief Tuning parameters for a first-person fly-navigation controller.
10 */
12 glm::vec3 initial_eye { 0.0F, 0.0F, 5.0F };
13 glm::vec3 initial_target { 0.0F, 0.0F, 0.0F };
14 float fov_radians { glm::radians(60.0F) };
15 float near_plane { 0.01F };
16 float far_plane { 1000.0F };
17 float move_speed { 3.0F }; ///< World units per second
18 float mouse_sensitivity { 0.002F }; ///< Radians per pixel
19 float scroll_speed { 0.5F }; ///< World units per scroll tick
20};
21
22/**
23 * @struct NavigationState
24 * @brief Mutable first-person navigation state.
25 *
26 * Holds eye position, orientation angles, per-axis movement flags, and
27 * mouse tracking state. All fields are plain data; no engine or event
28 * system dependency.
29 *
30 * Construct via make_navigation_state() to derive initial yaw/pitch from
31 * NavigationConfig::initial_target. Update by mutating fields directly,
32 * then call compute_view_transform() each frame.
33 */
35 glm::vec3 eye { 0.0F, 0.0F, 5.0F };
36 float yaw { 0.0F }; ///< Radians, horizontal rotation
37 float pitch { 0.0F }; ///< Radians, vertical rotation, clamped to [-89, +89] degrees
38
39 bool forward_held { false };
40 bool back_held { false };
41 bool left_held { false };
42 bool right_held { false };
43 bool down_held { false };
44 bool up_held { false };
45
46 bool rmb_held { false };
47 bool first_mouse { true };
48 double last_x { 0.0 };
49 double last_y { 0.0 };
50
51 float move_speed { 3.0F };
52 float mouse_sensitivity { 0.002F };
53 float scroll_speed { 0.5F };
54 float fov_radians { glm::radians(60.0F) };
55 float near_plane { 0.01F };
56 float far_plane { 1000.0F };
57
58 std::chrono::steady_clock::time_point last_tick { std::chrono::steady_clock::now() };
59
60 /** @brief Optional constraint applied to the proposed eye position after
61 * each advance. Receives the candidate position and returns the
62 * actual position to commit. Identity (no constraint) if empty.
63 **/
64 std::function<glm::vec3(glm::vec3)> eye_constraint;
65};
66
67/**
68 * @brief Construct a NavigationState from a NavigationConfig.
69 *
70 * Derives initial yaw and pitch from the look direction
71 * (config.initial_target - config.initial_eye) so the first frame does
72 * not produce a view jump.
73 *
74 * @param config Source configuration
75 * @return Initialised NavigationState
76 */
77[[nodiscard]] MAYAFLUX_API NavigationState make_navigation_state(const NavigationConfig& config);
78
79/**
80 * @brief Compute a ViewTransform from the current NavigationState.
81 *
82 * Computes dt from state.last_tick, advances eye position by held movement
83 * flags scaled by move_speed * dt, updates last_tick, then constructs view
84 * and projection matrices.
85 *
86 * @param state Navigation state (eye and last_tick mutated by this call)
87 * @param aspect Framebuffer width / height
88 * @return ViewTransform ready for push constant upload
89 */
90[[nodiscard]] MAYAFLUX_API ViewTransform compute_view_transform(NavigationState& state, float aspect);
91
92/**
93 * @brief Apply a mouse delta to yaw and pitch.
94 *
95 * Pitch is clamped to [-89, +89] degrees to avoid gimbal lock at the poles.
96 *
97 * @param state Navigation state (yaw, pitch mutated)
98 * @param dx Horizontal pixel delta (positive = right)
99 * @param dy Vertical pixel delta (positive = down)
100 */
101MAYAFLUX_API void apply_mouse_delta(NavigationState& state, float dx, float dy);
102
103/**
104 * @brief Dolly eye along the current forward vector.
105 *
106 * @param state Navigation state (eye mutated)
107 * @param ticks Signed scroll ticks (positive = forward)
108 */
109MAYAFLUX_API void apply_scroll(NavigationState& state, float ticks);
110
111/**
112 * @brief Snap to a named ortho view.
113 *
114 * Preserves the current distance from the origin. Yaw/pitch are set to
115 * exact axis-aligned values. The top view uses pitch = -89 degrees to
116 * avoid the degenerate lookAt case at exactly -90 degrees.
117 *
118 * @param state Navigation state (eye, yaw, pitch mutated)
119 * @param view 0 = front (+Z), 1 = right (+X), 2 = top (+Y), 3 = flip opposite
120 */
121MAYAFLUX_API void snap_ortho(NavigationState& state, int view);
122
123/**
124 * @brief Advance eye position by held movement flags against elapsed time.
125 *
126 * Computes dt from state.last_tick, moves the eye along the current forward
127 * and right vectors by the flags that are set, and updates last_tick.
128 * Does not produce a ViewTransform. Use build_view_transform() after this
129 * when the matrices are needed separately from the eye update.
130 *
131 * @param state Navigation state (eye and last_tick mutated by this call)
132 */
133MAYAFLUX_API void advance_navigation(NavigationState& state);
134
135/**
136 * @brief Build a ViewTransform from the current NavigationState without mutating it.
137 *
138 * Pure read of eye, yaw, pitch, fov_radians, near_plane, far_plane. Does not
139 * advance the eye or update last_tick. Call advance_navigation() first when
140 * the eye needs to move.
141 *
142 * @param state Navigation state (read-only)
143 * @param aspect Framebuffer width / height
144 * @return ViewTransform ready for push constant upload
145 */
146[[nodiscard]] ViewTransform build_view_transform(const NavigationState& state, float aspect);
147
148} // namespace MayaFlux::Kinesis
void advance_navigation(NavigationState &st)
Advance eye position by held movement flags against elapsed time.
void apply_scroll(NavigationState &st, float ticks)
Dolly eye along the current forward vector.
NavigationState make_navigation_state(const NavigationConfig &config)
Construct a NavigationState from a NavigationConfig.
ViewTransform compute_view_transform(NavigationState &st, float aspect)
Compute a ViewTransform from the current NavigationState.
void snap_ortho(NavigationState &st, int view)
Snap to a named ortho view.
void apply_mouse_delta(NavigationState &st, float dx, float dy)
Apply a mouse delta to yaw and pitch.
ViewTransform build_view_transform(const NavigationState &st, float aspect)
Build a ViewTransform from the current NavigationState without mutating it.
float mouse_sensitivity
Radians per pixel.
float scroll_speed
World units per scroll tick.
float move_speed
World units per second.
Tuning parameters for a first-person fly-navigation controller.
float pitch
Radians, vertical rotation, clamped to [-89, +89] degrees.
float yaw
Radians, horizontal rotation.
std::chrono::steady_clock::time_point last_tick
std::function< glm::vec3(glm::vec3)> eye_constraint
Optional constraint applied to the proposed eye position after each advance.
Mutable first-person navigation state.
View and projection matrices as a named push constant slot.