-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCamera.cpp
More file actions
86 lines (65 loc) · 2.16 KB
/
Camera.cpp
File metadata and controls
86 lines (65 loc) · 2.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include "Camera.h"
#include <cmath>
#include "UI.h"
namespace xyz {
namespace {
const Vec4F randomV(0.0f, 1.0f, 0.0f, 0.0f);
const Vec4F randomV2(0.0f, 0.0f, 1.0f, 0.0f);
const Vec4F A(0.0f, 0.0f, 0.0f, 1.0F);
} // namespace
Camera::Camera()
: Camera(Vec4F(0.0f, 0.0f, 1.0f, 1.0f), Vec4F(0.0f, 0.0f, 0.0f, 1.0f)) {
compute_projection();
}
Camera::Camera(Vec4F from, Vec4F to) : from_(from), to_(to) {
look_at(from, to);
compute_projection();
}
void Camera::look_at(Vec4F from, Vec4F to) {
from_ = from;
to_ = to;
forward_ = normalise(to_ - from_);
if (forward_ == randomV) {
right_ = normalise(cross(forward_, randomV2));
} else {
right_ = normalise(cross(forward_, randomV));
}
up_ = normalise(cross(right_, forward_));
cam_to_world_ = Mat44F(right_, up_, forward_, from_);
cam_to_world_.transpose();
alignas(16) float right_values[4];
right_.store(right_values);
right_values[3] = -dot(right_, from_);
alignas(16) float up_values[4];
up_.store(up_values);
up_values[3] = -dot(up_, from_);
auto forward = forward_;
forward.negate();
alignas(16) float forward_values[4];
forward.store(forward_values);
forward_values[3] = -dot(forward, from_);
world_to_cam_ =
Mat44F(Vec4F(right_values), Vec4F(up_values), Vec4F(forward_values), A);
}
void Camera::compute_projection() {
const auto ratio = static_cast<double>(UI::width) / UI::height;
const auto scale = tan(fov_ * 0.5 * M_PI / 180);
const auto r = ratio * scale;
const auto l = -r;
const auto t = scale;
const auto b = -t;
#if 1
Vec4F row_0(2.0f * near_ * (r - l), 0.0f, (r + l) / (r - l), 0.0f);
Vec4F row_1(0.0f, 2.0f * near_ / (t - b), (t + b) / (t - b), 0.0f);
Vec4F row_2(0.0f, 0.0f, -(far_ + near_) / (far_ - near_),
-2.0f * far_ * near_ / (far_ - near_));
Vec4F row_3(0.0f, 0.0f, -1.0f, 0.0f);
#else
Vec4F row_0(2.0f * (r - l), 0.0f, 0.0f, -(r + l)/(r - l));
Vec4F row_1(0.0f, 2.0f / (t - b), 0.0f, -(t + b) / (t - b));
Vec4F row_2(0.0f, 0.0f, -(2.0f) / (far_ - near_), -(far_ + near_) / (far_ - near_));
Vec4F row_3(0.0f, 0.0f, 0.0f, 1.0f);
#endif
m_projection_ = Mat44F(row_0, row_1, row_2, row_3);
}
} // namespace xyz