82 if(math::equal(fFOVY,
fov_, math::epsilon<float>()))
110 if(math::equal(distance,
near_clip_, math::epsilon<float>()))
130 if(math::equal(distance,
far_clip_, math::epsilon<float>()))
151 float far_size = math::tan(math::radians<float>(fov_ * 0.5f)) * far_clip_;
155 far_size * aspect_ratio_,
160 float spread = far_clip_ - near_clip_;
161 math::vec3
center = {0.0f, 0.0f, (far_clip_ + near_clip_) * 0.5f};
162 float orthographicSize = get_ortho_size();
163 math::vec3
size = {orthographicSize * 2.0f * aspect_ratio_, orthographicSize * 2.0f, spread};
170 if(math::equal(aspect,
aspect_ratio_, math::epsilon<float>()))
213 float fov_radians = math::radians<float>(
get_fov());
214 static const auto perspective_ =
249 static const auto ortho_ =
252 math::mat4 projection = ortho_(
rect.
left * zoom,
335 look_at(vEye, vAt, math::vec3(0.0f, 1.0f, 0.0f));
338void camera::look_at(
const math::vec3& vEye,
const math::vec3& vAt,
const math::vec3& vUp)
343 view_ = math::lookAt(vEye, vAt, vUp);
347 view_relative_ = math::lookAt(math::vec3(0.0f, 0.0f, 0.0f), vAt - vEye, vUp);
430 return f.classify_aabb(AABB);
439 return f.test_aabb(AABB);
448 return f.classify_obb(AABB, t);
457 return f.test_obb(AABB, t);
465 auto center = t.get_position();
467 float radius =
size * glm::root_two<float>();
470 return f.test_sphere(
sphere);
476 auto view_proj = get_view_projection();
479 math::vec4 clip = view_proj * math::vec4{pos.x, pos.y, pos.z, 1.0f};
482 const float recip_w = 1.0f / clip.w;
489 point.
x = ((clip.x * 0.5f) + 0.5f) *
float(viewport_size_.width) + float(viewport_pos_.x);
490 point.
y = ((clip.y * -0.5f) + 0.5f) *
float(viewport_size_.height) + float(viewport_pos_.y);
505 float ndc_x = 2.0f * (
point.
x - viewport_pos_.x) /
float(viewport_size_.width) - 1.0f;
506 float ndc_y = 2.0f * (
point.
y - viewport_pos_.y) /
float(viewport_size_.height) - 1.0f;
509 if (math::abs(mtx_proj[0][0]) < math::epsilon<float>() || math::abs(mtx_proj[1][1]) < math::epsilon<float>())
514 math::vec3 cursor(ndc_x / mtx_proj[0][0], -ndc_y / mtx_proj[1][1], 1.0f);
519 vec_ray_dir = math::normalize(mtx_inv_view[2]);
533 if(clip && ((
point.
x < viewport_pos_.x) || (
point.
x > (viewport_pos_.x + viewport_size_.width)) ||
534 (
point.
y < viewport_pos_.y) || (
point.
y > (viewport_pos_.y + viewport_size_.height))))
539 math::vec3 pick_ray_dir;
540 math::vec3 pick_ray_origin;
542 if(!viewport_to_ray(
point, pick_ray_origin, pick_ray_dir))
550 if(math::abs<float>(proj_ray_length) < math::epsilon<float>())
562 int nSign1 = (distance > 0) ? 1 : (distance < 0) ? -1 : 0;
563 int nSign2 = (proj_ray_length > 0) ? 1 : (proj_ray_length < 0) ? -1 : 0;
573 distance /= -proj_ray_length;
576 world_pos = pick_ray_origin + (pick_ray_dir * distance);
585 uint32_t quad_height,
586 math::vec2& pixel_out)
const ->
bool
588 const math::vec3 quad_center = quad_transform.get_position();
589 const math::vec3 quad_normal = quad_transform.z_unit_axis();
592 math::vec3 world_pos;
593 if(!viewport_to_world(viewport_point, plane, world_pos,
false))
595 pixel_out = math::vec2(-1.0f, -1.0f);
599 const math::vec3
local = quad_transform.inverse_transform_coord(world_pos);
602 pixel_out = math::vec2(-1.0f, -1.0f);
605 pixel_out.x = (
local.x + 0.5f) *
static_cast<float>(quad_width);
606 pixel_out.y = (0.5f -
local.y) *
static_cast<float>(quad_height);
611 const math::vec3& Origin,
612 math::vec3& world_pos,
613 math::vec3& major_axis)
const ->
bool
615 return viewport_to_major_axis(
point, Origin, z_unit_axis(), world_pos, major_axis);
619 const math::vec3& Origin,
620 const math::vec3& Normal,
621 math::vec3& world_pos,
622 math::vec3& major_axis)
const ->
bool
625 major_axis = math::vec3(1, 0, 0);
628 float x = math::abs<float>(Normal.x);
629 float y = math::abs<float>(Normal.y);
630 float z = math::abs<float>(Normal.z);
633 if(math::abs<float>(
x -
y) < math::epsilon<float>() && math::abs<float>(
x -
z) < math::epsilon<float>())
635 major_axis = math::vec3(0, 0, 1);
645 major_axis = math::vec3(0, 1, 0);
650 major_axis = math::vec3(0, 0, 1);
658 return viewport_to_world(
point, p, world_pos,
false);
664 auto& mtx_proj = get_projection();
667 camera_pos.x = (((2.0f * (
point.
x - viewport_pos_.x)) / float(viewport_size_.width)) - 1) / mtx_proj[0][0];
668 camera_pos.y = -(((2.0f * (
point.
y - viewport_pos_.y)) / float(viewport_size_.height)) - 1) / mtx_proj[1][1];
669 camera_pos.z = get_near_clip();
680 return get_zoom_factor();
685 viewport_to_world(math::vec2(
float(viewport_size_.width) / 2.0f,
float(viewport_size_.height) / 2.0f),
691 return estimate_zoom_factor(world);
705 return estimate_zoom_factor(world_pos, std::numeric_limits<float>::max());
713 float factor = get_zoom_factor();
714 return math::min(max_val, factor);
719 viewport_to_world(math::vec2(
float(viewport_size_.width) / 2.0f,
float(viewport_size_.height) / 2.0f),
725 return estimate_zoom_factor(world, max_val);
733 float factor = get_zoom_factor();
734 return math::min(max_val, factor);
740 math::vec3 view_pos = get_view().transform_coord(world_pos);
741 float distance = view_pos.z / (float(viewport_size_.height) * (45.0f / get_fov()));
742 return std::min<float>(max_val, distance);
746 const math::vec3& pos,
750 math::vec3
v = object_transform.transform_coord(pos);
751 wire_tolerance *= estimate_zoom_factor(
v);
754 math::vec3 object_wire_tolerance;
755 const math::vec3& vAxisScale = object_transform.get_scale();
756 return object_wire_tolerance / vAxisScale;
768 std::uint32_t temporal_frame_index,
769 std::uint32_t temporal_aa_samples,
771 float jitter_amplitude,
772 float jitter_temporal_phase_scale)
777 if(temporal_aa_samples > 1)
779 float SampleX = 0.0f;
780 float SampleY = 0.0f;
787 jitter_temporal_phase_scale);
793 jitter_temporal_phase_scale);
797 const float SamplesX[] = {-4.0f / 16.0f, 4.0f / 16.0f};
798 const float SamplesY[] = {4.0f / 16.0f, -4.0f / 16.0f};
799 const std::uint32_t idx = temporal_frame_index % 2u;
800 SampleX = SamplesX[idx];
801 SampleY = SamplesY[idx];
811 const float SamplesX[] = {0.0f, -0.34641016f, 0.34641016f};
812 const float SamplesY[] = {0.4f, -0.2f, -0.2f};
813 const std::uint32_t idx = temporal_frame_index % 3u;
814 SampleX = SamplesX[idx];
815 SampleY = SamplesY[idx];
820 const float SamplesX[] = {-2.0f / 16.0f, 6.0f / 16.0f, 2.0f / 16.0f, -6.0f / 16.0f};
821 const float SamplesY[] = {-6.0f / 16.0f, -2.0f / 16.0f, 6.0f / 16.0f, 2.0f / 16.0f};
822 const std::uint32_t idx = temporal_frame_index % 4u;
823 SampleX = SamplesX[idx];
824 SampleY = SamplesY[idx];
832 jitter_temporal_phase_scale);
836 const float amp = std::clamp(jitter_amplitude, 0.0f, 1.5f);
840 aa_data_ = math::vec4(
float(temporal_frame_index & 0xFFFFu),
841 float(temporal_aa_samples),
845 float width =
static_cast<float>(viewport_size.
width);
846 float height =
static_cast<float>(viewport_size.
height);
852 aa_data_ = math::vec4(0.0f, 0.0f, 0.0f, 0.0f);
882 math::vec3 X(1, 0, 0);
883 math::vec3 Y(0, 1, 0);
884 math::vec3 Z(0, 0, 1);
885 math::vec3 Zero(0, 0, 0);
892 t.set_rotation(-Z, +Y, +X);
895 t.set_rotation(+Z, +Y, -X);
900 t.set_rotation(+X, -Z, +Y);
904 t.set_rotation(+X, +Z, -Y);
910 t.set_rotation(+X, +Z, -Y);
914 t.set_rotation(+X, -Z, +Y);
918 t.set_rotation(+X, +Y, +Z);
921 t.set_rotation(-X, +Y, -Z);
928 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.
math::transform taa_prev_view_
Snapshot for temporal reprojection: view/projection before advancing jitter (see set_aa_data).
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 get_taa_prev_view_projection() const -> math::transform
View-projection used for the previous rendered frame (before the latest jitter sample).
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 get_viewport_pos() const -> const ipoint32_t &
Retrieves the position of the viewport.
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 &
ipoint32_t viewport_pos_
Viewport position.
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_
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.
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.
void set_aa_data(const usize32_t &viewport_size, std::uint32_t temporal_frame_index, std::uint32_t temporal_aa_samples, taa_jitter_mode jitter_mode=taa_jitter_mode::progressive_golden, float jitter_amplitude=1.0f, float jitter_temporal_phase_scale=1.0f)
Sets the current jitter value for temporal anti-aliasing.
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 &
void set_viewport_size(const usize32_t &viewport_size)
Sets the size of the viewport.
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.
void set_viewport_pos(const ipoint32_t &viewport_pos)
Sets the position of the viewport.
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.
auto project_to_quad(const math::vec2 &viewport_point, const math::transform &quad_transform, uint32_t quad_width, uint32_t quad_height, math::vec2 &pixel_out) const -> bool
Raycasts from viewport point onto a quad plane and returns pixel coordinates.
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_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 taa_prev_projection_
math::transform last_projection_
Cached "previous" projection matrix.
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
void taa_subpixel_offset_progressive(std::uint32_t frame, float &offset_x, float &offset_y, float temporal_phase_scale=1.0f)
2D subpixel jitter in [-0.5, 0.5] for temporal AA (Kronecker / golden-ratio sequence).
auto inverse(transform_t< T, Q > const &t) noexcept -> transform_t< T, Q >
void taa_subpixel_offset_halton(std::uint32_t frame, float &offset_x, float &offset_y, float temporal_phase_scale=1.0f)
void taa_subpixel_offset_r2(std::uint32_t frame, float &offset_x, float &offset_y, float temporal_phase_scale=1.0f)
projection_mode
Enum representing the projection mode of a camera.
taa_jitter_mode
Subpixel jitter sequence for temporal AA (see camera::set_aa_data).
@ r2_low_discrepancy
R2 / recurrence lattice pair; alternative progressive 2D coverage.
@ progressive_golden
Kronecker / golden-ratio; smooth incommensurable steps (default).
@ halton_2_3
Halton(base 2,3) in [-0.5,0.5]; strong low-discrepancy, larger frame-to-frame steps.
@ 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).