Unravel Engine C++ Reference
Loading...
Searching...
No Matches
camera.cpp
Go to the documentation of this file.
1#include "camera.h"
2
3#include <graphics/graphics.h>
4
5#include <limits>
6
7namespace unravel
8{
9auto camera::get_zoom_factor() const -> float
10{
11 if(viewport_size_.height == 0)
12 {
13 return 0.0f;
14 }
15
16 return ortho_size_ / (float(viewport_size_.height) / 2.0f);
17}
18
19auto camera::get_ppu() const -> float
20{
21 return float(viewport_size_.height) / (2.0f * ortho_size_);
22}
23
24void camera::set_viewport_size(const usize32_t& viewport_size)
25{
26 viewport_size_ = viewport_size;
27 set_aspect_ratio(float(viewport_size.width) / float(viewport_size.height));
28}
29
30void camera::set_viewport_pos(const upoint32_t& viewportPos)
31{
32 viewport_pos_ = viewportPos;
33}
34
36{
37 return viewport_size_;
38}
39
41{
42 return viewport_pos_;
43}
44
46{
48
49 touch();
50}
51
56
57auto camera::get_fov() const -> float
58{
59 return fov_;
60}
61
62auto camera::get_near_clip() const -> float
63{
64 return near_clip_;
65}
66
67auto camera::get_far_clip() const -> float
68{
69 return far_clip_;
70}
71
72auto camera::get_ortho_size() const -> float
73{
74 return ortho_size_;
75}
76
77void camera::set_fov(float fFOVY)
78{
79 // Skip if no-op
80 if(math::equal(fFOVY, fov_, math::epsilon<float>()))
81 {
82 return;
83 }
84
85 // Update projection matrix and view frustum
86 fov_ = fFOVY;
87
88 touch();
89}
90
92{
93 // Bail if this is a no op.
94 if(mode == projection_mode_)
95 {
96 return;
97 }
98
99 // Alter the projection mode.
100 projection_mode_ = mode;
101
102 touch();
103}
104
106{
107 // Skip if this is a no-op
108 if(math::equal(distance, near_clip_, math::epsilon<float>()))
109 {
110 return;
111 }
112
113 // Store value
115
116 touch();
117
118 // Make sure near clip is less than the far clip
120 {
122 }
123}
124
126{
127 // Skip if this is a no-op
128 if(math::equal(distance, far_clip_, math::epsilon<float>()))
129 {
130 return;
131 }
132
133 // Store value
135
136 touch();
137
138 // Make sure near clip is less than the far clip
140 {
142 }
143}
144
146{
147 if(projection_mode_ == projection_mode::perspective)
148 {
149 float far_size = math::tan(math::radians<float>(fov_ * 0.5f)) * far_clip_;
150 return math::bbox(-far_size * aspect_ratio_,
151 -far_size,
152 near_clip_,
153 far_size * aspect_ratio_,
154 far_size,
155 far_clip_);
156 }
157
158 float spread = far_clip_ - near_clip_;
159 math::vec3 center = {0.0f, 0.0f, (far_clip_ + near_clip_) * 0.5f};
160 float orthographicSize = get_ortho_size();
161 math::vec3 size = {orthographicSize * 2.0f * aspect_ratio_, orthographicSize * 2.0f, spread};
162 return math::bbox(center - (size / 2.0f), center + (size / 2.0f));
163}
164
165void camera::set_aspect_ratio(float aspect, bool bLocked /* = false */)
166{
167 // Is this a no-op?
168 if(math::equal(aspect, aspect_ratio_, math::epsilon<float>()))
169 {
170 aspect_locked_ = bLocked;
171 return;
172
173 } // End if aspect is the same
174
175 // Update camera properties
176 aspect_ratio_ = aspect;
177 aspect_locked_ = bLocked;
178 aspect_dirty_ = true;
179 frustum_dirty_ = true;
180 projection_dirty_ = true;
181}
182
183auto camera::get_aspect_ratio() const -> float
184{
185 return aspect_ratio_;
186}
187
192
193auto camera::is_frustum_locked() const -> bool
194{
195 return frustum_locked_;
196}
197
198void camera::lock_frustum(bool locked)
199{
200 frustum_locked_ = locked;
201}
202
203auto camera::get_projection() const -> const math::transform&
204{
205 // Only update matrix if something has changed
207 {
209 {
210 // Generate the updated perspective projection matrix
211 float fov_radians = math::radians<float>(get_fov());
212 static const auto perspective_ =
213 gfx::is_homogeneous_depth() ? math::perspectiveNO<float> : math::perspectiveZO<float>;
214
215 math::mat4 projection = perspective_(fov_radians, aspect_ratio_, near_clip_, far_clip_);
216
217 projection[2][0] += aa_data_.z;
218 projection[2][1] += aa_data_.w;
219 projection_ = projection;
220 // Matrix has been updated
221 projection_dirty_ = false;
222 aspect_dirty_ = false;
223
224 } // End if projection matrix needs updating
225 else if(aspect_dirty_)
226 {
227 // Just alter the aspect ratio
228 math::mat4 projection = projection_;
229 projection[0][0] = projection[1][1] / aspect_ratio_;
230 projection_ = projection;
231 // Matrix has been updated
232 aspect_dirty_ = false;
233
234 } // End if only aspect ratio changed
235
236 } // End if perspective
238 {
240 {
241 // Generate the updated orthographic projection matrix
242 float zoom = get_zoom_factor();
243 const frect_t rect = {-float(viewport_size_.width) / 2.0f,
244 float(viewport_size_.height) / 2.0f,
245 float(viewport_size_.width) / 2.0f,
246 -float(viewport_size_.height) / 2.0f};
247 static const auto ortho_ =
248 gfx::is_homogeneous_depth() ? math::orthoNO<float> : math::orthoZO<float>;
249
250 math::mat4 projection = ortho_(rect.left * zoom,
251 rect.right * zoom,
252 rect.bottom * zoom,
253 rect.top * zoom,
255 get_far_clip());
256 projection[2][0] += aa_data_.z;
257 projection[2][1] += aa_data_.w;
258 projection_ = projection;
259 // Matrix has been updated
260 projection_dirty_ = false;
261 aspect_dirty_ = false;
262
263 } // End if projection matrix needs updating
264
265 } // End if orthographic
266
267 // Return the projection matrix.
268 return projection_;
269}
270
271auto camera::get_prev_projection() const -> const math::transform&
272{
273 return last_projection_;
274}
275
276auto camera::get_view() const -> const math::transform&
277{
278 return view_;
279}
280
281auto camera::get_prev_view() const -> const math::transform&
282{
283 return last_view_;
284}
285
286auto camera::get_view_relative() const -> const math::transform&
287{
288 return view_relative_;
289}
290
291auto camera::get_prev_view_relative() const -> const math::transform&
292{
293 return last_view_relative_;
294}
295
296auto camera::get_view_inverse() const -> const math::transform&
297{
298 return view_inverse_;
299}
300
301auto camera::get_view_inverse_relative() const -> const math::transform&
302{
304}
305
306auto camera::get_view_projection() const -> math::transform
307{
308 return get_projection() * get_view();
309}
310
311auto camera::get_prev_view_projection() const -> math::transform
312{
314}
315
317{
319}
320
325
326void camera::look_at(const math::vec3& vEye, const math::vec3& vAt)
327{
328 look_at(vEye, vAt, math::vec3(0.0f, 1.0f, 0.0f));
329}
330
331void camera::look_at(const math::vec3& vEye, const math::vec3& vAt, const math::vec3& vUp)
332{
333 // First update so the camera can cache the previous matrices
334 // record_current_matrices();
335
336 view_ = math::lookAt(vEye, vAt, vUp);
338
339
340 view_relative_ = math::lookAt(math::vec3(0.0f, 0.0f, 0.0f), vAt - vEye, vUp);
342
343 touch();
344}
345
346auto camera::get_position() const -> const math::vec3&
347{
349}
350
351auto camera::x_unit_axis() const -> math::vec3
352{
353 return view_inverse_.x_unit_axis();
354}
355auto camera::y_unit_axis() const -> math::vec3
356{
357 return view_inverse_.y_unit_axis();
358}
359
360auto camera::z_unit_axis() const -> math::vec3
361{
362 return view_inverse_.z_unit_axis();
363}
364
365auto camera::get_frustum() const -> const math::frustum&
366{
367 // Recalculate frustum if necessary
369 {
371 frustum_dirty_ = false;
372
373 // Also build the frustum / volume that represents the space between the
374 // camera position and its near plane. This frustum represents the
375 // 'volume' that can end up clipping geometry.
376
381 //-math::dot((math::vec3&)_clipping_volume.planes[math::volume_plane::near_plane],
382 // get_position()); // At camera
384 // The corner points also need adjusting in this case such that they sit
385 // precisely on the new planes.
398
399 } // End if recalc frustum
400
401 // Return the frustum
402 return frustum_;
403}
404
405auto camera::get_clipping_volume() const -> const math::frustum&
406{
407 // Recalculate frustum if necessary
409 {
410 get_frustum();
411 }
412
413 // Return the clipping volume
414 return clipping_volume_;
415}
416
418{
419 // Recompute the frustum as necessary.
420 const math::frustum& f = get_frustum();
421
422 // Request that frustum classifies
423 return f.classify_aabb(AABB);
424}
425
426auto camera::test_aabb(const math::bbox& AABB) const -> bool
427{
428 // Recompute the frustum as necessary.
429 const math::frustum& f = get_frustum();
430
431 // Request that frustum classifies
432 return f.test_aabb(AABB);
433}
434
436{
437 // Recompute the frustum as necessary.
438 const math::frustum& f = get_frustum();
439
440 // Request that frustum classifies
441 return f.classify_obb(AABB, t);
442}
443
444auto camera::test_obb(const math::bbox& AABB, const math::transform& t) const -> bool
445{
446 // Recompute the frustum as necessary.
447 const math::frustum& f = get_frustum();
448
449 // Request that frustum classifies
450 return f.test_obb(AABB, t);
451}
452
453auto camera::test_billboard(float size, const math::transform& t) const -> bool
454{
455 // Recompute the frustum as necessary.
456 const math::frustum& f = get_frustum();
457
458 auto center = t.get_position();
459 // 2) Build our test‐sphere
460 float radius = size * glm::root_two<float>();
461 math::bsphere sphere{center, radius};
462
463 return f.test_sphere(sphere);
464}
465
466auto camera::world_to_viewport(const math::vec3& pos) const -> math::vec3
467{
468 // Ensure we have an up-to-date projection and view matrix
469 auto view_proj = get_view_projection();
470
471 // Transform the point into clip space
472 math::vec4 clip = view_proj * math::vec4{pos.x, pos.y, pos.z, 1.0f};
473
474 // Project!
475 const float recip_w = 1.0f / clip.w;
476 clip.x *= recip_w;
477 clip.y *= recip_w;
478 clip.z *= recip_w;
479
480 // Transform to final screen space position
481 math::vec3 point;
482 point.x = ((clip.x * 0.5f) + 0.5f) * float(viewport_size_.width) + float(viewport_pos_.x);
483 point.y = ((clip.y * -0.5f) + 0.5f) * float(viewport_size_.height) + float(viewport_pos_.y);
484 point.z = clip.z;
485
486 // Point on screen!
487 return point;
488}
489
490auto camera::viewport_to_ray(const math::vec2& point, math::vec3& vec_ray_start, math::vec3& vec_ray_dir) const -> bool
491{
492 // Ensure we have an up-to-date projection and view matrix
493 math::transform mtx_proj = get_projection();
494 math::transform mtx_view = get_view();
495 math::transform mtx_inv_view = math::inverse(mtx_view);
496
497 // Transform pick position from viewport to normalized device coordinates (NDC)
498 float ndc_x = 2.0f * (point.x - viewport_pos_.x) / float(viewport_size_.width) - 1.0f;
499 float ndc_y = 2.0f * (point.y - viewport_pos_.y) / float(viewport_size_.height) - 1.0f;
500
501 // Ensure projection matrix values are valid
502 if (math::abs(mtx_proj[0][0]) < math::epsilon<float>() || math::abs(mtx_proj[1][1]) < math::epsilon<float>())
503 {
504 return false;
505 }
506
507 math::vec3 cursor(ndc_x / mtx_proj[0][0], -ndc_y / mtx_proj[1][1], 1.0f);
508
509 if (get_projection_mode() == projection_mode::orthographic)
510 {
511 vec_ray_start = mtx_inv_view.transform_coord(cursor);
512 vec_ray_dir = math::normalize(mtx_inv_view[2]); // Z-axis direction
513 }
514 else
515 {
516 vec_ray_start = mtx_inv_view.get_position();
517 vec_ray_dir = math::normalize(mtx_inv_view.transform_normal(cursor));
518 }
519
520 return true;
521}
522
523auto camera::viewport_to_world(const math::vec2& point, const math::plane& pl, math::vec3& world_pos, bool clip) const
524 -> bool
525{
526 if(clip && ((point.x < viewport_pos_.x) || (point.x > (viewport_pos_.x + viewport_size_.width)) ||
527 (point.y < viewport_pos_.y) || (point.y > (viewport_pos_.y + viewport_size_.height))))
528 {
529 return false;
530 }
531
532 math::vec3 pick_ray_dir;
533 math::vec3 pick_ray_origin;
534 // Convert the screen coordinates to a ray.
535 if(!viewport_to_ray(point, pick_ray_origin, pick_ray_dir))
536 {
537 return false;
538 }
539
540 // Get the length of the 'adjacent' side of the virtual triangle formed
541 // by the direction and normal.
542 float proj_ray_length = math::plane::dot_normal(pl, pick_ray_dir);
543 if(math::abs<float>(proj_ray_length) < math::epsilon<float>())
544 {
545 return false;
546 }
547
548 // Calculate distance to plane along its normal
549 float distance = math::plane::dot_normal(pl, pick_ray_origin) + pl.data.w;
550
551 // If both the "direction" and origin are on the same side of the plane
552 // then we can't possibly intersect (perspective rule only)
553 if(get_projection_mode() == projection_mode::perspective)
554 {
555 int nSign1 = (distance > 0) ? 1 : (distance < 0) ? -1 : 0;
556 int nSign2 = (proj_ray_length > 0) ? 1 : (proj_ray_length < 0) ? -1 : 0;
557 if(nSign1 == nSign2)
558 {
559 return false;
560 }
561
562 } // End if perspective
563
564 // Calculate the actual interval (Distance along the adjacent side / length of
565 // adjacent side).
566 distance /= -proj_ray_length;
567
568 // Store the results
569 world_pos = pick_ray_origin + (pick_ray_dir * distance);
570
571 // Success!
572 return true;
573}
574
576 const math::vec3& Origin,
577 math::vec3& world_pos,
578 math::vec3& major_axis) const -> bool
579{
580 return viewport_to_major_axis(point, Origin, z_unit_axis(), world_pos, major_axis);
581}
582
584 const math::vec3& Origin,
585 const math::vec3& Normal,
586 math::vec3& world_pos,
587 math::vec3& major_axis) const -> bool
588{
589 // First select the major axis plane based on the specified normal
590 major_axis = math::vec3(1, 0, 0); // YZ
591
592 // Get absolute normal vector
593 float x = math::abs<float>(Normal.x);
594 float y = math::abs<float>(Normal.y);
595 float z = math::abs<float>(Normal.z);
596
597 // If all the components are effectively equal, select one plane
598 if(math::abs<float>(x - y) < math::epsilon<float>() && math::abs<float>(x - z) < math::epsilon<float>())
599 {
600 major_axis = math::vec3(0, 0, 1); // XY
601
602 } // End if components equal
603 else
604 {
605 // Calculate which component of the normal is the major axis
606 float norm = x;
607 if(norm < y)
608 {
609 norm = y;
610 major_axis = math::vec3(0, 1, 0);
611 } // XZ
612 if(norm < z)
613 {
614 norm = z;
615 major_axis = math::vec3(0, 0, 1);
616 } // XY
617
618 } // End if perform compare
619
620 // Generate the intersection plane based on this information
621 // and pass through to the standard viewportToWorld method
622 math::plane p = math::plane::from_point_normal(Origin, major_axis);
623 return viewport_to_world(point, p, world_pos, false);
624}
625
626auto camera::viewport_to_camera(const math::vec3& point, math::vec3& camera_pos) const -> bool
627{
628 // Ensure that we have an up-to-date projection and view matrix
629 auto& mtx_proj = get_projection();
630
631 // Transform the pick position from screen space into camera space
632 camera_pos.x = (((2.0f * (point.x - viewport_pos_.x)) / float(viewport_size_.width)) - 1) / mtx_proj[0][0];
633 camera_pos.y = -(((2.0f * (point.y - viewport_pos_.y)) / float(viewport_size_.height)) - 1) / mtx_proj[1][1];
634 camera_pos.z = get_near_clip();
635
636 // Success!
637 return true;
638}
639
640auto camera::estimate_zoom_factor(const math::plane& pl) const -> float
641{
642 // Just return the actual zoom factor if this is orthographic
643 if(get_projection_mode() == projection_mode::orthographic)
644 {
645 return get_zoom_factor();
646 }
647
648 math::vec3 world;
649 // Otherwise, estimate is based on the distance from the grid plane.
650 viewport_to_world(math::vec2(float(viewport_size_.width) / 2.0f, float(viewport_size_.height) / 2.0f),
651 pl,
652 world,
653 false);
654
655 // Perform full position based estimation
656 return estimate_zoom_factor(world);
657}
658
659//-----------------------------------------------------------------------------
660// Name : estimateZoomFactor ()
667//-----------------------------------------------------------------------------
668auto camera::estimate_zoom_factor(const math::vec3& world_pos) const -> float
669{
670 return estimate_zoom_factor(world_pos, std::numeric_limits<float>::max());
671}
672
673auto camera::estimate_zoom_factor(const math::plane& pl, float max_val) const -> float
674{
675 // Just return the actual zoom factor if this is orthographic
676 if(get_projection_mode() == projection_mode::orthographic)
677 {
678 float factor = get_zoom_factor();
679 return math::min(max_val, factor);
680
681 } // End if orthographic
682 // Otherwise, estimate is based on the distance from the grid plane.
683 math::vec3 world;
684 viewport_to_world(math::vec2(float(viewport_size_.width) / 2.0f, float(viewport_size_.height) / 2.0f),
685 pl,
686 world,
687 false);
688
689 // Perform full position based estimation
690 return estimate_zoom_factor(world, max_val);
691}
692
693auto camera::estimate_zoom_factor(const math::vec3& world_pos, float max_val) const -> float
694{
695 // Just return the actual zoom factor if this is orthographic
696 if(get_projection_mode() == projection_mode::orthographic)
697 {
698 float factor = get_zoom_factor();
699 return math::min(max_val, factor);
700
701 } // End if orthographic
702
703 // New Zoom factor is based on the distance to this position
704 // along the camera's look vector.
705 math::vec3 view_pos = get_view().transform_coord(world_pos);
706 float distance = view_pos.z / (float(viewport_size_.height) * (45.0f / get_fov()));
707 return std::min<float>(max_val, distance);
708}
709
710auto camera::estimate_pick_tolerance(float wire_tolerance,
711 const math::vec3& pos,
712 const math::transform& object_transform) const -> math::vec3
713{
714 // Scale tolerance based on estimated world space zoom factor.
715 math::vec3 v = object_transform.transform_coord(pos);
716 wire_tolerance *= estimate_zoom_factor(v);
717
718 // Convert into object space tolerance.
719 math::vec3 object_wire_tolerance;
720 const math::vec3& vAxisScale = object_transform.get_scale();
721 return object_wire_tolerance / vAxisScale;
722}
723
731
732void camera::set_aa_data(const usize32_t& viewport_size,
733 std::uint32_t current_subpixel_index,
734 std::uint32_t temporal_aa_samples)
735{
736 if(temporal_aa_samples > 1)
737 {
738 float SampleX = math::halton(current_subpixel_index, 2) - 0.5f;
739 float SampleY = math::halton(current_subpixel_index, 3) - 0.5f;
740 if(temporal_aa_samples == 2)
741 {
742 float SamplesX[] = {-4.0f / 16.0f, 4.0f / 16.0f};
743 float SamplesY[] = {4.0f / 16.0f, -4.0f / 16.0f};
744
745 std::uint32_t Index = current_subpixel_index;
746 SampleX = SamplesX[Index];
747 SampleY = SamplesY[Index];
748 }
749 else if(temporal_aa_samples == 3)
750 {
751 // 3xMSAA
752 // A..
753 // ..B
754 // .C.
755 // Rolling circle pattern (A,B,C).
756 float SamplesX[] = {-2.0f / 3.0f, 2.0f / 3.0f, 0.0f / 3.0f};
757 float SamplesY[] = {-2.0f / 3.0f, 0.0f / 3.0f, 2.0f / 3.0f};
758 std::uint32_t Index = current_subpixel_index;
759 SampleX = SamplesX[Index];
760 SampleY = SamplesY[Index];
761 }
762 else if(temporal_aa_samples == 4)
763 {
764 // 4xMSAA
765 // Pattern docs:
766 // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476218(v=vs.85).aspx
767 // .N..
768 // ...E
769 // W...
770 // ..S.
771 // Rolling circle pattern (N,E,S,W).
772 float SamplesX[] = {-2.0f / 16.0f, 6.0f / 16.0f, 2.0f / 16.0f, -6.0f / 16.0f};
773 float SamplesY[] = {-6.0f / 16.0f, -2.0f / 16.0f, 6.0f / 16.0f, 2.0f / 16.0f};
774 std::uint32_t Index = current_subpixel_index;
775 SampleX = SamplesX[Index];
776 SampleY = SamplesY[Index];
777 }
778 else if(temporal_aa_samples == 8)
779 {
780 // This works better than various orderings of 8xMSAA.
781 std::uint32_t Index = current_subpixel_index;
782 SampleX = math::halton(Index, 2) - 0.5f;
783 SampleY = math::halton(Index, 3) - 0.5f;
784 }
785 else
786 {
787 // More than 8 samples can improve quality.
788 std::uint32_t Index = current_subpixel_index;
789 SampleX = math::halton(Index, 2) - 0.5f;
790 SampleY = math::halton(Index, 3) - 0.5f;
791 }
792
793 aa_data_ = math::vec4(float(current_subpixel_index), float(temporal_aa_samples), SampleX, SampleY);
794
795 float width = static_cast<float>(viewport_size.width);
796 float height = static_cast<float>(viewport_size.height);
797 aa_data_.z *= (2.0f / width);
798 aa_data_.w *= (2.0f / height);
799 }
800 else
801 {
802 aa_data_ = math::vec4(0.0f, 0.0f, 0.0f, 0.0f);
803 }
804
805 projection_dirty_ = true;
806}
807
808auto camera::get_aa_data() const -> const math::vec4&
809{
810 return aa_data_;
811}
812
814{
815 // All modifications require projection matrix and
816 // frustum to be updated.
817 view_dirty_ = true;
818 projection_dirty_ = true;
819 frustum_dirty_ = true;
820}
821
822auto camera::get_face_camera(uint32_t face, const math::transform& transform) -> camera
823{
824 camera cam;
825 cam.set_fov(90.0f);
826 cam.set_aspect_ratio(1.0f, true);
827 cam.set_near_clip(0.01f);
828 cam.set_far_clip(256.0f);
829
830 // Configurable axis vectors used to construct view matrices. In the
831 // case of the omni light, we align all frustums to the world axes.
832 math::vec3 X(1, 0, 0);
833 math::vec3 Y(0, 1, 0);
834 math::vec3 Z(0, 0, 1);
835 math::vec3 Zero(0, 0, 0);
837 // Generate the correct view matrix for the frustum
838
839 switch(face)
840 {
841 case 0: // right
842 t.set_rotation(-Z, +Y, +X);
843 break;
844 case 1: // left
845 t.set_rotation(+Z, +Y, -X);
846 break;
847 case 2: // up
849 {
850 t.set_rotation(+X, -Z, +Y);
851 }
852 else
853 {
854 t.set_rotation(+X, +Z, -Y);
855 }
856 break;
857 case 3: // down
859 {
860 t.set_rotation(+X, +Z, -Y);
861 }
862 else
863 {
864 t.set_rotation(+X, -Z, +Y);
865 }
866 break;
867 case 4: // front
868 t.set_rotation(+X, +Y, +Z);
869 break;
870 case 5: // back
871 t.set_rotation(-X, +Y, -Z);
872 break;
873 }
874
875 t = transform * t;
876
877 // Set new transform
878 cam.look_at(t.get_position(), t.get_position() + t.z_unit_axis(), t.y_unit_axis());
879
880 return cam;
881}
882} // namespace unravel
Provides storage for common representation of spherical bounding volume, and wraps up common function...
Definition bsphere.h:18
Storage for frustum planes / values and wraps up common functionality.
Definition frustum.h:18
vec3 position
Definition frustum.h:230
void update(const transform &view, const transform &proj, bool _oglNDC)
Updates the frustum based on the specified view and projection matrices.
Definition frustum.cpp:66
std::array< plane, 6 > planes
< The 6 planes of the frustum.
Definition frustum.h:226
std::array< vec3, 8 > points
The originating position of the frustum.
Definition frustum.h:228
General purpose transformation class designed to maintain each component of the transformation separa...
Definition transform.hpp:27
auto get_position() const noexcept -> const vec3_t &
Get the position component.
auto transform_normal(const vec2_t &v) const noexcept -> vec2_t
Transform a 2D normal.
auto x_unit_axis() const noexcept -> vec3_t
Get the unit X axis of the transform.
auto z_unit_axis() const noexcept -> vec3_t
Get the unit Z axis of the transform.
auto y_unit_axis() const noexcept -> vec3_t
Get the unit Y axis of the transform.
auto transform_coord(const vec2_t &v) const noexcept -> vec2_t
Transform a 2D coordinate.
Class representing a camera. Contains functionality for manipulating and updating a camera....
Definition camera.h:35
auto get_view_projection_relative() const -> math::transform
Definition camera.cpp:316
auto get_far_clip() const -> float
Retrieves the distance from the camera to the far clip plane.
Definition camera.cpp:67
float far_clip_
Far clip plane Distance.
Definition camera.h:505
auto get_fov() const -> float
Retrieves the current field of view angle in degrees.
Definition camera.cpp:57
auto classify_obb(const math::bbox &bounds, const math::transform &t) const -> math::volume_query
Determines if the specified OBB is within the frustum.
Definition camera.cpp:435
auto viewport_to_major_axis(const math::vec2 &point, const math::vec3 &axis_origin, math::vec3 &position_out, math::vec3 &major_axis_out) const -> bool
Converts a screen position into a world space intersection point on a major axis plane.
Definition camera.cpp:575
auto viewport_to_world(const math::vec2 &point, const math::plane &plane, math::vec3 &position_out, bool clip) const -> bool
Converts a screen position into a world space position on the specified plane.
Definition camera.cpp:523
auto viewport_to_ray(const math::vec2 &point, math::vec3 &vec_ray_start, math::vec3 &vec_ray_dir) const -> bool
Converts the specified screen position into a ray origin and direction vector.
Definition camera.cpp:490
auto get_prev_view_projection() const -> math::transform
Retrieves the previous view matrix.
Definition camera.cpp:311
auto test_obb(const math::bbox &bounds, const math::transform &t) const -> bool
Tests if the specified OBB is within the frustum.
Definition camera.cpp:444
auto get_prev_view_relative() const -> const math::transform &
Definition camera.cpp:291
void set_fov(float degrees)
Sets the field of view angle of this camera (perspective only).
Definition camera.cpp:77
auto get_projection_mode() const -> projection_mode
Retrieves the current projection mode for this camera.
Definition camera.cpp:52
void look_at(const math::vec3 &eye, const math::vec3 &at)
Sets the camera to look at a specified target.
Definition camera.cpp:326
void set_orthographic_size(float size)
Sets the half of the vertical size of the viewing volume in world units.
Definition camera.cpp:45
bool aspect_locked_
Should the aspect ratio be automatically updated by the render driver?
Definition camera.h:523
math::transform view_relative_
Definition camera.h:483
math::frustum clipping_volume_
The near clipping volume (area of space between the camera position and the near plane).
Definition camera.h:497
auto get_ppu() const -> float
Retrieves the pixels per unit (PPU).
Definition camera.cpp:19
auto get_viewport_size() const -> const usize32_t &
Retrieves the size of the viewport.
Definition camera.cpp:35
auto x_unit_axis() const -> math::vec3
Retrieves the x-axis unit vector of the camera's local coordinate system.
Definition camera.cpp:351
projection_mode projection_mode_
The type of projection currently selected for this camera.
Definition camera.h:499
bool view_dirty_
View matrix dirty ?
Definition camera.h:515
auto get_projection() const -> const math::transform &
Retrieves the current projection matrix.
Definition camera.cpp:203
auto get_clipping_volume() const -> const math::frustum &
Retrieves the frustum representing the space between the camera position and its near plane.
Definition camera.cpp:405
auto get_zoom_factor() const -> float
Retrieves the zoom factor.
Definition camera.cpp:9
math::frustum frustum_
Details regarding the camera frustum.
Definition camera.h:495
float aspect_ratio_
The aspect ratio used to generate the correct horizontal degrees (perspective only)
Definition camera.h:509
auto get_local_bounding_box() -> math::bbox
Retrieves the bounding box of this object.
Definition camera.cpp:145
static auto get_face_camera(std::uint32_t face, const math::transform &transform) -> camera
Retrieves a camera for one of six cube faces.
Definition camera.cpp:822
void touch()
Marks the camera as modified.
Definition camera.cpp:813
float near_clip_
Near clip plane Distance.
Definition camera.h:503
bool projection_dirty_
Projection matrix dirty ?
Definition camera.h:517
auto get_view() const -> const math::transform &
Retrieves the current view matrix.
Definition camera.cpp:276
math::transform view_inverse_relative_
Definition camera.h:484
void set_aa_data(const usize32_t &viewportSize, std::uint32_t currentSubpixelIndex, std::uint32_t temporalAASamples)
Sets the current jitter value for temporal anti-aliasing.
Definition camera.cpp:732
math::transform projection_
Cached projection matrix.
Definition camera.h:487
float ortho_size_
camera's half-size when in orthographic mode.
Definition camera.h:507
math::transform last_view_
Cached "previous" view matrix.
Definition camera.h:489
auto test_aabb(const math::bbox &bounds) const -> bool
Tests if the specified AABB is within the frustum.
Definition camera.cpp:426
void set_viewport_pos(const upoint32_t &viewportPos)
Sets the position of the viewport.
Definition camera.cpp:30
auto test_billboard(float size, const math::transform &t) const -> bool
Definition camera.cpp:453
math::transform view_
Cached view matrix.
Definition camera.h:480
bool frustum_dirty_
Are the frustum planes dirty ?
Definition camera.h:521
void set_projection_mode(projection_mode mode)
Sets the current projection mode for this camera (i.e. orthographic or perspective).
Definition camera.cpp:91
auto estimate_zoom_factor(const math::plane &plane) const -> float
Estimates the zoom factor based on the specified plane.
Definition camera.cpp:640
math::vec4 aa_data_
Anti-aliasing data.
Definition camera.h:478
auto get_prev_view_projection_relative() const -> math::transform
Definition camera.cpp:321
auto is_aspect_locked() const -> bool
Determines if the aspect ratio is currently being updated by the render driver.
Definition camera.cpp:188
void set_far_clip(float distance)
Sets the far plane distance.
Definition camera.cpp:125
auto estimate_pick_tolerance(float pixel_tolerance, const math::vec3 &reference_position, const math::transform &object_transform) const -> math::vec3
Estimates the pick tolerance based on the pixel tolerance and reference position.
Definition camera.cpp:710
bool frustum_locked_
Is the frustum locked?
Definition camera.h:525
auto y_unit_axis() const -> math::vec3
Retrieves the y-axis unit vector of the camera's local coordinate system.
Definition camera.cpp:355
auto get_view_relative() const -> const math::transform &
Definition camera.cpp:286
auto is_frustum_locked() const -> bool
Checks if the frustum is currently locked.
Definition camera.cpp:193
auto z_unit_axis() const -> math::vec3
Retrieves the z-axis unit vector of the camera's local coordinate system.
Definition camera.cpp:360
math::transform last_view_relative_
Definition camera.h:490
auto viewport_to_camera(const math::vec3 &point, math::vec3 &position_out) const -> bool
Converts a screen position into a camera space position at the near plane.
Definition camera.cpp:626
void set_aspect_ratio(float aspect, bool locked=false)
Sets the aspect ratio to be used for generating the horizontal FOV angle (perspective only).
Definition camera.cpp:165
auto get_prev_view() const -> const math::transform &
Definition camera.cpp:281
void lock_frustum(bool locked)
Locks or unlocks the frustum.
Definition camera.cpp:198
float fov_
Vertical degrees angle (perspective only).
Definition camera.h:501
auto get_view_inverse() const -> const math::transform &
Definition camera.cpp:296
auto get_position() const -> const math::vec3 &
Retrieves the current position of the camera.
Definition camera.cpp:346
auto world_to_viewport(const math::vec3 &pos) const -> math::vec3
Transforms a point from world space into screen space.
Definition camera.cpp:466
auto classify_aabb(const math::bbox &bounds) const -> math::volume_query
Determines if the specified AABB falls within the frustum.
Definition camera.cpp:417
auto get_aspect_ratio() const -> float
Retrieves the aspect ratio used to generate the horizontal FOV angle.
Definition camera.cpp:183
upoint32_t viewport_pos_
Viewport position.
Definition camera.h:511
auto get_ortho_size() const -> float
Retrieves the orthographic size.
Definition camera.cpp:72
bool aspect_dirty_
Has the aspect ratio changed?
Definition camera.h:519
usize32_t viewport_size_
Viewport size.
Definition camera.h:513
auto get_viewport_pos() const -> const upoint32_t &
Retrieves the position of the viewport.
Definition camera.cpp:40
auto get_view_projection() const -> math::transform
Retrieves the current view-projection matrix.
Definition camera.cpp:306
auto get_prev_projection() const -> const math::transform &
Definition camera.cpp:271
void record_current_matrices()
Makes a copy of the current view and projection matrices before they are changed.
Definition camera.cpp:724
math::transform last_projection_
Cached "previous" projection matrix.
Definition camera.h:493
void set_viewport_size(const usize32_t &viewportSize)
Sets the size of the viewport.
Definition camera.cpp:24
void set_near_clip(float distance)
Sets the near plane distance.
Definition camera.cpp:105
math::transform view_inverse_
Definition camera.h:481
auto get_view_inverse_relative() const -> const math::transform &
Definition camera.cpp:301
auto get_frustum() const -> const math::frustum &
Retrieves the current camera object frustum.
Definition camera.cpp:365
auto get_aa_data() const -> const math::vec4 &
Retrieves the anti-aliasing data.
Definition camera.cpp:808
auto get_near_clip() const -> float
Retrieves the distance from the camera to the near clip plane.
Definition camera.cpp:62
auto is_homogeneous_depth() -> bool
auto is_origin_bottom_left() -> bool
Definition bbox.cpp:5
float halton(std::uint32_t Index, std::uint32_t Base)
Definition math.h:256
auto inverse(transform_t< T, Q > const &t) noexcept -> transform_t< T, Q >
volume_query
Definition math_types.h:13
projection_mode
Enum representing the projection mode of a camera.
Definition camera.h:16
@ sphere
Sphere type reflection probe.
float distance
float y
float x
float z
Storage for box vector values and wraps up common functionality.
Definition bbox.h:21
Storage for infinite plane.
Definition plane.h:21
static auto from_point_normal(const vec3 &point, const vec3 &normal) -> plane
Creates a plane from a point and a normal.
Definition plane.cpp:20
static auto dot_normal(const plane &p, const vec3 &v) -> float
Computes the dot product of the plane normal and a vec3.
Definition plane.cpp:15
static auto dot_coord(const plane &p, const vec3 &v) -> float
Computes the dot product of the plane and a vec3 (considering the plane's distance).
Definition plane.cpp:10
T width
Definition basetypes.hpp:55
T height
Definition basetypes.hpp:56