1#ifndef TATOOINE_RENDERING_CAMERA_CONTROLLER_H
2#define TATOOINE_RENDERING_CAMERA_CONTROLLER_H
12template <
typename Real>
13struct camera_controller;
15template <
typename Real>
16struct fps_camera_controller;
18template <
typename Real>
19struct orthographic_camera_controller;
21template <
typename Real>
48 vec3 const& up = {0, 1, 0}) {
58 virtual auto type() const -> std::type_info const& = 0;
60 virtual
void update(std::chrono::duration<
double> const& ) {}
63template <
typename Real>
77 :
m_pcam{{Real(0), Real(0), Real(0)},
78 {Real(0), Real(0), Real(1)},
80 static_cast<Real
>(0.01),
84 m_ocam{{Real(0), Real(0), Real(0)},
85 {Real(0), Real(0), Real(-1)},
86 m_orthographic_height,
91 m_active_cam{&m_pcam} {
96 m_orthographic_height = h;
97 m_ocam.set_projection_matrix(m_orthographic_height);
102 return m_active_cam->unproject(x);
105 return m_active_cam->unproject(x);
108 m_active_cam = &m_pcam;
111 m_active_cam = &m_ocam;
114 m_controller = std::make_unique<fps_camera_controller<Real>>(
this);
117 m_controller = std::make_unique<orthographic_camera_controller<Real>>(
this);
129 auto controller() const -> auto const& {
return *m_controller; }
132 return m_active_cam->transform_matrix();
135 auto eye()
const {
return m_active_cam->eye(); }
140 vec3 const& up = {0, 1, 0}) {
141 m_pcam.look_at(eye, lookat, up);
142 m_ocam.look_at(eye, lookat, up);
146 m_pcam.look_at(eye, pitch, yaw);
147 m_ocam.look_at(eye, pitch, yaw);
151 return m_active_cam->plane_height();
153 auto ray(
int x,
int y)
const {
return m_active_cam->ray(x, y); }
201 m_pcam.set_resolution(
static_cast<std::size_t
>(w),
static_cast<std::size_t
>(h));
202 m_ocam.set_resolution(
static_cast<std::size_t
>(w),
static_cast<std::size_t
>(h));
203 m_pcam.set_projection_matrix(60,
static_cast<Real
>(0.001), 1000);
204 m_ocam.set_projection_matrix(m_orthographic_height);
209 void update(std::chrono::duration<double>
const& dt) {
216template <
typename Real>
224 using parent_type::controller;
226 enum buttons : std::uint8_t { w = 1, a = 2, s = 4, d = 8, q = 16, e = 32 };
228 std::uint8_t m_buttons_down = 0;
230 bool m_right_button_down =
false;
231 bool m_shift_down =
false;
232 bool m_ctrl_down =
false;
241 if (k == gl::key::KEY_CTRL_L || k == gl::key::KEY_CTRL_R) {
244 if (k == gl::key::KEY_SHIFT_L || k == gl::key::KEY_SHIFT_R) {
247 if (k == gl::key::KEY_W) {
248 m_buttons_down = m_buttons_down | buttons::w;
250 if (k == gl::key::KEY_S) {
251 m_buttons_down = m_buttons_down |
static_cast<std::uint8_t
>(buttons::s);
253 if (k == gl::key::KEY_A) {
254 m_buttons_down = m_buttons_down |
static_cast<std::uint8_t
>(buttons::a);
256 if (k == gl::key::KEY_D) {
257 m_buttons_down = m_buttons_down |
static_cast<std::uint8_t
>(buttons::d);
259 if (k == gl::key::KEY_Q) {
260 m_buttons_down = m_buttons_down |
static_cast<std::uint8_t
>(buttons::q);
262 if (k == gl::key::KEY_E) {
263 m_buttons_down = m_buttons_down |
static_cast<std::uint8_t
>(buttons::e);
268 if (k == gl::key::KEY_CTRL_L || k == gl::key::KEY_CTRL_R) {
271 if (k == gl::key::KEY_SHIFT_L || k == gl::key::KEY_SHIFT_R) {
272 m_shift_down =
false;
274 if (k == gl::key::KEY_W) {
275 m_buttons_down =
static_cast<std::uint8_t
>(m_buttons_down &
~buttons::w);
277 if (k == gl::key::KEY_S) {
278 m_buttons_down =
static_cast<std::uint8_t
>(m_buttons_down &
~buttons::s);
280 if (k == gl::key::KEY_A) {
281 m_buttons_down =
static_cast<std::uint8_t
>(m_buttons_down &
~buttons::a);
283 if (k == gl::key::KEY_D) {
284 m_buttons_down =
static_cast<std::uint8_t
>(m_buttons_down &
~buttons::d);
286 if (k == gl::key::KEY_Q) {
287 m_buttons_down =
static_cast<std::uint8_t
>(m_buttons_down &
~buttons::q);
289 if (k == gl::key::KEY_E) {
290 m_buttons_down =
static_cast<std::uint8_t
>(m_buttons_down &
~buttons::e);
295 if (b == gl::button::right) {
296 m_right_button_down =
true;
301 if (b == gl::button::right) {
302 m_right_button_down =
false;
307 if (m_right_button_down) {
308 auto const offset_x =
static_cast<Real
>(gcem::ceil(x)) - m_mouse_pos_x;
309 auto const offset_y =
static_cast<Real
>(gcem::ceil(y)) - m_mouse_pos_y;
311 auto const old_view_dir = -controller().view_direction();
312 auto yaw = gcem::atan2(old_view_dir(2), old_view_dir(0));
313 auto pitch = gcem::asin(old_view_dir(1));
315 yaw += offset_x * Real(0.001);
316 pitch = std::clamp<Real>(pitch + offset_y * Real(0.001),
317 static_cast<Real
>(-M_PI * 0.5 * 0.7),
318 static_cast<Real
>(M_PI * 0.5 * 0.7));
319 auto const cos_pitch = gcem::cos(pitch);
320 auto const sin_pitch = gcem::sin(pitch);
321 auto const cos_yaw = gcem::cos(yaw);
322 auto const sin_yaw = gcem::sin(yaw);
323 auto const eye = controller().eye();
324 auto const new_view_dir =
325 vec{cos_pitch * cos_yaw, sin_pitch, cos_pitch * sin_yaw};
326 controller().look_at(eye, eye +
normalize(new_view_dir));
328 m_mouse_pos_x =
static_cast<Real
>(gcem::ceil(x));
329 m_mouse_pos_y =
static_cast<Real
>(gcem::ceil(y));
333 return Real(1) / 250;
336 return Real(1) / 1000;
338 return Real(1) / 500;
341 void update(std::chrono::duration<double>
const& dt)
override {
342 auto const look_dir = controller().view_direction();
343 auto const right_dir = controller().right_direction();
344 auto move_direction = vec3::zeros();
345 if (m_buttons_down & buttons::w) {
346 move_direction -= look_dir;
348 if (m_buttons_down & buttons::s) {
349 move_direction += look_dir;
351 if (m_buttons_down & buttons::a) {
352 move_direction -= right_dir;
354 if (m_buttons_down & buttons::d) {
355 move_direction += right_dir;
357 if (m_buttons_down & buttons::q) {
358 move_direction(1) += 1;
360 if (m_buttons_down & buttons::e) {
361 move_direction(1) -= 1;
363 auto const passed_time =
static_cast<Real
>(
364 std::chrono::duration_cast<std::chrono::milliseconds>(dt).count());
366 controller().eye() +
normalize(move_direction) * passed_time * speed();
367 controller().look_at(new_eye, new_eye - look_dir);
371 auto type() const -> std::type_info const&
override {
376template <
typename Real>
384 using parent_type::controller;
389 bool m_right_button_down =
false;
400 if (b == gl::button::right) {
401 m_right_button_down =
true;
406 if (b == gl::button::right) {
407 m_right_button_down =
false;
412 if (m_right_button_down) {
413 auto offset_x =
static_cast<Real
>(gcem::ceil(x)) - m_mouse_pos_x;
414 auto offset_y =
static_cast<Real
>(gcem::ceil(y)) - m_mouse_pos_y;
415 auto new_eye = controller().eye();
417 static_cast<Real
>(offset_x) *
418 controller().orthographic_camera().aspect_ratio() /
419 static_cast<Real
>(controller().orthographic_camera().plane_width()) *
420 controller().orthographic_camera().height();
422 static_cast<Real
>(offset_y) /
423 static_cast<Real
>(controller().orthographic_camera().plane_height()) *
424 controller().orthographic_camera().height();
425 this->look_at(new_eye, new_eye +
vec{0, 0, -1});
427 m_mouse_pos_x =
static_cast<Real
>(gcem::ceil(x));
428 m_mouse_pos_y =
static_cast<Real
>(gcem::ceil(y));
432 controller().set_orthographic_height(controller().orthographic_height() /
433 static_cast<Real
>(0.9));
444 controller().set_orthographic_height(controller().orthographic_height() *
445 static_cast<Real
>(0.9));
455 auto type() const -> std::type_info const&
override {
Definition: concepts.h:33
button
Definition: mouse.h:8
key
Definition: keyboard.h:9
constexpr auto normalize(base_tensor< Tensor, T, N > const &t_in) -> vec< T, N >
Definition: tensor_operations.h:100
Definition: window_listener.h:10
Definition: camera_controller.h:22
auto perspective_camera() const -> auto const &
Definition: camera_controller.h:38
auto perspective_camera() -> auto &
Definition: camera_controller.h:35
camera_controller< Real > * m_controller
Definition: camera_controller.h:28
virtual void update(std::chrono::duration< double > const &)
Definition: camera_controller.h:60
auto controller() const -> auto const &
Definition: camera_controller.h:54
auto controller() -> auto &
Definition: camera_controller.h:51
virtual auto type() const -> std::type_info const &=0
void look_at(vec3 const &eye, vec3 const &lookat, vec3 const &up={0, 1, 0})
Definition: camera_controller.h:47
auto orthographic_camera() const -> auto const &
Definition: camera_controller.h:44
virtual ~camera_controller_interface()=default
camera_controller_interface(camera_controller< Real > *controller)
Definition: camera_controller.h:31
auto orthographic_camera() -> auto &
Definition: camera_controller.h:41
Definition: camera_controller.h:64
camera_interface< Real > * m_active_cam
Definition: camera_controller.h:73
auto transform_matrix() const -> mat4
Definition: camera_controller.h:131
auto projection_matrix() const
Definition: camera_controller.h:130
void on_wheel_right() override
Definition: camera_controller.h:195
auto plane_height()
Definition: camera_controller.h:150
camera_controller(size_t const res_x, size_t const res_y)
Definition: camera_controller.h:76
void on_button_released(gl::button b) override
Definition: camera_controller.h:170
auto orthographic_height()
Definition: camera_controller.h:99
auto unproject(Vec2< Real > const &x)
Definition: camera_controller.h:101
auto look_at(vec3 const &eye, arithmetic auto const pitch, arithmetic auto const yaw)
Definition: camera_controller.h:144
void on_resize(int w, int h) override
Definition: camera_controller.h:200
auto perspective_camera() const -> auto const &
Definition: camera_controller.h:122
auto right_direction() const
Definition: camera_controller.h:136
auto controller() const -> auto const &
Definition: camera_controller.h:129
Real m_orthographic_height
Definition: camera_controller.h:70
void use_orthographic_controller()
Definition: camera_controller.h:116
auto perspective_camera() -> auto &
Definition: camera_controller.h:119
auto set_orthographic_height(Real const h)
Definition: camera_controller.h:95
auto plane_width()
Definition: camera_controller.h:149
void use_fps_controller()
Definition: camera_controller.h:113
auto ray(int x, int y) const
Definition: camera_controller.h:153
auto up_direction() const
Definition: camera_controller.h:137
auto look_at(vec3 const &eye, vec3 const &lookat, vec3 const &up={0, 1, 0})
Definition: camera_controller.h:139
auto view_direction() const
Definition: camera_controller.h:138
void on_cursor_moved(double x, double y) override
Definition: camera_controller.h:175
struct perspective_camera< Real > m_pcam
Definition: camera_controller.h:71
void on_wheel_up() override
Definition: camera_controller.h:180
void update(std::chrono::duration< double > const &dt)
Definition: camera_controller.h:209
void use_orthographic_camera()
Definition: camera_controller.h:110
void on_key_pressed(gl::key k) override
Definition: camera_controller.h:155
auto orthographic_camera() const -> auto const &
Definition: camera_controller.h:128
void on_wheel_down() override
Definition: camera_controller.h:185
auto eye() const
Definition: camera_controller.h:135
struct orthographic_camera< Real > m_ocam
Definition: camera_controller.h:72
void on_button_pressed(gl::button b) override
Definition: camera_controller.h:165
auto view_matrix() const
Definition: camera_controller.h:134
auto unproject(Vec4< Real > const &x)
Definition: camera_controller.h:104
auto active_camera() const -> auto const &
Definition: camera_controller.h:100
std::unique_ptr< camera_controller_interface< Real > > m_controller
Definition: camera_controller.h:74
void on_wheel_left() override
Definition: camera_controller.h:190
void use_perspective_camera()
Definition: camera_controller.h:107
void on_key_released(gl::key k) override
Definition: camera_controller.h:160
auto orthographic_camera() -> auto &
Definition: camera_controller.h:125
Interface for camera implementations.
Definition: camera.h:19
Definition: camera_controller.h:217
Real m_mouse_pos_x
Definition: camera_controller.h:229
fps_camera_controller(camera_controller< Real > *controller)
Definition: camera_controller.h:234
void on_button_released(gl::button b) override
Definition: camera_controller.h:300
auto speed() const
Definition: camera_controller.h:331
void update(std::chrono::duration< double > const &dt) override
Definition: camera_controller.h:341
auto type() const -> std::type_info const &override
Definition: camera_controller.h:371
void on_button_pressed(gl::button b) override
Definition: camera_controller.h:294
auto on_key_pressed(gl::key k) -> void override
Definition: camera_controller.h:240
void on_cursor_moved(double x, double y) override
Definition: camera_controller.h:306
buttons
Definition: camera_controller.h:226
void on_key_released(gl::key k) override
Definition: camera_controller.h:267
virtual ~fps_camera_controller()=default
Definition: camera_controller.h:377
auto on_wheel_up() -> void override
Definition: camera_controller.h:443
void on_button_pressed(gl::button b) override
Definition: camera_controller.h:399
auto on_wheel_down() -> void override
Definition: camera_controller.h:431
auto type() const -> std::type_info const &override
Definition: camera_controller.h:455
orthographic_camera_controller(camera_controller< Real > *controller)
Definition: camera_controller.h:393
Real m_mouse_pos_x
Definition: camera_controller.h:388
virtual ~orthographic_camera_controller()=default
auto on_cursor_moved(double x, double y) -> void override
Definition: camera_controller.h:411
void on_button_released(gl::button b) override
Definition: camera_controller.h:405
Definition: orthographic_camera.h:14
Perspective cameras are able to cast rays from one point called 'eye' through an image plane.
Definition: perspective_camera.h:15