80 if(math::equal(fFOVY,
fov_, math::epsilon<float>()))
149 float far_size = math::tan(math::radians<float>(fov_ * 0.5f)) * far_clip_;
153 far_size * aspect_ratio_,
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};
168 if(math::equal(aspect,
aspect_ratio_, math::epsilon<float>()))
211 float fov_radians = math::radians<float>(
get_fov());
212 static const auto perspective_ =
247 static const auto ortho_ =
250 math::mat4 projection = ortho_(
rect.
left * zoom,
328 look_at(vEye, vAt, math::vec3(0.0f, 1.0f, 0.0f));
331void camera::look_at(
const math::vec3& vEye,
const math::vec3& vAt,
const math::vec3& vUp)
336 view_ = math::lookAt(vEye, vAt, vUp);
340 view_relative_ = math::lookAt(math::vec3(0.0f, 0.0f, 0.0f), vAt - vEye, vUp);
423 return f.classify_aabb(AABB);
432 return f.test_aabb(AABB);
441 return f.classify_obb(AABB, t);
450 return f.test_obb(AABB, t);
458 auto center = t.get_position();
460 float radius =
size * glm::root_two<float>();
463 return f.test_sphere(
sphere);
469 auto view_proj = get_view_projection();
472 math::vec4 clip = view_proj * math::vec4{pos.x, pos.y, pos.z, 1.0f};
475 const float recip_w = 1.0f / clip.w;
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);
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;
502 if (math::abs(mtx_proj[0][0]) < math::epsilon<float>() || math::abs(mtx_proj[1][1]) < math::epsilon<float>())
507 math::vec3 cursor(ndc_x / mtx_proj[0][0], -ndc_y / mtx_proj[1][1], 1.0f);
512 vec_ray_dir = math::normalize(mtx_inv_view[2]);
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))))
532 math::vec3 pick_ray_dir;
533 math::vec3 pick_ray_origin;
535 if(!viewport_to_ray(
point, pick_ray_origin, pick_ray_dir))
543 if(math::abs<float>(proj_ray_length) < math::epsilon<float>())
556 int nSign2 = (proj_ray_length > 0) ? 1 : (proj_ray_length < 0) ? -1 : 0;
569 world_pos = pick_ray_origin + (pick_ray_dir *
distance);
576 const math::vec3& Origin,
577 math::vec3& world_pos,
578 math::vec3& major_axis)
const ->
bool
580 return viewport_to_major_axis(
point, Origin, z_unit_axis(), world_pos, major_axis);
584 const math::vec3& Origin,
585 const math::vec3& Normal,
586 math::vec3& world_pos,
587 math::vec3& major_axis)
const ->
bool
590 major_axis = math::vec3(1, 0, 0);
593 float x = math::abs<float>(Normal.x);
594 float y = math::abs<float>(Normal.y);
595 float z = math::abs<float>(Normal.z);
598 if(math::abs<float>(
x -
y) < math::epsilon<float>() && math::abs<float>(
x -
z) < math::epsilon<float>())
600 major_axis = math::vec3(0, 0, 1);
610 major_axis = math::vec3(0, 1, 0);
615 major_axis = math::vec3(0, 0, 1);
623 return viewport_to_world(
point, p, world_pos,
false);
629 auto& mtx_proj = get_projection();
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();
645 return get_zoom_factor();
650 viewport_to_world(math::vec2(
float(viewport_size_.width) / 2.0f,
float(viewport_size_.height) / 2.0f),
656 return estimate_zoom_factor(world);
670 return estimate_zoom_factor(world_pos, std::numeric_limits<float>::max());
678 float factor = get_zoom_factor();
679 return math::min(max_val, factor);
684 viewport_to_world(math::vec2(
float(viewport_size_.width) / 2.0f,
float(viewport_size_.height) / 2.0f),
690 return estimate_zoom_factor(world, max_val);
698 float factor = get_zoom_factor();
699 return math::min(max_val, factor);
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);
711 const math::vec3& pos,
715 math::vec3 v = object_transform.transform_coord(pos);
716 wire_tolerance *= estimate_zoom_factor(v);
719 math::vec3 object_wire_tolerance;
720 const math::vec3& vAxisScale = object_transform.get_scale();
721 return object_wire_tolerance / vAxisScale;
733 std::uint32_t current_subpixel_index,
734 std::uint32_t temporal_aa_samples)
736 if(temporal_aa_samples > 1)
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)
742 float SamplesX[] = {-4.0f / 16.0f, 4.0f / 16.0f};
743 float SamplesY[] = {4.0f / 16.0f, -4.0f / 16.0f};
745 std::uint32_t Index = current_subpixel_index;
746 SampleX = SamplesX[Index];
747 SampleY = SamplesY[Index];
749 else if(temporal_aa_samples == 3)
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];
762 else if(temporal_aa_samples == 4)
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];
778 else if(temporal_aa_samples == 8)
781 std::uint32_t Index = current_subpixel_index;
788 std::uint32_t Index = current_subpixel_index;
793 aa_data_ = math::vec4(
float(current_subpixel_index),
float(temporal_aa_samples), SampleX, SampleY);
795 float width =
static_cast<float>(viewport_size.
width);
796 float height =
static_cast<float>(viewport_size.
height);
802 aa_data_ = math::vec4(0.0f, 0.0f, 0.0f, 0.0f);
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);
842 t.set_rotation(-Z, +Y, +X);
845 t.set_rotation(+Z, +Y, -X);
850 t.set_rotation(+X, -Z, +Y);
854 t.set_rotation(+X, +Z, -Y);
860 t.set_rotation(+X, +Z, -Y);
864 t.set_rotation(+X, -Z, +Y);
868 t.set_rotation(+X, +Y, +Z);
871 t.set_rotation(-X, +Y, -Z);
878 cam.
look_at(t.get_position(), t.get_position() + t.z_unit_axis(), t.y_unit_axis());
Provides storage for common representation of spherical bounding volume, and wraps up common function...
Storage for frustum planes / values and wraps up common functionality.
void update(const transform &view, const transform &proj, bool _oglNDC)
Updates the frustum based on the specified view and projection matrices.
std::array< plane, 6 > planes
< The 6 planes of the frustum.
std::array< vec3, 8 > points
The originating position of the frustum.
Class representing a camera. Contains functionality for manipulating and updating a camera....
auto get_view_projection_relative() const -> math::transform
auto get_far_clip() const -> float
Retrieves the distance from the camera to the far clip plane.
float far_clip_
Far clip plane Distance.
auto get_fov() const -> float
Retrieves the current field of view angle in degrees.
auto classify_obb(const math::bbox &bounds, const math::transform &t) const -> math::volume_query
Determines if the specified OBB is within the frustum.
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.
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.
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.
auto get_prev_view_projection() const -> math::transform
Retrieves the previous view matrix.
auto test_obb(const math::bbox &bounds, const math::transform &t) const -> bool
Tests if the specified OBB is within the frustum.
auto get_prev_view_relative() const -> const math::transform &
void set_fov(float degrees)
Sets the field of view angle of this camera (perspective only).
auto get_projection_mode() const -> projection_mode
Retrieves the current projection mode for this camera.
void look_at(const math::vec3 &eye, const math::vec3 &at)
Sets the camera to look at a specified target.
void set_orthographic_size(float size)
Sets the half of the vertical size of the viewing volume in world units.
bool aspect_locked_
Should the aspect ratio be automatically updated by the render driver?
math::transform view_relative_
math::frustum clipping_volume_
The near clipping volume (area of space between the camera position and the near plane).
auto get_ppu() const -> float
Retrieves the pixels per unit (PPU).
auto get_viewport_size() const -> const usize32_t &
Retrieves the size of the viewport.
auto x_unit_axis() const -> math::vec3
Retrieves the x-axis unit vector of the camera's local coordinate system.
projection_mode projection_mode_
The type of projection currently selected for this camera.
bool view_dirty_
View matrix dirty ?
auto get_projection() const -> const math::transform &
Retrieves the current projection matrix.
auto get_clipping_volume() const -> const math::frustum &
Retrieves the frustum representing the space between the camera position and its near plane.
auto get_zoom_factor() const -> float
Retrieves the zoom factor.
math::frustum frustum_
Details regarding the camera frustum.
float aspect_ratio_
The aspect ratio used to generate the correct horizontal degrees (perspective only)
auto get_local_bounding_box() -> math::bbox
Retrieves the bounding box of this object.
static auto get_face_camera(std::uint32_t face, const math::transform &transform) -> camera
Retrieves a camera for one of six cube faces.
void touch()
Marks the camera as modified.
float near_clip_
Near clip plane Distance.
bool projection_dirty_
Projection matrix dirty ?
auto get_view() const -> const math::transform &
Retrieves the current view matrix.
math::transform view_inverse_relative_
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.
math::transform projection_
Cached projection matrix.
float ortho_size_
camera's half-size when in orthographic mode.
math::transform last_view_
Cached "previous" view matrix.
auto test_aabb(const math::bbox &bounds) const -> bool
Tests if the specified AABB is within the frustum.
void set_viewport_pos(const upoint32_t &viewportPos)
Sets the position of the viewport.
auto test_billboard(float size, const math::transform &t) const -> bool
math::transform view_
Cached view matrix.
bool frustum_dirty_
Are the frustum planes dirty ?
void set_projection_mode(projection_mode mode)
Sets the current projection mode for this camera (i.e. orthographic or perspective).
auto estimate_zoom_factor(const math::plane &plane) const -> float
Estimates the zoom factor based on the specified plane.
math::vec4 aa_data_
Anti-aliasing data.
auto get_prev_view_projection_relative() const -> math::transform
auto is_aspect_locked() const -> bool
Determines if the aspect ratio is currently being updated by the render driver.
void set_far_clip(float distance)
Sets the far plane distance.
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.
bool frustum_locked_
Is the frustum locked?
auto y_unit_axis() const -> math::vec3
Retrieves the y-axis unit vector of the camera's local coordinate system.
auto get_view_relative() const -> const math::transform &
auto is_frustum_locked() const -> bool
Checks if the frustum is currently locked.
auto z_unit_axis() const -> math::vec3
Retrieves the z-axis unit vector of the camera's local coordinate system.
math::transform last_view_relative_
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.
void set_aspect_ratio(float aspect, bool locked=false)
Sets the aspect ratio to be used for generating the horizontal FOV angle (perspective only).
auto get_prev_view() const -> const math::transform &
void lock_frustum(bool locked)
Locks or unlocks the frustum.
float fov_
Vertical degrees angle (perspective only).
auto get_view_inverse() const -> const math::transform &
auto get_position() const -> const math::vec3 &
Retrieves the current position of the camera.
auto world_to_viewport(const math::vec3 &pos) const -> math::vec3
Transforms a point from world space into screen space.
auto classify_aabb(const math::bbox &bounds) const -> math::volume_query
Determines if the specified AABB falls within the frustum.
auto get_aspect_ratio() const -> float
Retrieves the aspect ratio used to generate the horizontal FOV angle.
upoint32_t viewport_pos_
Viewport position.
auto get_ortho_size() const -> float
Retrieves the orthographic size.
bool aspect_dirty_
Has the aspect ratio changed?
usize32_t viewport_size_
Viewport size.
auto get_viewport_pos() const -> const upoint32_t &
Retrieves the position of the viewport.
auto get_view_projection() const -> math::transform
Retrieves the current view-projection matrix.
auto get_prev_projection() const -> const math::transform &
void record_current_matrices()
Makes a copy of the current view and projection matrices before they are changed.
math::transform last_projection_
Cached "previous" projection matrix.
void set_viewport_size(const usize32_t &viewportSize)
Sets the size of the viewport.
void set_near_clip(float distance)
Sets the near plane distance.
math::transform view_inverse_
auto get_view_inverse_relative() const -> const math::transform &
auto get_frustum() const -> const math::frustum &
Retrieves the current camera object frustum.
auto get_aa_data() const -> const math::vec4 &
Retrieves the anti-aliasing data.
auto get_near_clip() const -> float
Retrieves the distance from the camera to the near clip plane.
auto is_homogeneous_depth() -> bool
auto is_origin_bottom_left() -> bool
float halton(std::uint32_t Index, std::uint32_t Base)
auto inverse(transform_t< T, Q > const &t) noexcept -> transform_t< T, Q >
projection_mode
Enum representing the projection mode of a camera.
@ sphere
Sphere type reflection probe.
Storage for box vector values and wraps up common functionality.
Storage for infinite plane.
static auto from_point_normal(const vec3 &point, const vec3 &normal) -> plane
Creates a plane from a point and a normal.
static auto dot_normal(const plane &p, const vec3 &v) -> float
Computes the dot product of the plane normal and a vec3.
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).