MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
NavigationState.cpp
Go to the documentation of this file.
1#include "NavigationState.hpp"
2
3namespace MayaFlux::Kinesis {
4
6{
8 st.eye = config.initial_eye;
9 st.move_speed = config.move_speed;
11 st.scroll_speed = config.scroll_speed;
12 st.fov_radians = config.fov_radians;
13 st.near_plane = config.near_plane;
14 st.far_plane = config.far_plane;
15
16 const glm::vec3 dir = glm::normalize(config.initial_target - config.initial_eye);
17 st.yaw = std::atan2(dir.x, dir.z);
18 st.pitch = std::asin(glm::clamp(dir.y, -1.0F, 1.0F));
19
20 return st;
21}
22
24{
25 const auto now = std::chrono::steady_clock::now();
26 const float dt = std::chrono::duration<float>(now - st.last_tick).count();
27 st.last_tick = now;
28
29 const glm::vec3 forward {
30 std::cos(st.pitch) * std::sin(st.yaw),
31 std::sin(st.pitch),
32 std::cos(st.pitch) * std::cos(st.yaw)
33 };
34 const glm::vec3 right = glm::normalize(glm::cross(forward, glm::vec3(0.0F, 1.0F, 0.0F)));
35
36 const float step = st.move_speed * dt;
37
38 if (st.forward_held)
39 st.eye += forward * step;
40 if (st.back_held)
41 st.eye -= forward * step;
42 if (st.left_held)
43 st.eye -= right * step;
44 if (st.right_held)
45 st.eye += right * step;
46 if (st.down_held)
47 st.eye -= glm::vec3(0.0F, 1.0F, 0.0F) * step;
48 if (st.up_held)
49 st.eye += glm::vec3(0.0F, 1.0F, 0.0F) * step;
50
51 return {
52 .view = glm::lookAt(st.eye, st.eye + forward, glm::vec3(0.0F, 1.0F, 0.0F)),
53 .projection = glm::perspective(st.fov_radians, aspect, st.near_plane, st.far_plane)
54 };
55}
56
57void apply_mouse_delta(NavigationState& st, float dx, float dy)
58{
59 st.yaw += dx * st.mouse_sensitivity;
60 st.pitch += dy * st.mouse_sensitivity;
61
62 static constexpr float k_limit = glm::radians(89.0F);
63 st.pitch = glm::clamp(st.pitch, -k_limit, k_limit);
64}
65
66void apply_scroll(NavigationState& st, float ticks)
67{
68 const glm::vec3 forward {
69 std::cos(st.pitch) * std::sin(st.yaw),
70 std::sin(st.pitch),
71 std::cos(st.pitch) * std::cos(st.yaw)
72 };
73 st.eye += forward * (ticks * st.scroll_speed);
74}
75
76void snap_ortho(NavigationState& st, int view)
77{
78 const float dist = glm::length(st.eye);
79
80 switch (view) {
81 case 0: // front: camera on +Z looking toward -Z
82 st.eye = glm::vec3(0.0F, 0.0F, dist);
83 st.yaw = 0.0F;
84 st.pitch = 0.0F;
85 break;
86 case 1: // right: camera on +X looking toward -X
87 st.eye = glm::vec3(dist, 0.0F, 0.0F);
88 st.yaw = glm::radians(-90.0F);
89 st.pitch = 0.0F;
90 break;
91 case 2: // top: camera on +Y looking straight down
92 st.eye = glm::vec3(0.0F, dist, 0.0F);
93 st.yaw = 0.0F;
94 st.pitch = glm::radians(-89.0F);
95 break;
96 case 3: // flip: mirror through origin
97 st.eye = -st.eye;
98 st.yaw = st.yaw + glm::pi<float>();
99 st.pitch = -st.pitch;
100 break;
101 default:
102 break;
103 }
104}
105
106} // namespace MayaFlux::Kinesis
NavigationState make_navigation_state(const NavigationConfig &config)
Construct a NavigationState from a NavigationConfig.
void apply_mouse_delta(NavigationState &st, float dx, float dy)
Apply a mouse delta to yaw and pitch.
void apply_scroll(NavigationState &st, float ticks)
Dolly eye along the current forward vector.
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.
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
Mutable first-person navigation state.
View and projection matrices as a named push constant slot.