Laid Out Headers
This commit is contained in:
@@ -10,17 +10,17 @@
|
||||
|
||||
namespace J3ML::Geometry
|
||||
{
|
||||
|
||||
using J3ML::LinearAlgebra::CoordinateFrame;
|
||||
|
||||
/// A frustum can be set to one of the two common different forms.
|
||||
enum class FrustumType
|
||||
{
|
||||
Invalid,
|
||||
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.
|
||||
@@ -29,17 +29,183 @@ namespace J3ML::Geometry
|
||||
Perspective
|
||||
};
|
||||
|
||||
class Frustum : public Shape {
|
||||
public:
|
||||
Plane TopFace;
|
||||
Plane BottomFace;
|
||||
Plane RightFace;
|
||||
Plane LeftFace;
|
||||
Plane FarFace;
|
||||
Plane NearFace;
|
||||
static Frustum CreateFrustumFromCamera(const CoordinateFrame& cam, float aspect, float fovY, float zNear, float zFar);
|
||||
AABB MinimalEnclosingAABB() const;
|
||||
/// 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,
|
||||
};
|
||||
|
||||
/// 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
|
||||
};
|
||||
|
||||
/// Represents either an orthographic or a perspective viewing frustum.
|
||||
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: /// Methods
|
||||
Frustum();
|
||||
|
||||
static Frustum CreateFrustumFromCamera(const CoordinateFrame& cam, float aspect, float fovY, float zNear, float zFar);
|
||||
AABB MinimalEnclosingAABB() const;
|
||||
OBB MinimalEnclosingOBB() const;
|
||||
void SetKind(FrustumProjectiveSpace projectiveSpace, FrustumHandedness handedness);
|
||||
void SetViewPlaneDistances(float nearPlaneDistance, float farPlaneDistance);
|
||||
void SetFrame(const Vector3& pos, const Vector3& front, const Vector3& up);
|
||||
void SetPos(const Vector3& pos);
|
||||
void SetFront(const Vector3& front);
|
||||
void SetUp(const Vector3& up);
|
||||
void SetPerspective(float horizontalFov, float verticalFov);
|
||||
void SetOrthographic(float orthographicWidth, float orthographicHeight);
|
||||
FrustumHandedness Handedness() const { return handedness; }
|
||||
FrustumType Type() const { return type; }
|
||||
FrustumProjectiveSpace ProjectiveSpace() const { return projectiveSpace;}
|
||||
const Vector3 &Pos() const {return pos;}
|
||||
const Vector3 &Front() const { return front; }
|
||||
const Vector3 &Up() const { return up; }
|
||||
float NearPlaneDistance() const { return nearPlaneDistance; }
|
||||
float FarPlaneDistance() const { return farPlaneDistance;}
|
||||
float HorizontalFov() const { return horizontalFov;}
|
||||
float VerticalFov() const { return verticalFov;}
|
||||
float OrthographicWidth() const { return orthographicWidth; }
|
||||
float OrthograhpicHeight() const { return orthographicHeight; }
|
||||
int NumEdges() const { return 12; }
|
||||
float AspectRatio() const;
|
||||
|
||||
void SetHorizontalFovAndAspectRatio(float horizontalFov, float aspectRatio);
|
||||
|
||||
|
||||
Vector3 CornerPoint(int cornerIndex) const;
|
||||
|
||||
Vector3 NearPlanePos(float x, float y) const;
|
||||
Vector3 FarPlanePos(float x, float y) const;
|
||||
|
||||
Vector3 WorldRight() const;
|
||||
|
||||
Plane TopPlane() const;
|
||||
Plane BottomPlane() const;
|
||||
Plane RightPlane() const;
|
||||
Plane LeftPlane() const;
|
||||
Plane FarPlane() const;
|
||||
Plane NearPlane() const;
|
||||
float NearPlaneWidth() const;
|
||||
float NearPlaneHeight() const;
|
||||
|
||||
|
||||
void Translate(const Vector3& offset);
|
||||
void Transform(const Matrix3x3& transform);
|
||||
void Transform(const Matrix4x4& transform);
|
||||
void Transform(const Quaternion& transform);
|
||||
|
||||
|
||||
Polyhedron ToPolyhedron() const;
|
||||
|
||||
bool Intersects(const Ray& ray) const;
|
||||
//bool Intersects(const Line& line) const;
|
||||
bool Intersects(const LineSegment& lineSegment) const;
|
||||
bool Intersects(const AABB& aabb) const;
|
||||
bool Intersects(const OBB& obb) const;
|
||||
bool Intersects(const Plane& plane) const;
|
||||
bool Intersects(const Triangle& triangle) const;
|
||||
bool Intersects(const Polygon& lineSegment) const;
|
||||
bool Intersects(const Sphere& aabb) const;
|
||||
bool Intersects(const Capsule& obb) const;
|
||||
bool Intersects(const Frustum& plane) const;
|
||||
bool Intersects(const Polyhedron& triangle) const;
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user