-
Notifications
You must be signed in to change notification settings - Fork 10
/
Camera.cpp
69 lines (59 loc) · 2.23 KB
/
Camera.cpp
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
#include "Camera.h"
#include <QDebug>
void Camera::RotateAroundTarget(Vector2D motion)
{
Vector3D formTarget = position-target;
float radius = glm::length(formTarget);
float yaw = (float)std::atan2(formTarget.x, formTarget.z);
float pitch = (float)std::asin(formTarget.y / radius);
float factor = (float)M_PI * 2.f;
Vector3D offset;
yaw -= motion.x * factor;
pitch += motion.y * factor;
if(pitch + M_PI_2 < FLT_EPSILON) pitch = - glm::radians(89.9f);
if(pitch - M_PI_2 > FLT_EPSILON) pitch = glm::radians(89.9f);
offset.x = (radius * (float)std::cos(pitch) * (float)std::sin(yaw));
offset.y = (radius * (float)std::sin(pitch));
offset.z = (radius * (float)std::cos(pitch) * (float)std::cos(yaw));
position = target + offset;
}
void Camera::MoveTarget(Vector2D motion)
{
Vector3D fromPosition = target-position;
Vector3D forward = glm::normalize(fromPosition);
Vector3D left = glm::normalize(glm::cross({0.0f,1.0f,0.0f},forward));
Vector3D up = glm::normalize(glm::cross(forward,left));
float distance = glm::length(fromPosition);
float factor = distance * (float)tan(glm::radians(fov) / 2) * 2;
Vector3D deltaX = factor * aspect * motion.x * left;
Vector3D deltaY = factor * motion.y * up;
target += (deltaX+deltaY);
position += (deltaX+deltaY);
}
void Camera::CloseToTarget(int ratio)
{
Vector3D formTarget = position-target;
float radius = glm::length(formTarget);
float yaw = (float)std::atan2(formTarget.x, formTarget.z);
float pitch = (float)std::asin(formTarget.y / radius);
Vector3D offset;
radius *= (float)std::pow(0.95, ratio);
offset.x = (radius * (float)std::cos(pitch) * (float)std::sin(yaw));
offset.y = (radius * (float)std::sin(pitch));
offset.z = (radius * (float)std::cos(pitch) * (float)std::cos(yaw));
position = target + offset;
}
void Camera::SetModel(Coord3D modelCentre, float yRange)
{
target = modelCentre;
position = modelCentre;
position.z += (yRange / std::tan(glm::radians(fov) / 2));
}
glm::mat4 Camera::GetViewMatrix()
{
return glm::lookAt(position,target,{0.0f,1.0f,0.0f});
}
glm::mat4 Camera::GetProjectionMatrix()
{
return glm::perspective(glm::radians(fov), aspect, zNear, zFar);
}