Brenta Engine 1.2
Loading...
Searching...
No Matches
camera.hpp
1// SPDX-License-Identifier: MIT
2// Author: Giovanni Santini
3// Mail: giovanni.santini@proton.me
4// Github: @San7o
5
6#pragma once
7
8#include <brenta/transform.hpp>
9
10#include <glm/glm.hpp>
11#include <glm/gtc/matrix_transform.hpp>
12
13#include <variant>
14
15namespace brenta
16{
17
18//
19// The Camera class
20// ----------------
21//
22// This class represents a camera in the 3D world. It is used to
23// define the position, orientation and projection of the camera. The
24// class provides a builder pattern to create a camera object.
25//
26// The camera can be of two types: aircraft or spherical. The aircraft
27// type is used to represent a camera that moves in the world space
28// directions (x, y, z), while the spherical type is used to represent
29// a camera that rotates around a center point (you essentially
30// control the angle and radius around the center). They use
31// respectively euler angles and spherical coordinates to represent
32// the position of the camera.
33//
34// The camera can have two types of projection: perspective or
35// orthographic.
36//
37class Camera
38{
39public:
40
41 class Spherical;
42 class Aircraft;
43 class Position;
44 enum class ProjectionType;
45 enum class Movement;
46
47 class Config;
48 class Builder;
49
50 // Constructors
51
52 Camera() = default;
53 Camera(Config conf);
54 Camera(Builder& builder);
55
56 // Getters
57
58 std::variant<Spherical, Aircraft> get_pos() const;
59 Transform get_transform();
60 float get_fov() const;
61 glm::mat4 get_view_matrix() const;
62 ProjectionType get_projection_type() const;
63 glm::mat4 get_projection_matrix(int window_width,
64 int window_height) const;
65 glm::vec3 get_world_up() const;
66 glm::vec3 get_front() const;
67 glm::vec3 get_up() const;
68 glm::vec3 get_right() const;
69
70 // Setters
71
72 void set_pos(std::variant<Spherical, Aircraft> pos);
73 void set_projection_type(ProjectionType proj_type);
74 void set_fov(float fov);
75 void set_world_up(glm::vec3 world_up);
76 void set_front(glm::vec3 front);
77 void set_up(glm::vec3 up);
78 void set_right(glm::vec3 right);
79
81 {
82 public:
83
84 class Builder;
85
86 glm::vec3 center;
87 float theta;
88 float phi;
89 float radius;
90
91 Spherical() = default;
92 Spherical(glm::vec3 center, float theta,
93 float phi, float radius)
94 : center(center), theta(theta), phi(phi), radius(radius) {}
95 };
96
98 {
99 public:
100
101 class Builder;
102
103 glm::vec3 pos;
104 float yaw = 0;
105 float pitch = 0;
106 float roll = 0;
107
108 Aircraft() = default;
109 Aircraft(glm::vec3 pos)
110 : pos(pos) {}
111 Aircraft(glm::vec3 pos, float yaw, float pitch, float roll)
112 : pos(pos), yaw(yaw), pitch(pitch), roll(roll) {}
113 Aircraft(const Builder &builder);
114
115 };
116
117private:
118
119 std::variant<Spherical, Aircraft> pos;
120 ProjectionType proj_type;
121 float fov; // field of view / zoom
122
123 glm::vec3 front;
124 glm::vec3 up;
125 glm::vec3 right;
126 glm::vec3 world_up;
127
128 // Remember to always use set_pos when changing the position,
129 // never modify this value manually
130 Transform transform;
131
132 void update_spherical(Spherical pos);
133 void update_aircraft(Aircraft pos);
134};
135
136enum class Camera::ProjectionType
137{
138 Perspective,
139 Orthographic
140};
141
142enum class Camera::Movement
143{
144 Forward,
145 Backward,
146 Left,
147 Right
148};
149
151{
152public:
153
154 Builder() = default;
155
156 Builder &center(glm::vec3 center);
157 Builder &theta(float theta);
158 Builder &phi(float phi);
159 Builder &radius(float radius);
160
161 Camera::Spherical build();
162
163private:
164
166
167};
168
170{
171public:
172
173 Builder() = default;
174
175 Camera::Aircraft::Builder& pos(glm::vec3 pos);
176 Camera::Aircraft::Builder& yaw(float yaw);
177 Camera::Aircraft::Builder& pitch(float pitch);
178 Camera::Aircraft::Builder& roll(float roll);
179
180 Camera::Aircraft build();
181
182private:
183
184 Camera::Aircraft acam;
185
186};
187
189{
190 std::variant<Spherical, Aircraft> pos = Camera::Aircraft(glm::vec3(0.0));
191 ProjectionType proj_type = Camera::ProjectionType::Perspective;
192 float fov = 45.0f;
193 glm::vec3 world_up = glm::vec3(0.0f, 1.0f, 0.0f);
194 glm::vec3 front = glm::vec3(0.0f, 0.0f, -1.0f);
195 glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f);
196 glm::vec3 right = glm::vec3(1.0f, 0.0f, 0.0f);
197};
198
200{
201private:
202
203 Camera::Config conf = {};
204
205public:
206
207 Builder &projection_type(ProjectionType proj_type);
208 Builder &position(std::variant<Spherical, Aircraft> pos);
209 Builder &fov(float fov);
210 Builder &world_up(glm::vec3 worldUp);
211 Builder &front(glm::vec3 front);
212 Builder &up(glm::vec3 up);
213 Builder &right(glm::vec3 right);
214
215 Camera build();
216};
217
218} // namespace brenta