camera.cpp 2.43 KB
Newer Older
TheNumbat's avatar
TheNumbat committed
1
2
3

#include "camera.h"

TheNumbat's avatar
TheNumbat committed
4
5
const Vec3 UP = Vec3{0.0f, 1.0f, 0.0f};

TheNumbat's avatar
TheNumbat committed
6
7
8
9
10
Camera::Camera(Vec2 dim) {
    reset();
    set_ar(dim);
}

TheNumbat's avatar
TheNumbat committed
11
Mat4 Camera::get_view() const { return view; }
TheNumbat's avatar
TheNumbat committed
12

TheNumbat's avatar
TheNumbat committed
13
Mat4 Camera::get_proj() const { return Mat4::project(vert_fov, aspect_ratio, near_plane); }
TheNumbat's avatar
TheNumbat committed
14

TheNumbat's avatar
TheNumbat committed
15
Vec3 Camera::pos() const { return position; }
TheNumbat's avatar
TheNumbat committed
16

TheNumbat's avatar
TheNumbat committed
17
Vec3 Camera::front() const { return (looking_at - position).unit(); }
TheNumbat's avatar
TheNumbat committed
18

TheNumbat's avatar
TheNumbat committed
19
float Camera::dist() const { return (position - looking_at).norm(); }
TheNumbat's avatar
TheNumbat committed
20
21
22
23
24

void Camera::look_at(Vec3 cent, Vec3 pos) {
    position = pos;
    looking_at = cent;
    radius = (pos - cent).norm();
TheNumbat's avatar
TheNumbat committed
25
26
27
28
    if(dot(front(), UP) == -1.0f)
        rot = Quat::euler(Vec3{270.0f, 0.0f, 0.0f});
    else
        rot = Quat::euler(Mat4::rotate_z_to(front()).to_euler());
TheNumbat's avatar
TheNumbat committed
29
    update_pos();
TheNumbat's avatar
TheNumbat committed
30
31
32
33
34
}

void Camera::reset() {
    vert_fov = 90.0f;
    aspect_ratio = 1.7778f;
TheNumbat's avatar
TheNumbat committed
35
    rot = Quat::euler(Vec3(-45.0f, 45.0f, 0.0f));
TheNumbat's avatar
TheNumbat committed
36
37
38
39
40
41
42
43
44
45
    near_plane = 0.01f;
    radius = 5.0f;
    radius_sens = 0.25f;
    move_sens = 0.015f;
    orbit_sens = 0.2f;
    looking_at = Vec3();
    update_pos();
}

void Camera::mouse_orbit(Vec2 off) {
TheNumbat's avatar
TheNumbat committed
46
47
48
49
50
51
52
53
    float up_rot = -off.x * orbit_sens;
    float right_rot = off.y * orbit_sens;

    Vec3 up = rot.rotate(UP);
    Vec3 f = front();
    Vec3 right = cross(f, up).unit();

    rot = Quat::axis_angle(UP, up_rot) * Quat::axis_angle(right, right_rot) * rot;
TheNumbat's avatar
TheNumbat committed
54
55
56
57
    update_pos();
}

void Camera::mouse_move(Vec2 off) {
TheNumbat's avatar
TheNumbat committed
58
59
60
61
62
    Vec3 up = rot.rotate(UP);
    Vec3 f = front();
    Vec3 right = cross(f, up).unit();

    looking_at += -right * off.x * move_sens + up * off.y * move_sens;
TheNumbat's avatar
TheNumbat committed
63
64
65
66
67
68
69
70
71
    update_pos();
}

void Camera::mouse_radius(float off) {
    radius -= off * radius_sens;
    radius = std::max(radius, 2.0f * near_plane);
    update_pos();
}

TheNumbat's avatar
TheNumbat committed
72
void Camera::set_fov(float f) { vert_fov = f; }
TheNumbat's avatar
TheNumbat committed
73
74
75
76
77
78
79

float Camera::get_h_fov() const {
    float vfov = Radians(vert_fov);
    float hfov = 2.0f * std::atan(aspect_ratio * std::tan(vfov / 2.0f));
    return Degrees(hfov);
}

TheNumbat's avatar
TheNumbat committed
80
float Camera::get_fov() const { return vert_fov; }
TheNumbat's avatar
TheNumbat committed
81

TheNumbat's avatar
TheNumbat committed
82
float Camera::get_ar() const { return aspect_ratio; }
TheNumbat's avatar
TheNumbat committed
83

TheNumbat's avatar
TheNumbat committed
84
float Camera::get_near() const { return near_plane; }
TheNumbat's avatar
TheNumbat committed
85

TheNumbat's avatar
TheNumbat committed
86
Vec3 Camera::center() const { return looking_at; }
TheNumbat's avatar
TheNumbat committed
87

TheNumbat's avatar
TheNumbat committed
88
void Camera::set_ar(float a) { aspect_ratio = a; }
TheNumbat's avatar
TheNumbat committed
89

TheNumbat's avatar
TheNumbat committed
90
void Camera::set_ar(Vec2 dim) { aspect_ratio = dim.x / dim.y; }
TheNumbat's avatar
TheNumbat committed
91
92

void Camera::update_pos() {
TheNumbat's avatar
TheNumbat committed
93
94
95
96
    position = rot.rotate(Vec3{0.0f, 0.0f, 1.0f});
    position = looking_at + radius * position.unit();
    iview = Mat4::translate(position) * rot.to_mat();
    view = iview.inverse();
TheNumbat's avatar
TheNumbat committed
97
}