-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcamera.cpp
More file actions
144 lines (125 loc) · 3.31 KB
/
camera.cpp
File metadata and controls
144 lines (125 loc) · 3.31 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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include "camera.h"
#include <glm/gtc/matrix_transform.hpp>
#include <iostream>
Camera::Camera() :
Camera(400, 400)
{
look = glm::vec3(0, 0, -1);
up = glm::vec3(0, 1, 0);
right = glm::vec3(1, 0, 0);
}
Camera::Camera(unsigned int w, unsigned int h) :
Camera(w, h, glm::vec3(0, 0, 10), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0))
{}
Camera::Camera(unsigned int w, unsigned int h, const glm::vec3 &e, const glm::vec3 &r, const glm::vec3 &worldUp) :
fovy(45),
width(w),
height(h),
near_clip(0.1f),
far_clip(1000.f),
eye(e),
ref(r),
world_up(worldUp)
{
RecomputeAttributes();
}
Camera::Camera(const Camera &c) :
fovy(c.fovy),
width(c.width),
height(c.height),
near_clip(c.near_clip),
far_clip(c.far_clip),
aspect(c.aspect),
eye(c.eye),
ref(c.ref),
look(c.look),
up(c.up),
right(c.right),
world_up(c.world_up),
V(c.V),
H(c.H)
{}
void Camera::UpdateEyeAndRef(const glm::vec3& eye_in,
const glm::vec3& ref_in) {
eye = eye_in;
ref = ref_in;
RecomputeAttributes();
}
void Camera::RecomputeAttributes()
{
look = glm::normalize(ref - eye);
right = glm::normalize(glm::cross(look, world_up));
up = glm::cross(right, look);
float tan_fovy = tan(glm::radians(fovy / 2));
float len = glm::length(ref - eye);
aspect = (float)width / (float)height;
V = up * len*tan_fovy;
H = right * len*aspect*tan_fovy;
}
glm::mat4 Camera::GetViewProjMat()
{
return glm::perspective(glm::radians(fovy),
(float)width / (float)height,
near_clip, far_clip) * glm::lookAt(eye, ref, up);
}
glm::mat4 Camera::GetView()
{
glm::mat4 View = glm::lookAt(
eye,
ref,
up
);
return View;
}
glm::mat4 Camera::GetProj()
{
glm::mat4 projectionMatrix = glm::perspective(
glm::radians(fovy), // The vertical Field of View, in radians: the amount of "zoom". Think "camera lens". Usually between 90?(extra wide) and 30?(quite zoomed in)
aspect, // Aspect Ratio. Depends on the size of your window. Notice that 4/3 == 800/600 == 1280/960, sounds familiar ?
near_clip, // Near clipping plane. Keep as big as possible, or you'll get precision issues.
far_clip // Far clipping plane. Keep as little as possible.
);
return projectionMatrix;
}
glm::vec3 Camera::GetForward()
{
return look;
}
glm::vec3 Camera::GetPos()
{
return eye;
}
void Camera::RotateAboutUp(float deg)
{
glm::mat4 rotation = glm::rotate(glm::mat4(1.0f), glm::radians(deg), up);
ref = ref - eye;
ref = glm::vec3(rotation * glm::vec4(ref, 1));
ref = ref + eye;
RecomputeAttributes();
}
void Camera::RotateAboutRight(float deg)
{
glm::mat4 rotation = glm::rotate(glm::mat4(1.0f), glm::radians(deg), right);
ref = ref - eye;
ref = glm::vec3(rotation * glm::vec4(ref, 1));
ref = ref + eye;
RecomputeAttributes();
}
void Camera::TranslateAlongLook(float amt)
{
glm::vec3 translation = look * amt;
eye += translation;
ref += translation;
}
void Camera::TranslateAlongRight(float amt)
{
glm::vec3 translation = right * amt;
eye += translation;
ref += translation;
}
void Camera::TranslateAlongUp(float amt)
{
glm::vec3 translation = world_up * amt;
eye += translation;
ref += translation;
}