Tatooine
camera.h
Go to the documentation of this file.
1#ifndef TATOOINE_RENDERING_CAMERA_H
2#define TATOOINE_RENDERING_CAMERA_H
3//==============================================================================
4#include <tatooine/concepts.h>
6#include <tatooine/ray.h>
8#include <tatooine/vec.h>
9
10#include <array>
11//==============================================================================
13//==============================================================================
18template <floating_point Real>
20 //----------------------------------------------------------------------------
21 // typedefs
22 //----------------------------------------------------------------------------
23 using real_type = Real;
30
31 //----------------------------------------------------------------------------
32 // member variables
33 //----------------------------------------------------------------------------
34 private:
38
41
42 //----------------------------------------------------------------------------
43 // constructors / destructor
44 //----------------------------------------------------------------------------
45 public:
46 constexpr camera_interface(vec3 const& eye, vec3 const& lookat,
47 vec3 const& up, Vec4<std::size_t> const& viewport)
51 //----------------------------------------------------------------------------
52 constexpr camera_interface(vec3 const& eye, vec3 const& lookat, vec3 const& up,
53 Vec4<std::size_t> const& viewport, mat4 const& p)
57 //----------------------------------------------------------------------------
58 virtual ~camera_interface() = default;
59 //----------------------------------------------------------------------------
60 // object methods
61 //----------------------------------------------------------------------------
63 auto constexpr viewport() const -> auto const& { return m_viewport; }
64 auto constexpr viewport(std::size_t const i) const -> auto const& {
65 return m_viewport(i);
66 }
67 //----------------------------------------------------------------------------
69 auto constexpr plane_width() const { return m_viewport(2); }
70 //----------------------------------------------------------------------------
72 auto constexpr plane_height() const { return m_viewport(3); }
73 //----------------------------------------------------------------------------
74 auto constexpr aspect_ratio() const {
75 return static_cast<Real>(m_viewport(2)) / static_cast<Real>(m_viewport(3));
76 }
77 //----------------------------------------------------------------------------
78 auto constexpr eye() const -> auto {
79 return vec3{m_transform_matrix(0, 3),
81 m_transform_matrix(2, 3)};
82 }
83 //----------------------------------------------------------------------------
84 auto constexpr right_direction() const {
85 return vec3{m_transform_matrix(0, 0),
87 m_transform_matrix(2, 0)};
88 }
89 //----------------------------------------------------------------------------
90 auto constexpr up_direction() const {
91 return vec3{m_transform_matrix(0, 1),
93 m_transform_matrix(2, 1)};
94 }
95 //----------------------------------------------------------------------------
96 auto constexpr view_direction() const {
97 return vec3{m_transform_matrix(0, 2),
99 m_transform_matrix(2, 2)};
100 }
101 //----------------------------------------------------------------------------
102 auto constexpr set_viewport_without_update(std::size_t const bottom,
103 std::size_t const left,
104 std::size_t const width,
105 std::size_t const height) {
106 m_viewport(0) = bottom;
107 m_viewport(1) = left;
108 m_viewport(2) = width;
109 m_viewport(3) = height;
110 }
111 //----------------------------------------------------------------------------
112 auto constexpr set_viewport(std::size_t const bottom, std::size_t const left,
113 std::size_t const width,
114 std::size_t const height) {
115 m_viewport(0) = bottom;
116 m_viewport(1) = left;
117 m_viewport(2) = width;
118 m_viewport(3) = height;
119 //setup();
120 }
121 //----------------------------------------------------------------------------
122 auto constexpr set_resolution_without_update(std::size_t const width,
123 std::size_t const height) {
124 m_viewport(2) = width;
125 m_viewport(3) = height;
126 }
127 //----------------------------------------------------------------------------
128 auto constexpr set_resolution(std::size_t const width,
129 std::size_t const height) {
130 m_viewport(2) = width;
131 m_viewport(3) = height;
132 //setup();
133 }
134 //----------------------------------------------------------------------------
135 auto set_gl_viewport() const {
136 gl::viewport(static_cast<GLint>(m_viewport[0]),
137 static_cast<GLint>(m_viewport[1]),
138 static_cast<GLsizei>(m_viewport[2]),
139 static_cast<GLsizei>(m_viewport[3]));
140 }
141 //----------------------------------------------------------------------------
142 auto constexpr look_at(vec3 const& eye, vec3 const& lookat,
143 vec3 const& up = {0, 1, 0}) -> void {
145 //setup();
146 }
147 //----------------------------------------------------------------------------
148 auto constexpr look_at(vec3 const& eye, arithmetic auto const pitch,
149 arithmetic auto const yaw) -> void {
151 //setup();
152 }
153 //----------------------------------------------------------------------------
154 auto constexpr transform_matrix() const -> auto const& {
155 return m_transform_matrix;
156 }
157 //----------------------------------------------------------------------------
158 auto constexpr view_matrix() const {
159 auto const& T = transform_matrix();
160 auto const eye_o_x =
161 T(0, 3) * T(0, 0) + T(1, 3) * T(1, 0) + T(2, 3) * T(2, 0);
162 auto const eye_o_y =
163 T(0, 3) * T(0, 1) + T(1, 3) * T(1, 1) + T(2, 3) * T(2, 1);
164 auto const eye_o_z =
165 T(0, 3) * T(0, 2) + T(1, 3) * T(1, 2) + T(2, 3) * T(2, 2);
166 return mat4{{T(0, 0), T(1, 0), T(2, 0), -eye_o_x},
167 {T(0, 1), T(1, 1), T(2, 1), -eye_o_y},
168 {T(0, 2), T(1, 2), T(2, 2), -eye_o_z},
169 {real_type(0), real_type(0), real_type(0), real_type(1)}};
170 }
171 //----------------------------------------------------------------------------
172 auto constexpr projection_matrix() const -> auto const& {
173 return m_projection_matrix;
174 }
175 //----------------------------------------------------------------------------
177 return projection_matrix() * view_matrix();
178 }
179 //----------------------------------------------------------------------------
181 auto unproject(vec2 const& p) const {
182 return unproject(vec4{p.x(), p.y(), 0.5, 1});
183 }
184 //----------------------------------------------------------------------------
186 auto unproject(vec3 const& p) const {
187 return unproject(vec4{p.x(), p.y(), p.z(), 1});
188 }
189 //----------------------------------------------------------------------------
191 auto unproject(vec4 p) const {
192 // [0,w-1] x [0,h-1] -> [-1,1] x [-1,1]
193 p(0) = (p(0) - static_cast<Real>(m_viewport(0))) /
194 static_cast<Real>(m_viewport(2) - 1) * 2 -
195 1;
196 p(1) = (p(1) - static_cast<Real>(m_viewport(1))) /
197 static_cast<Real>(m_viewport(3) - 1) * 2 -
198 1;
199 p(2) = p(2) * 2 - 1;
200 p(3) = 1;
201
202 // canonical view volume to world coordinate
203 p = *inv(view_projection_matrix()) * p;
204 p(3) = 1 / p(3);
205 p(0) = p(0) * p(3);
206 p(1) = p(1) * p(3);
207 p(2) = p(2) * p(3);
208 p(3) = 1;
209 return p;
210 }
211 //----------------------------------------------------------------------------
213 auto project(vec2 const& p) const {
214 return project(vec4{p(0), p(1), 0, 1});
215 }
216 //----------------------------------------------------------------------------
218 auto project(vec3 const& p) const {
219 return project(vec4{p(0), p(1), p(2), 1});
220 }
221 //----------------------------------------------------------------------------
223 auto project(vec4 p) const {
224 p = view_projection_matrix() * p;
225 p(0) /= p(3);
226
227 // [-1,1] -> [0,1]
228 p(0) = p(0) * Real(0.5) + Real(0.5);
229 p(1) = p(1) * Real(0.5) + Real(0.5);
230 p(2) = p(2) * Real(0.5) + Real(0.5);
231
232 // [0,1] to viewport
233 p(0) = p(0) * static_cast<Real>(plane_width() - 1) + static_cast<Real>(m_viewport(0));
234 p(1) = p(1) * static_cast<Real>(plane_height() - 1) + static_cast<Real>(m_viewport(1));
235
236 return p;
237 }
238 //------------------------------------------------------------------------------
243 auto ray(Real const x, Real const y) const -> ray_type {
244 auto const A = *inv(view_projection_matrix());
245
246 auto const bottom_left_near_homogeneous = A * Vec4<Real>{-1, -1, -1, 1};
247 auto const bottom_right_homogeneous = A * Vec4<Real>{1, -1, -1, 1};
248 auto const top_left_homogeneous = A * Vec4<Real>{-1, 1, -1, 1};
249
250 auto const bottom_left =
251 bottom_left_near_homogeneous.xyz() / bottom_left_near_homogeneous.w();
252 auto const bottom_right =
253 bottom_right_homogeneous.xyz() / bottom_right_homogeneous.w();
254 auto const top_left =
255 top_left_homogeneous.xyz() / top_left_homogeneous.w();
256
257 auto const plane_base_x =
258 (bottom_right - bottom_left) / real_type(this->plane_width() - 1);
259 auto const plane_base_y =
260 (top_left - bottom_left) / real_type(this->plane_height() - 1);
261
262 auto const view_plane_point =
263 bottom_left + x * plane_base_x + y * plane_base_y;
264 return {{eye()}, {view_plane_point - eye()}};
265 }
267 //auto setup() -> void {
268 // auto const A = *inv(view_projection_matrix());
269 //
270 // auto const bottom_left_homogeneous = (A * Vec4<Real>{-1, -1, -1, 1});
271 // m_bottom_left = bottom_left_homogeneous.xyz() / bottom_left_homogeneous.w();
272 // auto const bottom_right = A * Vec4<Real>{1, -1, -1, 1};
273 // auto const top_left = A * Vec4<Real>{-1, 1, -1, 1};
274 // m_plane_base_x = (bottom_right.xyz() / bottom_right.w() - m_bottom_left) /
275 // (this->plane_width() - 1);
276 // m_plane_base_y = (top_left.xyz() / top_left.w() - m_bottom_left) /
277 // (this->plane_height() - 1);
278 //}
279 protected:
282 }
283};
284//==============================================================================
285namespace detail::camera {
286//==============================================================================
287template <std::floating_point Real>
289 -> std::true_type;
290template <typename>
291auto ptr_convertible_to_camera(const volatile void*) -> std::false_type;
292
293template <typename>
294auto is_derived_from_camera(...) -> std::true_type;
295template <typename D>
297 -> decltype(ptr_convertible_to_camera(static_cast<D*>(nullptr)));
298//==============================================================================
299} // namespace detail::camera
300//==============================================================================
301template <typename T>
303 : std::integral_constant<
304 bool,
305 std::is_class_v<T>&& decltype(detail::camera::is_derived_from_camera<
306 T>(0))::value> {};
307//------------------------------------------------------------------------------
308template <typename T>
309static auto constexpr is_camera = is_camera_impl<T>::value;
310//==============================================================================
311template <typename T>
312concept camera = is_camera<T>;
313//==============================================================================
314} // namespace tatooine::rendering
315//==============================================================================
316#endif
Definition: concepts.h:33
Definition: camera.h:312
DLL_API auto viewport(GLint x, GLint y, GLsizei width, GLsizei height) -> void
auto is_derived_from_camera(...) -> std::true_type
auto ptr_convertible_to_camera(const volatile camera_interface< Real > *) -> std::true_type
Definition: camera.h:12
auto constexpr fps_look_at_matrix(Vec3< Real > const &eye, arithmetic auto const pitch, arithmetic auto const yaw) -> Mat4< Real >
Can be used as transform matrix of an object.
Definition: matrices.h:274
static auto constexpr is_camera
Definition: camera.h:309
auto constexpr look_at_matrix(Vec3< Real > const &eye, Vec3< Real > const &center, Vec3< Real > const &up={0, 1, 0}) -> Mat4< Real >
Definition: matrices.h:155
constexpr auto inv(diag_static_tensor< Tensor, N, N > const &A) -> std::optional< diag_static_tensor< vec< tatooine::value_type< Tensor >, N >, N, N > >
Definition: diag_tensor.h:109
Definition: mat.h:14
Definition: ray.h:10
Interface for camera implementations.
Definition: camera.h:19
auto constexpr eye() const -> auto
Definition: camera.h:78
mat4 m_projection_matrix
Definition: camera.h:40
auto constexpr aspect_ratio() const
Definition: camera.h:74
auto constexpr up_direction() const
Definition: camera.h:90
auto project(vec2 const &p) const
Projects a world coordinate to screen coordinates.
Definition: camera.h:213
vec3 m_plane_base_x
Definition: camera.h:37
vec3 m_plane_base_y
Definition: camera.h:37
auto constexpr viewport() const -> auto const &
Returns number of pixels of plane in x-direction.
Definition: camera.h:63
auto set_projection_matrix(mat4 const &projection_matrix) -> void
Definition: camera.h:280
auto constexpr projection_matrix() const -> auto const &
Definition: camera.h:172
auto view_projection_matrix() const
Definition: camera.h:176
auto constexpr plane_height() const
Returns number of pixels of plane in y-direction.
Definition: camera.h:72
constexpr camera_interface(vec3 const &eye, vec3 const &lookat, vec3 const &up, Vec4< std::size_t > const &viewport)
Definition: camera.h:46
auto constexpr view_matrix() const
Definition: camera.h:158
vec3 m_bottom_left
Definition: camera.h:36
auto unproject(vec2 const &p) const
Projects a screen coordinates to world coordinates.
Definition: camera.h:181
auto constexpr viewport(std::size_t const i) const -> auto const &
Definition: camera.h:64
auto constexpr right_direction() const
Definition: camera.h:84
auto set_gl_viewport() const
Definition: camera.h:135
constexpr camera_interface(vec3 const &eye, vec3 const &lookat, vec3 const &up, Vec4< std::size_t > const &viewport, mat4 const &p)
Definition: camera.h:52
auto constexpr view_direction() const
Definition: camera.h:96
auto constexpr set_viewport(std::size_t const bottom, std::size_t const left, std::size_t const width, std::size_t const height)
Definition: camera.h:112
auto constexpr transform_matrix() const -> auto const &
Definition: camera.h:154
Real real_type
Definition: camera.h:23
auto ray(Real const x, Real const y) const -> ray_type
Gets a ray through plane at pixel with coordinate [x,y].
Definition: camera.h:243
auto constexpr look_at(vec3 const &eye, vec3 const &lookat, vec3 const &up={0, 1, 0}) -> void
Definition: camera.h:142
auto constexpr set_viewport_without_update(std::size_t const bottom, std::size_t const left, std::size_t const width, std::size_t const height)
Definition: camera.h:102
auto constexpr set_resolution(std::size_t const width, std::size_t const height)
Definition: camera.h:128
mat4 m_transform_matrix
Definition: camera.h:39
Vec4< std::size_t > m_viewport
Definition: camera.h:35
auto unproject(vec4 p) const
Projects a homogeneous screen coordinates to world coordinates.
Definition: camera.h:191
auto project(vec4 p) const
Projects a homogeneous world coordinate to screen coordinates.
Definition: camera.h:223
auto unproject(vec3 const &p) const
Projects a screen coordinates to world coordinates.
Definition: camera.h:186
auto constexpr look_at(vec3 const &eye, arithmetic auto const pitch, arithmetic auto const yaw) -> void
Definition: camera.h:148
auto constexpr plane_width() const
Returns number of pixels of plane in x-direction.
Definition: camera.h:69
auto project(vec3 const &p) const
Projects a world coordinate to screen coordinates.
Definition: camera.h:218
auto constexpr set_resolution_without_update(std::size_t const width, std::size_t const height)
Definition: camera.h:122
Definition: camera.h:306
Perspective cameras are able to cast rays from one point called 'eye' through an image plane.
Definition: perspective_camera.h:15
Definition: vec.h:12
auto constexpr xyz() const
Definition: vec.h:118