-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathCamera.hpp
109 lines (85 loc) · 1.98 KB
/
Camera.hpp
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
#ifndef CAMERA_HPP
#define CAMERA_HPP
#include <glm/vec3.hpp>
#include <glm/vec4.hpp>
#include <glm/mat4x4.hpp>
#include <glm/ext/matrix_transform.hpp> // glm::translate, glm::rotate, glm::scale
#include <glm/ext/matrix_clip_space.hpp> // glm::perspective
#include <glm/ext/scalar_constants.hpp> // glm::pi
class Camera {
private:
glm::highp_vec3 position;
glm::highp_vec3 target;
glm::highp_vec3 up;
glm::mat4 projection;
glm::mat4 view;
glm::mat4 viewprojection;
float fov;
float aspectRatio;
float nearClip;
float farClip;
float viewLengthInverse;
bool vpIsDirty;
public:
Camera() {}
Camera(float _fov, float _aspectRatio, float _nearClip, float _farClip) {
position = glm::highp_vec3(2.0f, 2.0f, 0.0f);
target = glm::highp_vec3(0.0f, 0.0f, 0.0f);
up = glm::highp_vec3(0.0f, 1.0f, 0.0f);
fov = _fov;
aspectRatio = _aspectRatio;
nearClip = _nearClip;
farClip = _farClip;
projection = glm::mat4(1.0f);
view = glm::mat4(1.0f);
vpIsDirty = true;
}
void moveTo(float x, float y, float z) {
position = glm::highp_vec3(x, y, z);
vpIsDirty = true;
}
void lookAt(float x, float y, float z) {
target = glm::highp_vec3(x, y, z);
vpIsDirty = true;
}
/*
Angle is in degrees
*/
void rotateAroundTarget(float angle) {
glm::fquat q = glm::angleAxis(glm::radians(angle), glm::normalize(up));
position = target + q * position;
vpIsDirty = true;
}
glm::vec3 dir() {
return (position - target);
}
glm::mat4 v() {
if (vpIsDirty) {
clean();
}
return view;
}
void clean() {
projection = glm::perspective(glm::radians(fov), aspectRatio, nearClip, farClip);
view = glm::lookAtLH(position, target, up);
viewprojection = projection * view;
vpIsDirty = false;
viewLengthInverse = 1.0f / (far() - near());
}
glm::mat4 vp() {
if (vpIsDirty) {
clean();
}
return viewprojection;
}
float cameraLengthInverse() {
return viewLengthInverse;
}
float far() {
return farClip;
}
float near() {
return nearClip;
}
};
#endif