533 lines
34 KiB
C++
533 lines
34 KiB
C++
//
|
|
// Created by dawsh on 1/25/24.
|
|
//
|
|
#pragma once
|
|
|
|
#include <J3ML/Geometry/Shape.hpp>
|
|
#include <J3ML/Geometry/Forward.hpp>
|
|
#include <J3ML/LinearAlgebra.hpp>
|
|
|
|
namespace J3ML::Geometry
|
|
{
|
|
/// A frustum can be set to one of the two common different forms.
|
|
enum class FrustumType
|
|
{
|
|
Invalid = 0,
|
|
|
|
/// Set the Frustum type to this value to define the orthographic projection formula. In orthographic projection,
|
|
/// 3D images are projected onto a 2D plane essentially by flattening the object along one direction (the plane normal).
|
|
/// The size of the projected images appear the same independent of their distance to the camera, and distant objects will
|
|
/// not appear smaller. The shape of the Frustum is identical to an oriented bounding box (OBB).
|
|
Orthographic,
|
|
|
|
/// Set the Frustum type to this value to use the perspective projection formula. With perspective projection, the 2D
|
|
/// image is formed by projecting 3D points towards a single point (the eye point/tip) of the Frustum, and computing the
|
|
/// point of intersection of the line of the projection and the near plane of the Frustum.
|
|
/// This corresponds to the optics in the real-world, and objects become smaller as they move to the distance.
|
|
/// The shape of the Frustum is a rectangular pyramid capped from the tip.
|
|
Perspective
|
|
};
|
|
|
|
/// The Frustum class offers choosing between the two common conventions for the value ranges in
|
|
/// post-projective space. If you are using either the OpenGL or Direct3D API, you must feed the API data that matches
|
|
/// the correct convention.
|
|
enum class FrustumProjectiveSpace
|
|
{
|
|
Invalid = 0,
|
|
/// If this option is chosen, the post-projective unit cube of the Frustum
|
|
/// is modelled after the OpenGL API convention, meaning that in projected space,
|
|
/// points inside the Frustum have the X and Y range in [-1, 1] and Z ranges in [-1, 1],
|
|
/// where the near plane maps to Z=-1 and the far plane maps to Z=1.
|
|
/// @note If you are submitting projection matrices to GPU hardware using the OpenGL API,
|
|
/// you **must** use this convention. (or otherwise more than half of the precision of the GL depth buffer is wasted)
|
|
GL,
|
|
|
|
/// If this option is chosen, the post-projective unit cube is modelled after the
|
|
/// Direct3D API convention, which differs from the GL convention that Z ranges in [0, 1] instead.
|
|
/// Near plane maps to Z=0, and far plane maps to Z=1. The X and Y ranges in [-1, 1] as is with GL.
|
|
/// @note If you are submitting projection matrices to GPU hardware using the Direct3D API,
|
|
/// you **must** use this convention.
|
|
D3D,
|
|
};
|
|
|
|
/// @brief The handedness rule in J3ML bundles together two different conventions related to the camera:
|
|
/// * the chirality of the world and view spaces,
|
|
/// * the fixed local front direction of the Frustum.
|
|
/// @note The world and view spaces are always assumed to the same chirality, meaning that Frustum::ViewMatrix()
|
|
/// (and hence Frustum::WorldMatrix()) always returns a matrix with a positive determinant, i.e. it does not mirror.
|
|
/// If FrustumRightHanded is chosen, then Frustum::ProjectionMatrix() is a mirroring matrix, since the post-projective space
|
|
/// is always left-handed.
|
|
/// @note Even though in the local space of the camera +Y is always up, in the world space one can use any 'world up' direction
|
|
/// as one pleases, by orienting the camera via the Frustum::up vector.
|
|
enum class FrustumHandedness
|
|
{
|
|
Invalid = 0,
|
|
|
|
/// If a Frustum is left-handed, then in the local space of the Frustum (the view space), the camera looks towards +Z,
|
|
/// while +Y goes towards up, and +X goes towards right.
|
|
/// @note The fixed-pipeline D3D9 API traditionally used the FrustumLeftHanded convention.
|
|
Left,
|
|
|
|
/// If a Frustum is right-handed, then the camera looks towards -Z, +Y is up, and +X is right.
|
|
/// @note The fixed-pipeline OpenGL API traditionally used the FrustumRightHanded convention.
|
|
Right
|
|
};
|
|
|
|
/// @brief Represents either an orthographic or a perspective viewing frustum.
|
|
/// @see FrustumType
|
|
/// @see FrustumProjectiveSpace
|
|
/// @see FrustumHandedness
|
|
class Frustum : public Shape {
|
|
public: // Members
|
|
|
|
/// Specifies whether this frustum is a perspective or an orthographic frustum.
|
|
FrustumType type;
|
|
/// Specifies whether the [-1, 1] or [0, 1] range is used for the post-projective depth range.
|
|
FrustumProjectiveSpace projectiveSpace ;
|
|
/// Specifies the chirality of world and view spaces
|
|
FrustumHandedness handedness;
|
|
/// The eye point of this frustum
|
|
Vector3 pos;
|
|
/// The normalized direction this frustum is watching towards.
|
|
Vector3 front;
|
|
/// The normalized up direction for this frustum.
|
|
/// This vector is specified in world (global) space. This vector is always normalized.
|
|
/// @note The vectors front and up must always be perpendicular to each other. This means that this up vector is not
|
|
/// a static/constant up vector, e.g. (0, 1, 0), but changes according to when the camera pitches up and down to
|
|
/// preserve the condition that front and up are always perpendicular
|
|
/// @note In the _local_ space of the Frustum, the direction +y is _always_ the up direction and cannot be changed. This
|
|
/// coincides to how Direct3D and OpenGL view and projection matrices are constructed
|
|
Vector3 up;
|
|
/// Distance from the eye point to the front plane
|
|
/// This parameter must be positive. If perspective projection is used, this parameter must be strictly positive
|
|
/// (0 is not allowed). If orthographic projection is used, 0 is possible (but uncommon, and not recommended).
|
|
/// When using the Frustum class to derive perspective projection matrices for a GPU, it should be noted that too
|
|
/// small values cause poor resolution of Z values near the back plane in post-perspective space, if non-linear
|
|
/// depth is used (which is common). The larger this value is, the more resolution there is for the Z values across the
|
|
/// depth range. Too large values cause clipping of geometry when they come very near the camera. */
|
|
float nearPlaneDistance;
|
|
/// Distance from the eye point to the back plane of the projection matrix.
|
|
/// This parameter must be strictly greater than nearPlaneDistance. The range [nearPlaneDistance, farPlaneDistance]
|
|
// specifies the visible range of objects inside the Frustum. When using the Frustum class for deriving perspective
|
|
// projection matrix for GPU rendering, it should be remembered that any geometry farther from the camera (in Z value)
|
|
// than this distance will be clipped from the view, and not rendered.
|
|
float farPlaneDistance;
|
|
|
|
union {
|
|
/// Horizontal field-of-view, in radians. This field is only valid if type == PerspectiveFrustum.
|
|
/** @see type. */
|
|
float horizontalFov;
|
|
/// The width of the orthographic frustum. This field is only valid if type == OrthographicFrustum.
|
|
/** @see type. */
|
|
float orthographicWidth;
|
|
};
|
|
|
|
union {
|
|
/// Vertical field-of-view, in radians. This field is only valid if type == PerspectiveFrustum.
|
|
/** @see type. */
|
|
float verticalFov;
|
|
/// The height of the orthographic frustum. This field is only valid if type == OrthographicFrustum.
|
|
/** @see type. */
|
|
float orthographicHeight;
|
|
};
|
|
|
|
void WorldMatrixChanged();
|
|
void ProjectionMatrixChanged();
|
|
|
|
/// Frustums are typically used in batch culling operations.
|
|
/// Therefore the matrices associated with a frustum are cached for immediate access.
|
|
Matrix4x4 worldMatrix;
|
|
Matrix4x4 projectionMatrix;
|
|
Matrix4x4 viewProjectionMatrix;
|
|
public:
|
|
|
|
/// The default constructor creates an uninitialized Frustum object.
|
|
/** This means that the values of the members type, projectiveSpace, handedness, pos, front, up, nearPlaneDistance, farPlaneDistance, horizontalFov/orthographicWidth and
|
|
verticalFov/orthographicHeight are all NaN after creating a new Frustum using this
|
|
default constructor. Remember to assign to them before use.
|
|
@note As an exception to other classes in MathGeoLib, this class initializes its members to NaNs, whereas the other classes leave the members uninitialized. This difference
|
|
is because the Frustum class implements a caching mechanism where world, projection and viewProj matrices are recomputed on demand, which does not work nicely together
|
|
if the defaults were uninitialized. */
|
|
Frustum();
|
|
public:
|
|
|
|
/// Quickly returns an arbitrary point inside this Frustum. Used in GJK intersection test.
|
|
[[nodiscard]] Vector3 AnyPointFast() const { return CornerPoint(0); }
|
|
|
|
|
|
/// Returns the tightest AABB that contains this Frustum.
|
|
/** This function computes the optimal minimum volume AABB that encloses this Frustum.
|
|
@note Since an AABB cannot generally represent a Frustum, this conversion is not exact, but the returned AABB
|
|
specifies a larger volume.
|
|
@see MinimalEnclosingOBB(), ToPolyhedron(). */
|
|
[[nodiscard]] AABB MinimalEnclosingAABB() const;
|
|
|
|
[[nodiscard]] bool IsFinite() const;
|
|
|
|
/// Returns the tightest OBB that encloses this Frustum.
|
|
/** This function computes the optimal minimum volume OBB that encloses this Frustum.
|
|
@note If the type of this frustum is Perspective, this conversion is not exact, but the returned OBB specifies
|
|
a larger volume. If the type of this Frustum is orthographic, this conversion is exact, since the shape of an
|
|
orthographic Frustum is an OBB.
|
|
@see MinimalEnclosingAABB(), ToPolyhedron(). */
|
|
[[nodiscard]] OBB MinimalEnclosingOBB(float expandGuardband = 1e-5f) const;
|
|
|
|
/// Sets the type of this Frustum.
|
|
/** @note Calling this function recomputes the cached view and projection matrices of this Frustum.
|
|
@see SetViewPlaneDistances(), SetFrame(), SetPos(), SetFront(), SetUp(), SetPerspective(), SetOrthographic(), ProjectiveSpace(), Handedness(). */
|
|
void SetKind(FrustumProjectiveSpace projectiveSpace, FrustumHandedness handedness);
|
|
/// Sets the depth clip distances of this Frustum.
|
|
/** @param n The z distance from the eye point to the position of the Frustum near clip plane. Always pass a positive value here.
|
|
@param f The z distance from the eye point to the position of the Frustum far clip plane. Always pass a value that is larger than nearClipDistance.
|
|
@note Calling this function recomputes the cached projection matrix of this Frustum.
|
|
@see SetKind(), SetFrame(), SetPos(), SetFront(), SetUp(), SetPerspective(), SetOrthographic(), NearPlaneDistance(), FarPlaneDistance(). */
|
|
void SetViewPlaneDistances(float n, float f);
|
|
|
|
/// Specifies the full coordinate space of this Frustum in one call.
|
|
/** @note Calling this function recomputes the cached world matrix of this Frustum.
|
|
@note As a micro-optimization, prefer this function over the individual SetPos/SetFront/SetUp functions if you need to do a batch of two or more changes, to avoid
|
|
redundant recomputation of the world matrix.
|
|
@see SetKind(), SetViewPlaneDistances(), SetPos(), SetFront(), SetUp(), SetPerspective(), SetOrthographic(), Pos(), Front(), Up(). */
|
|
void SetFrame(const Vector3& pos, const Vector3& front, const Vector3& up);
|
|
|
|
/// Sets the world-space position of this Frustum.
|
|
/** @note Calling this function recomputes the cached world matrix of this Frustum.
|
|
@see SetKind(), SetViewPlaneDistances(), SetFrame(), SetFront(), SetUp(), SetPerspective(), SetOrthographic(), Pos(). */
|
|
void SetPos(const Vector3& pos);
|
|
|
|
/// Sets the world-space direction the Frustum eye is looking towards.
|
|
/** @note Calling this function recomputes the cached world matrix of this Frustum.
|
|
@see SetKind(), SetViewPlaneDistances(), SetFrame(), SetPos(), SetUp(), SetPerspective(), SetOrthographic(), Front(). */
|
|
void SetFront(const Vector3& front);
|
|
|
|
/// Sets the world-space camera up direction vector of this Frustum.
|
|
/** @note Calling this function recomputes the cached world matrix of this Frustum.
|
|
@see SetKind(), SetViewPlaneDistances(), SetFrame(), SetPos(), SetFront(), SetPerspective(), SetOrthographic(), Up(). */
|
|
void SetUp(const Vector3& up);
|
|
|
|
/// Makes this Frustum use a perspective projection formula with the given FOV parameters.
|
|
/** A Frustum that uses the perspective projection is shaped like a pyramid that is cut from the top, and has a
|
|
base with a rectangular area.
|
|
@note Calling this function recomputes the cached projection matrix of this Frustum.
|
|
@see SetKind(), SetViewPlaneDistances(), SetFrame(), SetPos(), SetFront(), SetUp(), SetOrthographic(), HorizontalFov(), VerticalFov(), SetHorizontalFovAndAspectRatio(), SetVerticalFovAndAspectRatio(). */
|
|
void SetPerspective(float h, float v);
|
|
|
|
/// Makes this Frustum use an orthographic projection formula with the given FOV parameters.
|
|
/** A Frustum that uses the orthographic projection is shaded like a cube (an OBB).
|
|
@note Calling this function recomputes the cached projection matrix of this Frustum.
|
|
@see SetKind(), SetViewPlaneDistances(), SetFrame(), SetPos(), SetFront(), SetUp(), SetOrthographic(), OrthographicWidth(), OrthographicHeight(). */
|
|
void SetOrthographic(float w, float h);
|
|
|
|
/// Returns the handedness of the projection formula used by this Frustum.
|
|
/** @see SetKind(), FrustumHandedness. */
|
|
[[nodiscard]] FrustumHandedness Handedness() const { return handedness; }
|
|
/// Returns the type of the projection formula used by this Frustum.
|
|
/** @see SetPerspective(), SetOrthographic(), FrustumType. */
|
|
[[nodiscard]] FrustumType Type() const { return type; }
|
|
/// Returns the convention of the post-projective space used by this Frustum.
|
|
/** @see SetKind(), FrustumProjectiveSpace. */
|
|
[[nodiscard]] FrustumProjectiveSpace ProjectiveSpace() const { return projectiveSpace;}
|
|
/// Returns the world-space position of this Frustum.
|
|
/** @see SetPos(), Front(), Up(). */
|
|
[[nodiscard]] const Vector3 &Pos() const {return pos;}
|
|
/// Returns the world-space camera look-at direction of this Frustum.
|
|
/** @see Pos(), SetFront(), Up(). */
|
|
[[nodiscard]] const Vector3 &Front() const { return front; }
|
|
/// Returns the world-space camera up direction of this Frustum.
|
|
/** @see Pos(), Front(), SetUp(). */
|
|
[[nodiscard]] const Vector3 &Up() const { return up; }
|
|
/// Returns the distance from the Frustum eye to the near clip plane.
|
|
/** @see SetViewPlaneDistances(), FarPlaneDistance(). */
|
|
[[nodiscard]] float NearPlaneDistance() const { return nearPlaneDistance; }
|
|
/// Returns the distance from the Frustum eye to the far clip plane.
|
|
/** @see SetViewPlaneDistances(), NearPlaneDistance(). */
|
|
[[nodiscard]] float FarPlaneDistance() const { return farPlaneDistance;}
|
|
/// Returns the horizontal field-of-view used by this Frustum, in radians.
|
|
/** @note Calling this function when the Frustum is not set to use perspective projection will return values that are meaningless.
|
|
@see SetPerspective(), Type(), VerticalFov(). */
|
|
[[nodiscard]] float HorizontalFov() const { return horizontalFov;}
|
|
/// Returns the vertical field-of-view used by this Frustum, in radians.
|
|
/** @note Calling this function when the Frustum is not set to use perspective projection will return values that are meaningless.
|
|
@see SetPerspective(), Type(), HorizontalFov(). */
|
|
[[nodiscard]] float VerticalFov() const { return verticalFov;}
|
|
/// Returns the world-space width of this Frustum.
|
|
/** @note Calling this function when the Frustum is not set to use orthographic projection will return values that are meaningless.
|
|
@see SetOrthographic(), Type(), OrthographicHeight(). */
|
|
[[nodiscard]] float OrthographicWidth() const { return orthographicWidth; }
|
|
/// Returns the world-space height of this Frustum.
|
|
/** @note Calling this function when the Frustum is not set to use orthographic projection will return values that are meaningless.
|
|
@see SetOrthographic(), Type(), OrthographicWidth(). */
|
|
[[nodiscard]] float OrthograhpicHeight() const { return orthographicHeight; }
|
|
/// Returns the number of line segment edges that this Frustum is made up of, which is always 12.
|
|
/** This function is used in template-based algorithms to provide an unified API for iterating over the features of a Polyhedron. */
|
|
static int NumEdges() { return 12; }
|
|
/// Returns the aspect ratio of the view rectangle on the near plane.
|
|
/** The aspect ratio is the ratio of the width of the viewing rectangle to its height. This can also be computed by
|
|
the expression horizontalFov / verticalFov. To produce a proper non-stretched image when rendering, this
|
|
aspect ratio should match the aspect ratio of the actual render target (e.g. 4:3, 16:9 or 16:10 in full screen mode).
|
|
@see horizontalFov, verticalFov. */
|
|
[[nodiscard]] float AspectRatio() const;
|
|
|
|
/// Makes this Frustum use a perspective projection formula with the given horizontal FOV parameter and aspect ratio.
|
|
/** Specifies the horizontal and vertical field-of-view values for this Frustum based on the given horizontal FOV
|
|
and the screen size aspect ratio.
|
|
@note Calling this function recomputes the cached projection matrix of this Frustum.
|
|
@see SetPerspective(), SetVerticalFovAndAspectRatio(). */
|
|
void SetHorizontalFovAndAspectRatio(float hFov, float aspectRatio);
|
|
|
|
/// Makes this Frustum use a perspective projection formula with the given vertical FOV parameter and aspect ratio.
|
|
/** Specifies the horizontal and vertical field-of-view values for this Frustum based on the given vertical FOV
|
|
and the screen size aspect ratio.
|
|
@note Calling this function recomputes the cached projection matrix of this Frustum.
|
|
@see SetPerspective(), SetHorizontalFovAndAspectRatio(). */
|
|
void SetVerticalFovAndAspectRatio(float vFov, float aspectRatio);
|
|
|
|
/// Finds a ray in world space that originates at the eye point and looks in the given direction inside the frustum.
|
|
/** The (x,y) coordinate specifies the normalized viewport coordinate through which the ray passes.
|
|
Both x and y must be in the range [-1,1].
|
|
Specifying (-1, -1) returns the bottom-left corner of the near plane.
|
|
The point (1, 1) corresponds to the top-right corner of the near plane. */
|
|
Ray UnProject(float x, float y) const;
|
|
|
|
Ray UnProject(const Vector2& xy) const;
|
|
|
|
Ray UnProjectFromNearPlane(float x, float y) const;
|
|
|
|
[[nodiscard]] LineSegment UnProjectLineSegment(float x, float y) const;
|
|
|
|
Vector3 PointInside(float x, float y, float z) const;
|
|
|
|
Vector3 PointInside(const Vector3& xyz) const;
|
|
|
|
|
|
[[nodiscard]] Vector3 CenterPoint() const;
|
|
|
|
[[nodiscard]] Vector3 CornerPoint(int cornerIndex) const;
|
|
|
|
/// Returns a point on the near plane.
|
|
/** @param x A value in the range [-1, 1].
|
|
@param y A value in the range [-1, 1].
|
|
Specifying (-1, -1) returns the bottom-left corner of the near plane.
|
|
The point (1, 1) corresponds to the top-right corner of the near plane.
|
|
@note This coordinate space is called the normalized viewport coordinate space.
|
|
@see FarPlanePos(). */
|
|
[[nodiscard]] Vector3 NearPlanePos(float x, float y) const;
|
|
[[nodiscard]] Vector3 NearPlanePos(const Vector2& point) const;
|
|
|
|
/// Returns a point on the far plane.
|
|
/** @param x A value in the range [-1, 1].
|
|
@param y A value in the range [-1, 1].
|
|
Specifying (-1, -1) returns the bottom-left corner of the far plane.
|
|
The point (1, 1) corresponds to the top-right corner of the far plane.
|
|
@note This coordinate space is called the normalized viewport coordinate space.
|
|
@see NearPlanePos(). */
|
|
[[nodiscard]] Vector3 FarPlanePos(float x, float y) const;
|
|
[[nodiscard]] Vector3 FarPlanePos(const Vector2& point) const;
|
|
|
|
/// Computes the direction vector that points logically to the right-hand side of the Frustum.
|
|
/** This vector together with the member variables 'front' and 'up' form the orthonormal basis of the view frustum.
|
|
@see pos, front. */
|
|
[[nodiscard]] Vector3 WorldRight() const;
|
|
|
|
[[nodiscard]] Plane TopPlane() const; ///< [similarOverload: LeftPlane] [hideIndex]
|
|
[[nodiscard]] Plane BottomPlane() const; ///< [similarOverload: LeftPlane] [hideIndex]
|
|
[[nodiscard]] Plane RightPlane() const; ///< [similarOverload: LeftPlane] [hideIndex]
|
|
|
|
|
|
/// Returns the plane equation of the specified side of this Frustum.
|
|
/** The normal vector of the returned plane points outwards from the volume inside the frustum.
|
|
This means the negative half-space of the Frustum is the space inside the Frustum.
|
|
[indexTitle: Left/Right/Top/BottomPlane]
|
|
@see NearPlane(), FarPlane(), GetPlane(), GetPlanes(). */
|
|
[[nodiscard]] Plane LeftPlane() const;
|
|
|
|
/// Computes the plane equation of the far plane of this Frustum. [similarOverload: NearPlane]
|
|
/** The normal vector of the returned plane points outwards from the volume inside the frustum, i.e. away from the eye point.
|
|
(towards front). This means the negative half-space of the Frustum is the space inside the Frustum.
|
|
@see front, FarPlane(), LeftPlane(), RightPlane(), TopPlane(), BottomPlane(), GetPlane(), GetPlanes(). */
|
|
[[nodiscard]] Plane FarPlane() const;
|
|
|
|
/// Computes the plane equation of the near plane of this Frustum.
|
|
/** The normal vector of the returned plane points outwards from the volume inside the frustum, i.e. towards the eye point
|
|
(towards -front). This means the negative half-space of the Frustum is the space inside the Frustum.
|
|
@see front, FarPlane(), LeftPlane(), RightPlane(), TopPlane(), BottomPlane(), GetPlane(), GetPlanes(). */
|
|
[[nodiscard]] Plane NearPlane() const;
|
|
|
|
/// Computes the width of the near plane quad in world space units.
|
|
/** @see NearPlaneHeight(). */
|
|
[[nodiscard]] float NearPlaneWidth() const;
|
|
|
|
/// Computes the height of the near plane quad in world space units.
|
|
/** @see NearPlaneHeight(). */
|
|
[[nodiscard]] float NearPlaneHeight() const;
|
|
|
|
|
|
/// Returns the specified plane of this frustum.
|
|
/** The normal vector of the returned plane points outwards from the volume inside the frustum.
|
|
@param faceIndex A number in the range [0,5], which returns the plane at the selected index from
|
|
the array { near, far, left, right, top, bottom} */
|
|
Plane GetPlane(int faceIndex) const;
|
|
|
|
/// Returns all six planes of this Frustum.
|
|
/** The planes will be output in the order { near, far, left, right, top, bottom }.
|
|
@param outArray [out] A pointer to an array of at least 6 elements. This pointer will receive the planes of this Frustum.
|
|
This pointer may not be null.
|
|
@see GetPlane(), NearPlane(), FarPlane(), LeftPlane(), RightPlane(), TopPlane(), BottomPlane(). */
|
|
void GetPlanes(Plane *outArray) const;
|
|
|
|
|
|
/// Moves this Frustum by the given offset vector.
|
|
/** @note This function operates in-place.
|
|
@param offset The world space offset to apply to the position of this Frustum.
|
|
@see Transform(). */
|
|
void Translate(const Vector3& offset);
|
|
|
|
/// Applies a transformation to this Frustum.
|
|
/** @param transform The transformation to apply to this Frustum. This transformation must be
|
|
* affine, and must contain an orthogoal set of column vectors (may not contain shear or projection).
|
|
* The transformation can only contain uniform
|
|
* @see Translate(), Scale(), classes Matrix3x3, Matrix4x4, Quaternion
|
|
*/
|
|
void Transform(const Matrix3x3& transform);
|
|
void Transform(const Matrix4x4& transform);
|
|
void Transform(const Quaternion& transform);
|
|
|
|
/// Converts this Frustum to a Polyhedron.
|
|
/** This function returns a Polyhedron representation of this Frustum. This conversion is exact, meaning that the returned
|
|
Polyhedron represents exactly the same set of points that this Frustum does.
|
|
@see MinimalEnclosingAABB(), MinimalEnclosingOBB(). */
|
|
[[nodiscard]] Polyhedron ToPolyhedron() const;
|
|
|
|
/// Converts this Frustum to a PBVolume.
|
|
/** This function returns a plane-bounded volume representation of this Frustum. The conversion is exact, meaning that the
|
|
returned PBVolume<6> represents exactly the same set of points that this Frustum does.
|
|
@see ToPolyhedron(). */
|
|
[[nodiscard]] PBVolume<6> ToPBVolume() const;
|
|
|
|
|
|
[[nodiscard]] Vector3 Project(const Vector3& point) const;
|
|
|
|
/// Computes the matrix that transforms from the world (global) space to the projection space of this Frustum.
|
|
/** The matrix computed by this function is simply the concatenation ProjectionMatrix()*ViewMatrix(). This order
|
|
of concatenation follows the M*v convention of transforming vectors (as opposed to the v*M convention). This
|
|
multiplication order is used, since the matrices ProjectionMatrix() and ViewMatrix() also follow the M*v convention.
|
|
@return A matrix that performs the world->view->proj transformation. This matrix is neither invertible or
|
|
orthonormal. The returned matrix is built to use the convention Matrix * vector
|
|
to map a point between these spaces. (as opposed to the convention v*M).
|
|
@see WorldMatrix(), ViewMatrix(), ProjectionMatrix(). */
|
|
[[nodiscard]] Matrix4x4 ViewProjMatrix() const;
|
|
[[nodiscard]] Matrix4x4 ComputeViewProjMatrix() const;
|
|
|
|
|
|
/// Computes the matrix that transforms from the view space to the world (global) space of this Frustum.
|
|
/** @note The returned matrix is the inverse of the matrix returned by ViewMatrix().
|
|
@return An orthonormal affine matrix that performs the view->world transformation. The returned
|
|
matrix is built to use the convention Matrix * vector to map a point between these spaces.
|
|
(as opposed to the convention v*M).
|
|
@see ViewMatrix(), ProjectionMatrix(), ViewProjMatrix(). */
|
|
[[nodiscard]] Matrix4x4 WorldMatrix() const;
|
|
[[nodiscard]] Matrix4x4 ComputeWorldMatrix() const;
|
|
|
|
/// Computes the matrix that transforms from the world (global) space to the view space of this Frustum.
|
|
/** @note The returned matrix is the inverse of the matrix returned by WorldMatrix().
|
|
@return An orthonormal affine matrix that performs the world->view transformation. The returned
|
|
matrix is built to use the convention Matrix * vector to map a point between these spaces.
|
|
(as opposed to the convention v*M).
|
|
@see WorldMatrix(), ProjectionMatrix(), ViewProjMatrix(). */
|
|
[[nodiscard]] Matrix4x4 ViewMatrix() const;
|
|
[[nodiscard]] Matrix4x4 ComputeViewMatrix() const;
|
|
|
|
|
|
/// Computes the matrix that projects from the view space to the projection space of this Frustum.
|
|
/** @return A projection matrix that performs the view->proj transformation. This matrix is neither
|
|
invertible or orthonormal. The returned matrix is built to use the convention Matrix * vector
|
|
to map a point between these spaces. (as opposed to the convention v*M).
|
|
@see WorldMatrix(), ViewMatrix(), ViewProjMatrix(). */
|
|
[[nodiscard]] Matrix4x4 ProjectionMatrix() const;
|
|
[[nodiscard]] Matrix4x4 ComputeProjectionMatrix() const;
|
|
|
|
|
|
/// Tests if the given object is fully contained inside this Frustum.
|
|
/** This function returns true if the given object lies inside this Frustum, and false otherwise.
|
|
@note The comparison is performed using less-or-equal, so the faces of this Frustum count as being inside, but
|
|
due to float inaccuracies, this cannot generally be relied upon.
|
|
@todo Add Contains(Circle/Disc/Sphere/Capsule).
|
|
@see Distance(), Intersects(), ClosestPoint(). */
|
|
[[nodiscard]] bool Contains(const Vector3 &point) const;
|
|
[[nodiscard]] bool Contains(const LineSegment &lineSegment) const;
|
|
[[nodiscard]] bool Contains(const Triangle &triangle) const;
|
|
[[nodiscard]] bool Contains(const Polygon &polygon) const;
|
|
[[nodiscard]] bool Contains(const AABB &aabb) const;
|
|
[[nodiscard]] bool Contains(const OBB &obb) const;
|
|
[[nodiscard]] bool Contains(const Frustum &frustum) const;
|
|
[[nodiscard]] bool Contains(const Polyhedron &polyhedron) const;
|
|
|
|
/// Computes the distance between this Frustum and the given object.
|
|
/** This function finds the nearest pair of points on this and the given object, and computes their distance.
|
|
If the two objects intersect, or one object is contained inside the other, the returned distance is zero.
|
|
@todo Add Frustum::Distance(Line/Ray/LineSegment/Plane/Triangle/Polygon/Circle/Disc/AABB/OBB/Capsule/Frustum/Polyhedron).
|
|
@see Contains(), Intersects(), ClosestPoint(). */
|
|
[[nodiscard]] float Distance(const Vector3 &point) const;
|
|
|
|
/// Computes the closest point inside this frustum to the given point.
|
|
/** If the target point lies inside this Frustum, then that point is returned.
|
|
@see Distance(), Contains(), Intersects().
|
|
@todo Add ClosestPoint(Line/Ray/LineSegment/Plane/Triangle/Polygon/Circle/Disc/AABB/OBB/Capsule/Frustum/Polyhedron). */
|
|
[[nodiscard]] Vector3 ClosestPoint(const Vector3& point) const;
|
|
|
|
/// Tests whether this Frustum and the given object intersect.
|
|
/** Both objects are treated as "solid", meaning that if one of the objects is fully contained inside
|
|
another, this function still returns true. (e.g. in case a line segment is contained inside this Frustum,
|
|
or this Frustum is contained inside a Sphere, etc.)
|
|
The first parameter of this function specifies the other object to test against.
|
|
@see Contains(), Distance(), ClosestPoint().
|
|
@todo Add Intersects(Circle/Disc). */
|
|
[[nodiscard]] bool Intersects(const Ray& ray) const;
|
|
[[nodiscard]] bool Intersects(const Line &line) const;
|
|
[[nodiscard]] bool Intersects(const LineSegment& lineSegment) const;
|
|
[[nodiscard]] bool Intersects(const AABB& aabb) const;
|
|
[[nodiscard]] bool Intersects(const OBB& obb) const;
|
|
[[nodiscard]] bool Intersects(const Plane& plane) const;
|
|
[[nodiscard]] bool Intersects(const Triangle& triangle) const;
|
|
[[nodiscard]] bool Intersects(const Polygon& lineSegment) const;
|
|
[[nodiscard]] bool Intersects(const Sphere& aabb) const;
|
|
[[nodiscard]] bool Intersects(const Capsule& obb) const;
|
|
[[nodiscard]] bool Intersects(const Frustum& plane) const;
|
|
[[nodiscard]] bool Intersects(const Polyhedron& triangle) const;
|
|
|
|
/// Projects this Frustum onto the given 1D axis direction vector.
|
|
/** This function collapses this Frustum onto an 1D axis for the purposes of e.g. separate axis test computations.
|
|
The function returns a 1D range [outMin, outMax] denoting the interval of the projection.
|
|
@param direction The 1D axis to project to. This vector may be unnormalized, in which case the output
|
|
of this function gets scaled by the length of this vector.
|
|
@param outMin [out] Returns the minimum extent of this object along the projection axis.
|
|
@param outMax [out] Returns the maximum extent of this object along the projection axis. */
|
|
void ProjectToAxis(const Vector3 &direction, float &outMin, float &outMax) const;
|
|
|
|
void GetCornerPoints(Vector3 *outPointArray) const;
|
|
|
|
Vector3 ExtremePoint(const Vector3 &direction, float &projectionDistance) const;
|
|
|
|
[[nodiscard]] LineSegment Edge(int edgeIndex) const;
|
|
|
|
|
|
|
|
/// Maps a point from the normalized viewport space to the screen space
|
|
/** In normalized viewport space, top-left: (-1, 1), top-right: (1,1), bottom-left: (-1, -1), bottom-right: (-1, 1)
|
|
In screen space: top-left: (0, 0), top-right: (0, screenWidth-1), bottom-left: (0, screenHeight-1), bottom-right: (screenWidth-1, screenHeight-1).
|
|
This mapping is affine.
|
|
@see ScreenToViewportSpace(). */
|
|
static Vector2 ViewportToScreenSpace(float x, float y, int screenWidth, int screenHeight);
|
|
static Vector2 ViewportToScreenSpace(const Vector2& point, int screenWidth, int screenHeight);
|
|
|
|
/// Maps a point from screen space to normalized viewport space.
|
|
/** This function computes the inverse function of ViewportToScreenSpace(). This mapping is affine.
|
|
@see ViewportToScreenSpace(). */
|
|
static Vector2 ScreenToViewportSpace(float x, float y, int screenWidth, int screenHeight);
|
|
static Vector2 ScreenToViewportSpace(const Vector2& point, int screenWidth, int screenHeight);
|
|
};
|
|
|
|
Frustum operator * (const Matrix3x3& transform, const Frustum& frustum);
|
|
Frustum operator * (const Matrix4x4& transform, const Frustum& frustum);
|
|
Frustum operator * (const Quaternion& transform, const Frustum& frustum);
|
|
} |