Implemented More Documentation
This commit is contained in:
7
include/J3ML/Algorithm/SAT.h
Normal file
7
include/J3ML/Algorithm/SAT.h
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
namespace J3ML::Algorithm
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
@@ -8,86 +8,173 @@
|
|||||||
|
|
||||||
namespace J3ML::Geometry
|
namespace J3ML::Geometry
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
using namespace J3ML::LinearAlgebra;
|
using namespace J3ML::LinearAlgebra;
|
||||||
using J3ML::Algorithm::RNG;
|
using J3ML::Algorithm::RNG;
|
||||||
// A 3D axis-aligned bounding box
|
|
||||||
// This data structure can be used to represent coarse bounds of objects, in situations where detailed triangle-level
|
|
||||||
// computations can be avoided. In physics systems, bounding boxes are used as an efficient early-out test for geometry
|
|
||||||
// intersection queries.
|
|
||||||
// the 'Axis-aligned' part in the name means that the local axes of this bounding box are restricted to align with the
|
|
||||||
// axes of the world space coordinate system. This makes computation involving AABB's very fast, since AABB's cannot
|
|
||||||
// be arbitrarily oriented in the space with respect to each other.
|
|
||||||
// If you need to represent a box in 3D space with arbitrary orientation, see the class OBB. */
|
|
||||||
|
|
||||||
|
/// @brief A 3D axis-aligned bounding box.
|
||||||
|
/// This data structure can be used to represent coarse bounds of objects, in situations where detailed triangle-level
|
||||||
|
/// computations can be avoided. In physics systems, bounding boxes are used as an efficient early-out test for geometry
|
||||||
|
/// intersection queries.
|
||||||
|
/// the 'Axis-aligned' part in the name means that the local axes of this bounding box are restricted to align with the
|
||||||
|
/// axes of the world space coordinate system. This makes computation involving AABB's very fast, since AABB's cannot
|
||||||
|
/// be arbitrarily oriented in the space with respect to each other.
|
||||||
|
/// If you need to represent a box in 3D space with arbitrary orientation, see the class OBB. */
|
||||||
class AABB : public Shape {
|
class AABB : public Shape {
|
||||||
public:
|
public:
|
||||||
|
/// Specifies the minimum extent of this AABB in the world space x, y and z axes.
|
||||||
Vector3 minPoint;
|
Vector3 minPoint;
|
||||||
|
/// Specifies the maximum extent of this AABB in the world space x, y and z axes. [similarOverload: minPoint]
|
||||||
Vector3 maxPoint;
|
Vector3 maxPoint;
|
||||||
public:
|
public:
|
||||||
static int NumFaces() { return 6; }
|
static int NumFaces() { return 6; }
|
||||||
static int NumEdges() { return 12; }
|
static int NumEdges() { return 12; }
|
||||||
static int NumVertices() { return 8; }
|
static int NumVertices() { return 8; }
|
||||||
public:
|
public:
|
||||||
|
/// The default constructor does not initialize any members of this class.
|
||||||
|
/** This means that the values of the members minPoint and maxPoint are undefined after creating a new AABB using this
|
||||||
|
default constructor. Remember to assign to them before use.
|
||||||
|
@see minPoint, maxPoint. */
|
||||||
AABB();
|
AABB();
|
||||||
|
|
||||||
|
/// Constructs this AABB by specifying the minimum and maximum extending corners of the box.
|
||||||
|
/** @see minPoint, maxPoint. */
|
||||||
AABB(const Vector3& min, const Vector3& max);
|
AABB(const Vector3& min, const Vector3& max);
|
||||||
|
|
||||||
|
/// Constructs this AABB to enclose the given OBB.
|
||||||
|
/** This constructor computes the optimal minimum volume AABB that encloses the given OBB.
|
||||||
|
@note Since an AABB cannot generally represent an OBB, this conversion is not exact, but the returned AABB
|
||||||
|
specifies a larger volume.
|
||||||
|
@see class OBB. */
|
||||||
|
explicit AABB(const OBB &obb);
|
||||||
|
|
||||||
|
/// Constructs this AABB to enclose the given Sphere.
|
||||||
|
/** @see class Sphere. */
|
||||||
|
explicit AABB(const Sphere &s);
|
||||||
|
|
||||||
Vector3 HalfDiagonal() const { return HalfSize(); }
|
Vector3 HalfDiagonal() const { return HalfSize(); }
|
||||||
|
|
||||||
static AABB FromCenterAndSize(const Vector3 ¢er, const Vector3 &size);
|
static AABB FromCenterAndSize(const Vector3 ¢er, const Vector3 &size);
|
||||||
|
|
||||||
|
|
||||||
|
/// Returns the minimum world-space coordinate along the given axis.
|
||||||
float MinX() const;
|
float MinX() const;
|
||||||
float MinY() const;
|
float MinY() const; ///< [similarOverload: MinX]
|
||||||
float MinZ() const;
|
float MinZ() const; ///< [similarOverload: MinX]
|
||||||
|
|
||||||
|
/// Returns the maximum world-space coordinate along the given axis.
|
||||||
float MaxX() const;
|
float MaxX() const;
|
||||||
float MaxY() const;
|
float MaxY() const; ///< [similarOverload: MaxX]
|
||||||
float MaxZ() const;
|
float MaxZ() const; ///< [similarOverload: MaxX]
|
||||||
|
|
||||||
/// Returns the smallest sphere that contains this AABB.
|
/// Returns the smallest sphere that contains this AABB.
|
||||||
/// This function computes the minimal volume sphere that contains all the points inside this AABB
|
/// This function computes the minimal volume sphere that contains all the points inside this AABB
|
||||||
Sphere MinimalEnclosingSphere() const;
|
Sphere MinimalEnclosingSphere() const;
|
||||||
|
|
||||||
|
/// [similarOverload: Size]
|
||||||
|
/** Returns Size()/2.
|
||||||
|
@see Size(), HalfDiagonal(). */
|
||||||
Vector3 HalfSize() const;
|
Vector3 HalfSize() const;
|
||||||
|
|
||||||
/// Returns the largest sphere that can fit inside this AABB
|
/// Returns the largest sphere that can fit inside this AABB
|
||||||
/// This function computes the largest sphere that can fit inside this AABB.
|
/// This function computes the largest sphere that can fit inside this AABB.
|
||||||
Sphere MaximalContainedSphere() const;
|
Sphere MaximalContainedSphere() const;
|
||||||
|
|
||||||
|
/// Tests if this AABB is finite.
|
||||||
|
/** @return True if the member variables of this AABB are valid floats and do not contain NaNs or infs, and false otherwise.
|
||||||
|
@see IsDegenerate(), minPoint, maxPoint. */
|
||||||
bool IsFinite() const;
|
bool IsFinite() const;
|
||||||
|
|
||||||
|
/// @return The center point of this AABB.
|
||||||
Vector3 Centroid() const;
|
Vector3 Centroid() const;
|
||||||
|
|
||||||
|
/// Returns the side lengths of this AABB in x, y and z directions.
|
||||||
|
/** The returned vector is equal to the diagonal vector of this AABB, i.e. it spans from the
|
||||||
|
minimum corner of the AABB to the maximum corner of the AABB.
|
||||||
|
@see HalfSize(), Diagonal(). */
|
||||||
Vector3 Size() const;
|
Vector3 Size() const;
|
||||||
|
|
||||||
// Quickly returns an arbitrary point inside this AABB
|
// Quickly returns an arbitrary point inside this AABB
|
||||||
Vector3 AnyPointFast() const;
|
Vector3 AnyPointFast() const;
|
||||||
|
|
||||||
|
/// Generates a point inside this AABB.
|
||||||
|
/** @param x A normalized value between [0,1]. This specifies the point position along the world x axis.
|
||||||
|
@param y A normalized value between [0,1]. This specifies the point position along the world y axis.
|
||||||
|
@param z A normalized value between [0,1]. This specifies the point position along the world z axis.
|
||||||
|
@return A point inside this AABB at point specified by given parameters.
|
||||||
|
@see Edge(), CornerPoint(), PointOnEdge(), FaceCenterPoint(), FacePoint(). */
|
||||||
Vector3 PointInside(float x, float y, float z) const;
|
Vector3 PointInside(float x, float y, float z) const;
|
||||||
|
|
||||||
// Returns an edge of this AABB
|
// Returns an edge of this AABB
|
||||||
LineSegment Edge(int edgeIndex) const;
|
LineSegment Edge(int edgeIndex) const;
|
||||||
|
|
||||||
|
/// Returns a corner point of this AABB.
|
||||||
|
/** This function generates one of the eight corner points of this AABB.
|
||||||
|
@param cornerIndex The index of the corner point to generate, in the range [0, 7].
|
||||||
|
The points are returned in the order 0: ---, 1: --+, 2: -+-, 3: -++, 4: +--, 5: +-+, 6: ++-, 7: +++. (corresponding the XYZ axis directions).
|
||||||
|
@todo Draw which index generates which corner point.
|
||||||
|
@see PointInside(), Edge(), PointOnEdge(), FaceCenterPoint(), FacePoint(), GetCornerPoints(). */
|
||||||
Vector3 CornerPoint(int cornerIndex) const;
|
Vector3 CornerPoint(int cornerIndex) const;
|
||||||
|
|
||||||
|
/// Computes an extreme point of this AABB in the given direction.
|
||||||
|
/** An extreme point is a farthest point of this AABB in the given direction. Given a direction,
|
||||||
|
this point is not necessarily unique.
|
||||||
|
@param direction The direction vector of the direction to find the extreme point. This vector may
|
||||||
|
be unnormalized, but may not be null.
|
||||||
|
@return An extreme point of this AABB in the given direction. The returned point is always a
|
||||||
|
corner point of this AABB.
|
||||||
|
@see CornerPoint(). */
|
||||||
Vector3 ExtremePoint(const Vector3 &direction) const;
|
Vector3 ExtremePoint(const Vector3 &direction) const;
|
||||||
Vector3 ExtremePoint(const Vector3 &direction, float &projectionDistance) const;
|
Vector3 ExtremePoint(const Vector3 &direction, float &projectionDistance) const;
|
||||||
|
|
||||||
|
/// Returns a point on an edge of this AABB.
|
||||||
|
/** @param edgeIndex The index of the edge to generate a point to, in the range [0, 11]. @todo Document which index generates which one.
|
||||||
|
@param u A normalized value between [0,1]. This specifies the relative distance of the point along the edge.
|
||||||
|
@see PointInside(), CornerPoint(), CornerPoint(), FaceCenterPoint(), FacePoint(). */
|
||||||
Vector3 PointOnEdge(int edgeIndex, float u) const;
|
Vector3 PointOnEdge(int edgeIndex, float u) const;
|
||||||
|
|
||||||
|
/// Returns the point at the center of the given face of this AABB.
|
||||||
|
/** @param faceIndex The index of the AABB face to generate the point at. The valid range is [0, 5].
|
||||||
|
This index corresponds to the planes in the order (-X, +X, -Y, +Y, -Z, +Z).
|
||||||
|
@see PointInside(), CornerPoint(), PointOnEdge(), PointOnEdge(), FacePoint(). */
|
||||||
Vector3 FaceCenterPoint(int faceIndex) const;
|
Vector3 FaceCenterPoint(int faceIndex) const;
|
||||||
|
|
||||||
|
/// Generates a point at the surface of the given face of this AABB.
|
||||||
|
/** @param faceIndex The index of the AABB face to generate the point at. The valid range is [0, 5].
|
||||||
|
This index corresponds to the planes in the order (-X, +X, -Y, +Y, -Z, +Z).
|
||||||
|
@param u A normalized value between [0, 1].
|
||||||
|
@param v A normalized value between [0, 1].
|
||||||
|
@see PointInside(), CornerPoint(), PointOnEdge(), PointOnEdge(), FaceCenterPoint(). */
|
||||||
Vector3 FacePoint(int faceIndex, float u, float v) const;
|
Vector3 FacePoint(int faceIndex, float u, float v) const;
|
||||||
|
|
||||||
|
/// Returns the surface normal direction vector the given face points towards.
|
||||||
|
/** @param faceIndex The index of the AABB face to generate the point at. The valid range is [0, 5].
|
||||||
|
This index corresponds to the planes in the order (-X, +X, -Y, +Y, -Z, +Z).
|
||||||
|
@see FacePoint(), FacePlane(). */
|
||||||
Vector3 FaceNormal(int faceIndex) const;
|
Vector3 FaceNormal(int faceIndex) const;
|
||||||
|
|
||||||
|
/// Computes the plane equation of the given face of this AABB.
|
||||||
|
/** @param faceIndex The index of the AABB face. The valid range is [0, 5].
|
||||||
|
This index corresponds to the planes in the order (-X, +X, -Y, +Y, -Z, +Z).
|
||||||
|
@return The plane equation the specified face lies on. The normal of this plane points outwards from this AABB.
|
||||||
|
@see FacePoint(), FaceNormal(), GetFacePlanes(). */
|
||||||
Plane FacePlane(int faceIndex) const;
|
Plane FacePlane(int faceIndex) const;
|
||||||
|
|
||||||
|
|
||||||
void ProjectToAxis(const Vector3 &direction, float &outMin, float &outMax) const;
|
void ProjectToAxis(const Vector3 &direction, float &outMin, float &outMax) const;
|
||||||
|
|
||||||
|
/// Generates an AABB that encloses the given point set.
|
||||||
|
/** This function finds the smallest AABB that contains the given set of points.
|
||||||
|
@param pointArray A pointer to an array of points to enclose inside an AABB.
|
||||||
|
@param numPoints The number of elements in the pointArray list.
|
||||||
|
@see SetFrom(). */
|
||||||
static AABB MinimalEnclosingAABB(const Vector3 *pointArray, int numPoints);
|
static AABB MinimalEnclosingAABB(const Vector3 *pointArray, int numPoints);
|
||||||
float GetVolume() const;
|
AABB MinimalEnclosingAABB() const { return *this;}
|
||||||
float GetSurfaceArea() const;
|
/// Computes the volume of this AABB.
|
||||||
|
/** @see SurfaceArea(), IsDegenerate(). */
|
||||||
|
float Volume() const;
|
||||||
|
/// Computes the surface area of the faces of this AABB.
|
||||||
|
/** @see Volume(). */
|
||||||
|
float SurfaceArea() const;
|
||||||
Vector3 GetClosestPoint(const Vector3& point) const;
|
Vector3 GetClosestPoint(const Vector3& point) const;
|
||||||
|
|
||||||
void Translate(const Vector3& offset);
|
void Translate(const Vector3& offset);
|
||||||
@@ -95,9 +182,23 @@ namespace J3ML::Geometry
|
|||||||
AABB TransformAABB(const Matrix3x3& transform);
|
AABB TransformAABB(const Matrix3x3& transform);
|
||||||
AABB TransformAABB(const Matrix4x4& transform);
|
AABB TransformAABB(const Matrix4x4& transform);
|
||||||
AABB TransformAABB(const Quaternion& transform);
|
AABB TransformAABB(const Quaternion& transform);
|
||||||
|
/// Applies a transformation to this AABB and returns the resulting OBB.
|
||||||
|
/** Transforming an AABB produces an oriented bounding box. This set of functions does not apply the transformation
|
||||||
|
to this object itself, but instead returns the OBB that results in the transformation.
|
||||||
|
@param transform The transformation to apply to this AABB. This function assumes that this
|
||||||
|
transformation does not contain shear, nonuniform scaling or perspective properties, i.e. that the fourth
|
||||||
|
row of the float4x4 is [0 0 0 1].
|
||||||
|
@see Translate(), Scale(), TransformAsAABB(), classes float3x3, float3x4, float4x4, Quat. */
|
||||||
OBB Transform(const Matrix3x3& transform) const;
|
OBB Transform(const Matrix3x3& transform) const;
|
||||||
OBB Transform(const Matrix4x4& transform) const;
|
OBB Transform(const Matrix4x4& transform) const;
|
||||||
OBB Transform(const Quaternion& transform) const;
|
OBB Transform(const Quaternion& transform) const;
|
||||||
|
|
||||||
|
/// Tests if the given object is fully contained inside this AABB.
|
||||||
|
/** This function returns true if the given object lies inside this AABB, and false otherwise.
|
||||||
|
@note The comparison is performed using less-or-equal, so the faces of this AABB 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(). */
|
||||||
bool Contains(const Vector3& point) const;
|
bool Contains(const Vector3& point) const;
|
||||||
bool Contains(const Vector3& aabbMinPoint, const Vector3& aabbMaxPoint) const;
|
bool Contains(const Vector3& aabbMinPoint, const Vector3& aabbMaxPoint) const;
|
||||||
bool Contains(const LineSegment& lineSegment) const;
|
bool Contains(const LineSegment& lineSegment) const;
|
||||||
@@ -109,27 +210,93 @@ namespace J3ML::Geometry
|
|||||||
bool Contains(const Frustum& frustum) const;
|
bool Contains(const Frustum& frustum) const;
|
||||||
bool Contains(const Polyhedron& polyhedron) const;
|
bool Contains(const Polyhedron& polyhedron) const;
|
||||||
bool Contains(const Capsule& capsule) const;
|
bool Contains(const Capsule& capsule) const;
|
||||||
// Tests whether this AABB and the given object intersect.
|
|
||||||
|
/// Tests whether this AABB 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 AABB,
|
||||||
|
or this AABB is contained inside a Sphere, etc.)
|
||||||
|
@param ray The first parameter of this function specifies the other object to test against.
|
||||||
|
@param dNear [out] If specified, receives the parametric distance along the line denoting where the
|
||||||
|
line entered this AABB.
|
||||||
|
@param dFar [out] If specified, receives the parametric distance along the line denoting where the
|
||||||
|
line exited this AABB.
|
||||||
|
@see Contains(), Distance(), ClosestPoint().
|
||||||
|
@note If you do not need the intersection intervals, you should call the functions without these
|
||||||
|
parameters in the function signature for optimal performance.
|
||||||
|
@todo Add Intersects(Circle/Disc). */
|
||||||
bool Intersects(const Ray& ray, float dNear, float dFar) const;
|
bool Intersects(const Ray& ray, float dNear, float dFar) const;
|
||||||
bool Intersects(const Capsule& capsule) const;
|
bool Intersects(const Capsule& capsule) const;
|
||||||
bool Intersects(const Triangle& triangle) const;
|
bool Intersects(const Triangle& triangle) const;
|
||||||
bool Intersects(const Polygon& polygon) const;
|
bool Intersects(const Polygon& polygon) const;
|
||||||
bool Intersects(const Frustum& frustum) const;
|
bool Intersects(const Frustum& frustum) const;
|
||||||
bool Intersects(const Polyhedron& polyhedron) const;
|
bool Intersects(const Polyhedron& polyhedron) const;
|
||||||
|
|
||||||
|
/** For reference documentation on the Sphere-AABB intersection test, see Christer Ericson's Real-Time Collision Detection, p. 165. [groupSyntax]
|
||||||
|
@param sphere The first parameter of this function specifies the other object to test against.
|
||||||
|
@param closestPointOnAABB [out] Returns the closest point on this AABB to the given sphere. This pointer
|
||||||
|
may be null. */
|
||||||
|
bool Intersects(const Sphere &sphere, Vector3 *closestPointOnAABB = 0) const;
|
||||||
|
|
||||||
|
/// Generates an unindexed triangle mesh representation of this AABB.
|
||||||
|
/** @param numFacesX The number of faces to generate along the X axis. This value must be >= 1.
|
||||||
|
@param numFacesY The number of faces to generate along the Y axis. This value must be >= 1.
|
||||||
|
@param numFacesZ The number of faces to generate along the Z axis. This value must be >= 1.
|
||||||
|
@param outPos [out] An array of size numVertices which will receive a triangle list
|
||||||
|
of vertex positions. Cannot be null.
|
||||||
|
@param outNormal [out] An array of size numVertices which will receive vertex normals.
|
||||||
|
If this parameter is null, vertex normals are not returned.
|
||||||
|
@param outUV [out] An array of size numVertices which will receive vertex UV coordinates.
|
||||||
|
If this parameter is null, a UV mapping is not generated.
|
||||||
|
@param ccwIsFrontFacing If true, then the front-facing direction of the faces will be the sides
|
||||||
|
with counterclockwise winding order. Otherwise, the faces are generated in clockwise winding order.
|
||||||
|
The number of vertices that outPos, outNormal and outUV must be able to contain is
|
||||||
|
(x*y + x*z + y*z)*2*6. If x==y==z==1, then a total of 36 vertices are required. Call
|
||||||
|
NumVerticesInTriangulation to obtain this value.
|
||||||
|
@see ToPolyhedron(), ToEdgeList(), NumVerticesInTriangulation(). */
|
||||||
TriangleMesh Triangulate(int numFacesX, int numFacesY, int numFacesZ, bool ccwIsFrontFacing) const;
|
TriangleMesh Triangulate(int numFacesX, int numFacesY, int numFacesZ, bool ccwIsFrontFacing) const;
|
||||||
|
|
||||||
|
/// Returns the number of vertices that the Triangulate() function will output with the given subdivision parameters.
|
||||||
|
/** @see Triangulate(). */
|
||||||
|
static int NumVerticesInTriangulation(int numFacesX, int numFacesY, int numFacesZ)
|
||||||
|
{
|
||||||
|
return (numFacesX*numFacesY + numFacesX*numFacesZ + numFacesY*numFacesZ)*2*6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the number of vertices that the ToEdgeList() function will output.
|
||||||
|
/** @see ToEdgeList(). */
|
||||||
|
static int NumVerticesInEdgeList()
|
||||||
|
{
|
||||||
|
return 4*3*2;
|
||||||
|
}
|
||||||
|
|
||||||
/// Finds the set intersection of this and the given AABB.
|
/// Finds the set intersection of this and the given AABB.
|
||||||
/** @return This function returns the AABB that is contained in both this and the given AABB.
|
/** @return This function returns the AABB that is contained in both this and the given AABB.
|
||||||
@todo Add Intersection(OBB/Polyhedron). */
|
@todo Add Intersection(OBB/Polyhedron). */
|
||||||
AABB Intersection(const AABB& rhs) const;
|
AABB Intersection(const AABB& rhs) const;
|
||||||
|
|
||||||
|
|
||||||
|
/// Sets this AABB to enclose the given set of points.
|
||||||
|
/** @param pointArray A pointer to an array of points to enclose inside an AABB.
|
||||||
|
@param numPoints The number of elements in the pointArray list.
|
||||||
|
@see MinimalEnclosingAABB(). */
|
||||||
void SetFrom(const Vector3 *pVector3, int i);
|
void SetFrom(const Vector3 *pVector3, int i);
|
||||||
|
|
||||||
|
/// Sets this AABB by specifying its center and size.
|
||||||
|
/** @param center The center point of this AABB.
|
||||||
|
@param size A vector that specifies the size of this AABB in x, y and z directions.
|
||||||
|
@see SetFrom(), FromCenterAndSize(). */
|
||||||
void SetFromCenterAndSize(const Vector3 ¢er, const Vector3 &size);
|
void SetFromCenterAndSize(const Vector3 ¢er, const Vector3 &size);
|
||||||
|
|
||||||
|
/// Sets this AABB to enclose the given OBB.
|
||||||
|
/** This function computes the minimal axis-aligned bounding box for the given oriented bounding box. If the orientation
|
||||||
|
of the OBB is not aligned with the world axes, this conversion is not exact and loosens the volume of the bounding box.
|
||||||
|
@param obb The oriented bounding box to convert into this AABB.
|
||||||
|
@todo Implement SetFrom(Polyhedron).
|
||||||
|
@see SetCenter(), class OBB. */
|
||||||
void SetFrom(const OBB &obb);
|
void SetFrom(const OBB &obb);
|
||||||
|
|
||||||
|
/// Sets this AABB to enclose the given sphere.
|
||||||
|
/** This function computes the smallest possible AABB (in terms of volume) that contains the given sphere, and stores the result in this structure. */
|
||||||
void SetFrom(const Sphere &s);
|
void SetFrom(const Sphere &s);
|
||||||
|
|
||||||
Vector3 GetRandomPointInside(RNG& rng) const;
|
Vector3 GetRandomPointInside(RNG& rng) const;
|
||||||
@@ -137,15 +304,28 @@ namespace J3ML::Geometry
|
|||||||
Vector3 GetRandomPointOnEdge(RNG& rng) const;
|
Vector3 GetRandomPointOnEdge(RNG& rng) const;
|
||||||
Vector3 GetRandomCornerPoint(RNG& rng) const;
|
Vector3 GetRandomCornerPoint(RNG& rng) const;
|
||||||
|
|
||||||
|
/// Sets this structure to a degenerate AABB that does not have any volume.
|
||||||
|
/** This function is useful for initializing the AABB to "null" before a loop of calls to Enclose(),
|
||||||
|
which incrementally expands the bounds of this AABB to enclose the given objects.
|
||||||
|
@see Enclose(). */
|
||||||
void SetNegativeInfinity();
|
void SetNegativeInfinity();
|
||||||
|
|
||||||
|
/// Expands this AABB to enclose the given object.
|
||||||
|
/** This function computes an AABB that encloses both this AABB and the specified object, and stores the resulting
|
||||||
|
AABB into this.
|
||||||
|
@note The generated AABB is not necessarily the optimal enclosing AABB for this AABB and the given object. */
|
||||||
void Enclose(const Vector3 &point);
|
void Enclose(const Vector3 &point);
|
||||||
|
|
||||||
void Enclose(const Vector3 &aabbMinPt, const Vector3 &aabbMaxPt);
|
void Enclose(const Vector3 &aabbMinPt, const Vector3 &aabbMaxPt);
|
||||||
|
|
||||||
void Enclose(const LineSegment &lineSegment);
|
void Enclose(const LineSegment &lineSegment);
|
||||||
|
|
||||||
void Enclose(const OBB &obb);
|
void Enclose(const OBB &obb);
|
||||||
|
void Enclose(const Sphere &sphere);
|
||||||
|
void Enclose(const Triangle &triangle);
|
||||||
|
void Enclose(const Capsule &capsule);
|
||||||
|
void Enclose(const Frustum &frustum);
|
||||||
|
void Enclose(const Polygon &polygon);
|
||||||
|
void Enclose(const Polyhedron &polyhedron);
|
||||||
|
void Enclose(const Vector3 *pointArray, int numPoints);
|
||||||
|
|
||||||
|
|
||||||
bool TestAxis(const Vector3& axis, const Vector3& v0, const Vector3& v1, const Vector3& v2) const;
|
bool TestAxis(const Vector3& axis, const Vector3& v0, const Vector3& v1, const Vector3& v2) const;
|
||||||
|
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "LineSegment.h"
|
#include "LineSegment.h"
|
||||||
#include "Shape.h"
|
#include "Shape.h"
|
||||||
#include <J3ML/LinearAlgebra/Vector3.h>
|
#include <J3ML/LinearAlgebra.h>
|
||||||
#include <J3ML/Geometry/Common.h>
|
#include <J3ML/Geometry/Common.h>
|
||||||
|
|
||||||
namespace J3ML::Geometry
|
namespace J3ML::Geometry
|
||||||
@@ -16,7 +16,7 @@ namespace J3ML::Geometry
|
|||||||
b = std::move(temp);
|
b = std::move(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace LinearAlgebra;
|
/// A 3D cylinder with spherical ends.
|
||||||
class Capsule : public Shape
|
class Capsule : public Shape
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -25,13 +25,39 @@ namespace J3ML::Geometry
|
|||||||
// Specifies the radius of this capsule
|
// Specifies the radius of this capsule
|
||||||
float r;
|
float r;
|
||||||
public:
|
public:
|
||||||
|
/// The default constructor does not initialize any members of this class.
|
||||||
|
/** This means that the values of the members l and r are both undefined after creating a new capsule using
|
||||||
|
this default constructor. Remember to assign to them before use.
|
||||||
|
@see l, r. */
|
||||||
Capsule();
|
Capsule();
|
||||||
|
/// Constructs a new capsule by explicitly specifying the member variables.
|
||||||
|
/** @param endPoints Specifies the line segment of the capsule.
|
||||||
|
@param radius Specifies the size of this capsule.
|
||||||
|
@see l, r. */
|
||||||
Capsule(const LineSegment& endPoints, float radius);
|
Capsule(const LineSegment& endPoints, float radius);
|
||||||
|
/// Constructs a new capsule by explicitly specifying the member variables.
|
||||||
|
/** This constructor is equivalent to calling Capsule(LineSegment(bottomPoint, topPoint), radius), but provided
|
||||||
|
here for conveniency.
|
||||||
|
@see l, r. */
|
||||||
Capsule(const Vector3& bottomPt, const Vector3& topPt, float radius);
|
Capsule(const Vector3& bottomPt, const Vector3& topPt, float radius);
|
||||||
|
|
||||||
/// Quickly returns an arbitrary point inside this Capsule. Used in GJK intersection test.
|
/// Quickly returns an arbitrary point inside this Capsule. Used in GJK intersection test.
|
||||||
inline Vector3 AnyPointFast() const { return l.A; }
|
inline Vector3 AnyPointFast() const { return l.A; }
|
||||||
|
|
||||||
|
/// Generates a point that perhaps lies inside this capsule.
|
||||||
|
/** @param height A normalized value between [0,1]. This specifies the point position along the height line of this capsule.
|
||||||
|
@param x A normalized value between [0,1]. This specifies the x coordinate on the plane of the circle cross-section specified by l.
|
||||||
|
@param y A normalized value between [0,1]. This specifies the y coordinate on the plane of the circle cross-section specified by l.
|
||||||
|
@note This function will generate points uniformly, but they do not necessarily lie inside the capsule.
|
||||||
|
@see PointInside(). */
|
||||||
|
Vector3 UniformPointPerhapsInside(float height, float x, float y) const;
|
||||||
|
|
||||||
|
/// Returns the Sphere defining the 'bottom' section of this Capsule (corresponding to the endpoint l.a)
|
||||||
|
Sphere SphereA() const;
|
||||||
|
|
||||||
|
/// Returns the Sphere defining the 'top' section of this Capsule (corresponding to the endpoint l.b)
|
||||||
|
Sphere SphereB() const;
|
||||||
|
|
||||||
/// Computes the extreme point of this Capsule in the given direction.
|
/// Computes the extreme point of this Capsule in the given direction.
|
||||||
/** An extreme point is a farthest point of this Capsule in the given direction. Given a direction,
|
/** An extreme point is a farthest point of this Capsule in the given direction. Given a direction,
|
||||||
this point is not necessarily unique.
|
this point is not necessarily unique.
|
||||||
@@ -40,40 +66,135 @@ namespace J3ML::Geometry
|
|||||||
@return The extreme point of this Capsule in the given direction. */
|
@return The extreme point of this Capsule in the given direction. */
|
||||||
Vector3 ExtremePoint(const Vector3 &direction) const;
|
Vector3 ExtremePoint(const Vector3 &direction) const;
|
||||||
Vector3 ExtremePoint(const Vector3 &direction, float &projectionDistance) const;
|
Vector3 ExtremePoint(const Vector3 &direction, float &projectionDistance) const;
|
||||||
|
/// Tests if this Capsule is degenerate.
|
||||||
|
/** @return True if this Capsule does not span a strictly positive volume. */
|
||||||
bool IsDegenerate() const;
|
bool IsDegenerate() const;
|
||||||
|
/// Computes the total height of this capsule, i.e. LineLength() + Diameter().
|
||||||
|
/** <img src="CapsuleFunctions.png" />
|
||||||
|
@see LineLength(). */
|
||||||
float Height() const;
|
float Height() const;
|
||||||
|
/// Computes the diameter of this capsule.
|
||||||
float Diameter() const;
|
float Diameter() const;
|
||||||
|
/// Returns the bottom-most point of this Capsule.
|
||||||
|
/** <img src="CapsuleFunctions.png" />
|
||||||
|
@note The bottom-most point is only a naming convention, and does not correspond to the bottom-most point along any world axis. The returned
|
||||||
|
point is simply the point at the far end of this Capsule where the point l.a resides.
|
||||||
|
@note The bottom-most point of the capsule is different than the point l.a. The returned point is the point at the very far
|
||||||
|
edge of this capsule, and does not lie on the internal line. See the attached diagram.
|
||||||
|
@see Top(), l. */
|
||||||
Vector3 Bottom() const;
|
Vector3 Bottom() const;
|
||||||
|
/// Returns the center point of this Capsule.
|
||||||
|
/** <img src="doc/static/docs/CapsuleFunctions.png" />
|
||||||
|
@return The point (l.a + l.b) / 2. This point is the center of mass for this capsule.
|
||||||
|
@see l, Bottom(), Top(). */
|
||||||
Vector3 Center() const;
|
Vector3 Center() const;
|
||||||
Vector3 Centroid() const;
|
Vector3 Centroid() const; ///< [similarOverload: Center]
|
||||||
|
|
||||||
|
/// Returns the direction from the bottommost point towards the topmost point of this Capsule.
|
||||||
|
/** <img src="CapsuleFunctions.png" />
|
||||||
|
@return The normalized direction vector from l.a to l.b.
|
||||||
|
@see l. */
|
||||||
|
Vector3 UpDirection() const;
|
||||||
|
|
||||||
|
/// Computes the volume of this Capsule.
|
||||||
|
/** @return pi * r^2 * |b-a| + 4 * pi * r^2 / 3.
|
||||||
|
@see SurfaceArea(). */
|
||||||
|
float Volume() const;
|
||||||
|
|
||||||
|
/// Computes the surface area of this Capsule.
|
||||||
|
/** @return 2 * pi * r * |b-a| + 4 * pi * r^2.
|
||||||
|
@see Volume(). */
|
||||||
|
float SurfaceArea() const;
|
||||||
|
|
||||||
|
/// Returns the cross-section circle at the given height of this Capsule.
|
||||||
|
/** <img src="CapsuleFunctions.png" />
|
||||||
|
@param l A normalized parameter between [0,1]. l == 0 returns a degenerate circle of radius 0 at the bottom of this Capsule, and l == 1
|
||||||
|
will return a degenerate circle of radius 0 at the top of this Capsule. */
|
||||||
|
//Circle CrossSection(float l) const;
|
||||||
|
|
||||||
Vector3 ExtremePoint(const Vector3& direction);
|
Vector3 ExtremePoint(const Vector3& direction);
|
||||||
|
|
||||||
|
/// Returns the smallest AABB that encloses this capsule.
|
||||||
|
/** @see MinimalEnclosingOBB(). */
|
||||||
AABB MinimalEnclosingAABB() const;
|
AABB MinimalEnclosingAABB() const;
|
||||||
|
|
||||||
|
/// Returns the smallest OBB that encloses this capsule.
|
||||||
|
/** @see MinimalEnclosingAABB(). */
|
||||||
|
OBB MinimalEnclosingOBB() const;
|
||||||
|
|
||||||
|
/// Projects this Capsule onto the given 1D axis direction vector.
|
||||||
|
/** This function collapses this Capsule 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 ProjectToAxis(const Vector3 &direction, float &outMin, float &outMax) const;
|
||||||
|
|
||||||
|
/// Returns the topmost point of this Capsule.
|
||||||
|
/** <img src="CapsuleFunctions.png" />
|
||||||
|
@note The topmost point is only a naming convention, and does not correspond to the topmost point along any world axis. The returned
|
||||||
|
point is simply the point at the far end of this Capsule where the point l.b resides.
|
||||||
|
@note The topmost point of the capsule is different than the point l.b. The returned point is the point at the very far
|
||||||
|
edge of this capsule, and does not lie on the internal line. See the attached diagram.
|
||||||
|
@see Bottom(), l. */
|
||||||
|
Vector3 Top() const;
|
||||||
|
|
||||||
|
/// Applies a transformation to this capsule.
|
||||||
|
/** @param transform The transformation to apply to this capsule. This transformation must be
|
||||||
|
affine, and must contain an orthogonal set of column vectors (may not contain shear or projection).
|
||||||
|
The transformation can only contain uniform scale, and may not contain mirroring.
|
||||||
|
@see Translate(), Scale(), classes Matrix3x3, Matrix4x4, Quaternion. */
|
||||||
|
void Transform(const Matrix3x3 &transform);
|
||||||
|
void Transform(const Matrix4x4 &transform);
|
||||||
|
void Transform(const Quaternion &transform);
|
||||||
|
|
||||||
|
/// Computes the closest point inside this capsule to the given point.
|
||||||
|
/** If the target point lies inside this capsule, then that point is returned.
|
||||||
|
@see Distance(), Contains(), Intersects().
|
||||||
|
@todo Add ClosestPoint(Line/Ray/LineSegment/Plane/Triangle/Polygon/Circle/Disc/AABB/OBB/Sphere/Capsule/Frustum/Polyhedron). */
|
||||||
|
Vector3 ClosestPoint(const Vector3 &targetPoint) const;
|
||||||
|
|
||||||
|
|
||||||
|
/// Computes the distance between this capsule 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 Distance(Triangle/Polygon/Circle/Disc/Capsule).
|
||||||
|
@see Contains(), Intersects(), ClosestPoint(). */
|
||||||
|
float Distance(const Vector3 &point) const;
|
||||||
|
float Distance(const Plane &plane) const;
|
||||||
|
float Distance(const Sphere &sphere) const;
|
||||||
|
float Distance(const Ray &ray) const;
|
||||||
|
float Distance(const Line &line) const;
|
||||||
|
float Distance(const LineSegment &lineSegment) const;
|
||||||
|
float Distance(const Capsule &capsule) const;
|
||||||
|
|
||||||
|
/// Tests if the given object is fully contained inside this capsule.
|
||||||
|
/** This function returns true if the given object lies inside this capsule, and false otherwise.
|
||||||
|
@note The comparison is performed using less-or-equal, so the surface of this capsule 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(). */
|
||||||
|
bool Contains(const Vector3 &point) const;
|
||||||
|
bool Contains(const LineSegment &lineSegment) const;
|
||||||
|
bool Contains(const Triangle &triangle) const;
|
||||||
|
bool Contains(const Polygon &polygon) const;
|
||||||
|
bool Contains(const AABB &aabb) const;
|
||||||
|
bool Contains(const OBB &obb) const;
|
||||||
|
bool Contains(const Frustum &frustum) const;
|
||||||
|
bool Contains(const Polyhedron &polyhedron) const;
|
||||||
|
|
||||||
bool Intersects(const Plane &plane) const;
|
bool Intersects(const Plane &plane) const;
|
||||||
|
|
||||||
bool Intersects(const Ray &ray) const;
|
bool Intersects(const Ray &ray) const;
|
||||||
|
|
||||||
bool Intersects(const Line &line) const;
|
bool Intersects(const Line &line) const;
|
||||||
|
|
||||||
bool Intersects(const LineSegment &lineSegment) const;
|
bool Intersects(const LineSegment &lineSegment) const;
|
||||||
|
|
||||||
bool Intersects(const AABB &aabb) const;
|
bool Intersects(const AABB &aabb) const;
|
||||||
|
|
||||||
bool Intersects(const OBB &obb) const;
|
bool Intersects(const OBB &obb) const;
|
||||||
|
|
||||||
bool Intersects(const Sphere &sphere) const;
|
bool Intersects(const Sphere &sphere) const;
|
||||||
|
|
||||||
bool Intersects(const Capsule &capsule) const;
|
bool Intersects(const Capsule &capsule) const;
|
||||||
|
|
||||||
bool Intersects(const Triangle &triangle) const;
|
bool Intersects(const Triangle &triangle) const;
|
||||||
|
|
||||||
bool Intersects(const Polygon &polygon) const;
|
bool Intersects(const Polygon &polygon) const;
|
||||||
|
|
||||||
bool Intersects(const Frustum &frustum) const;
|
bool Intersects(const Frustum &frustum) const;
|
||||||
|
|
||||||
bool Intersects(const Polyhedron &polyhedron) const;
|
bool Intersects(const Polyhedron &polyhedron) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
@@ -51,7 +51,7 @@ namespace J3ML::Geometry
|
|||||||
D3D,
|
D3D,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The handedness rule in J3ML bundles together two different conventions related to the camera:
|
/// @brief The handedness rule in J3ML bundles together two different conventions related to the camera:
|
||||||
/// * the chirality of the world and view spaces,
|
/// * the chirality of the world and view spaces,
|
||||||
/// * the fixed local front direction of the Frustum.
|
/// * 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()
|
/// @note The world and view spaces are always assumed to the same chirality, meaning that Frustum::ViewMatrix()
|
||||||
@@ -74,10 +74,12 @@ namespace J3ML::Geometry
|
|||||||
Right
|
Right
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Represents either an orthographic or a perspective viewing frustum.
|
/// @brief Represents either an orthographic or a perspective viewing frustum.
|
||||||
|
/// @see FrustumType
|
||||||
|
/// @see FrustumProjectiveSpace
|
||||||
|
/// @see FrustumHandedness
|
||||||
class Frustum : public Shape {
|
class Frustum : public Shape {
|
||||||
public: /// Members
|
public: // Members
|
||||||
|
|
||||||
|
|
||||||
/// Specifies whether this frustum is a perspective or an orthographic frustum.
|
/// Specifies whether this frustum is a perspective or an orthographic frustum.
|
||||||
FrustumType type;
|
FrustumType type;
|
||||||
@@ -138,85 +140,228 @@ namespace J3ML::Geometry
|
|||||||
Matrix4x4 worldMatrix;
|
Matrix4x4 worldMatrix;
|
||||||
Matrix4x4 projectionMatrix;
|
Matrix4x4 projectionMatrix;
|
||||||
Matrix4x4 viewProjectionMatrix;
|
Matrix4x4 viewProjectionMatrix;
|
||||||
public: /// Methods
|
public:
|
||||||
Frustum()
|
|
||||||
: type(FrustumType::Invalid),
|
|
||||||
pos(Vector3::NaN),
|
|
||||||
front(Vector3::NaN),
|
|
||||||
up(Vector3::NaN),
|
|
||||||
nearPlaneDistance(NAN),
|
|
||||||
farPlaneDistance(NAN),
|
|
||||||
worldMatrix(Matrix4x4::NaN),
|
|
||||||
viewProjectionMatrix(Matrix4x4::NaN)
|
|
||||||
{
|
|
||||||
// For conveniency, allow automatic initialization of the graphics API and handedness in use.
|
|
||||||
// If neither of the #defines are set, user must specify per-instance.
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/// 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();
|
||||||
|
|
||||||
/// Quickly returns an arbitrary point inside this Frustum. Used in GJK intersection test.
|
/// Quickly returns an arbitrary point inside this Frustum. Used in GJK intersection test.
|
||||||
inline Vector3 AnyPointFast() const { return CornerPoint(0); }
|
inline Vector3 AnyPointFast() const { return CornerPoint(0); }
|
||||||
|
|
||||||
static Frustum CreateFrustumFromCamera(const CoordinateFrame& cam, float aspect, float fovY, float zNear, float zFar);
|
static Frustum CreateFrustumFromCamera(const CoordinateFrame& cam, float aspect, float fovY, float zNear, float zFar);
|
||||||
|
/// 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(). */
|
||||||
AABB MinimalEnclosingAABB() const;
|
AABB MinimalEnclosingAABB() 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(). */
|
||||||
OBB MinimalEnclosingOBB() const;
|
OBB MinimalEnclosingOBB() 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);
|
void SetKind(FrustumProjectiveSpace projectiveSpace, FrustumHandedness handedness);
|
||||||
|
/// Sets the depth clip distances of this Frustum.
|
||||||
|
/** @param nearPlaneDistance The z distance from the eye point to the position of the Frustum near clip plane. Always pass a positive value here.
|
||||||
|
@param farPlaneDistance 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 nearPlaneDistance, float farPlaneDistance);
|
void SetViewPlaneDistances(float nearPlaneDistance, float farPlaneDistance);
|
||||||
|
/// 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);
|
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);
|
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);
|
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);
|
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 horizontalFov, float verticalFov);
|
void SetPerspective(float horizontalFov, float verticalFov);
|
||||||
|
/// 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 orthographicWidth, float orthographicHeight);
|
void SetOrthographic(float orthographicWidth, float orthographicHeight);
|
||||||
|
/// Returns the handedness of the projection formula used by this Frustum.
|
||||||
|
/** @see SetKind(), FrustumHandedness. */
|
||||||
FrustumHandedness Handedness() const { return handedness; }
|
FrustumHandedness Handedness() const { return handedness; }
|
||||||
|
/// Returns the type of the projection formula used by this Frustum.
|
||||||
|
/** @see SetPerspective(), SetOrthographic(), FrustumType. */
|
||||||
FrustumType Type() const { return type; }
|
FrustumType Type() const { return type; }
|
||||||
|
/// Returns the convention of the post-projective space used by this Frustum.
|
||||||
|
/** @see SetKind(), FrustumProjectiveSpace. */
|
||||||
FrustumProjectiveSpace ProjectiveSpace() const { return projectiveSpace;}
|
FrustumProjectiveSpace ProjectiveSpace() const { return projectiveSpace;}
|
||||||
|
/// Returns the world-space position of this Frustum.
|
||||||
|
/** @see SetPos(), Front(), Up(). */
|
||||||
const Vector3 &Pos() const {return pos;}
|
const Vector3 &Pos() const {return pos;}
|
||||||
|
/// Returns the world-space camera look-at direction of this Frustum.
|
||||||
|
/** @see Pos(), SetFront(), Up(). */
|
||||||
const Vector3 &Front() const { return front; }
|
const Vector3 &Front() const { return front; }
|
||||||
|
/// Returns the world-space camera up direction of this Frustum.
|
||||||
|
/** @see Pos(), Front(), SetUp(). */
|
||||||
const Vector3 &Up() const { return up; }
|
const Vector3 &Up() const { return up; }
|
||||||
|
/// Returns the distance from the Frustum eye to the near clip plane.
|
||||||
|
/** @see SetViewPlaneDistances(), FarPlaneDistance(). */
|
||||||
float NearPlaneDistance() const { return nearPlaneDistance; }
|
float NearPlaneDistance() const { return nearPlaneDistance; }
|
||||||
|
/// Returns the distance from the Frustum eye to the far clip plane.
|
||||||
|
/** @see SetViewPlaneDistances(), NearPlaneDistance(). */
|
||||||
float FarPlaneDistance() const { return farPlaneDistance;}
|
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(). */
|
||||||
float HorizontalFov() const { return horizontalFov;}
|
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(). */
|
||||||
float VerticalFov() const { return verticalFov;}
|
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(). */
|
||||||
float OrthographicWidth() const { return orthographicWidth; }
|
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(). */
|
||||||
float OrthograhpicHeight() const { return orthographicHeight; }
|
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. */
|
||||||
int NumEdges() const { return 12; }
|
int NumEdges() const { 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. */
|
||||||
float AspectRatio() const;
|
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 horizontalFov, float aspectRatio);
|
void SetHorizontalFovAndAspectRatio(float horizontalFov, 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 verticalFov, float aspectRatio);
|
||||||
|
|
||||||
Vector3 CornerPoint(int cornerIndex) const;
|
Vector3 CornerPoint(int cornerIndex) const;
|
||||||
|
|
||||||
Vector3 NearPlanePos(float x, float y) const;
|
Vector3 NearPlanePos(float x, float y) const;
|
||||||
Vector3 FarPlanePos(float x, float y) const;
|
Vector3 FarPlanePos(float x, float y) const;
|
||||||
|
|
||||||
Vector3 WorldRight() 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.
|
||||||
if (handedness == FrustumHandedness::Right)
|
@see pos, front. */
|
||||||
return Vector3::Cross(front, up);
|
Vector3 WorldRight() const;
|
||||||
else
|
|
||||||
return Vector3::Cross(up, front);
|
|
||||||
}
|
|
||||||
|
|
||||||
Plane TopPlane() const;
|
Plane TopPlane() const; ///< [similarOverload: LeftPlane] [hideIndex]
|
||||||
Plane BottomPlane() const;
|
Plane BottomPlane() const; ///< [similarOverload: LeftPlane] [hideIndex]
|
||||||
Plane RightPlane() const;
|
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(). */
|
||||||
Plane LeftPlane() const;
|
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(). */
|
||||||
Plane FarPlane() const;
|
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(). */
|
||||||
Plane NearPlane() const;
|
Plane NearPlane() const;
|
||||||
|
/// Computes the width of the near plane quad in world space units.
|
||||||
|
/** @see NearPlaneHeight(). */
|
||||||
float NearPlaneWidth() const;
|
float NearPlaneWidth() const;
|
||||||
|
/// Computes the height of the near plane quad in world space units.
|
||||||
|
/** @see NearPlaneHeight(). */
|
||||||
float NearPlaneHeight() const;
|
float NearPlaneHeight() 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);
|
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 Matrix3x3& transform);
|
||||||
void Transform(const Matrix4x4& transform);
|
void Transform(const Matrix4x4& transform);
|
||||||
void Transform(const Quaternion& 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(). */
|
||||||
Polyhedron ToPolyhedron() const;
|
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(). */
|
||||||
|
//PBVolume<6> ToPBVolume() 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(). */
|
||||||
|
bool Contains(const Vector3 &point) const;
|
||||||
|
bool Contains(const LineSegment &lineSegment) const;
|
||||||
|
bool Contains(const Triangle &triangle) const;
|
||||||
|
bool Contains(const Polygon &polygon) const;
|
||||||
|
bool Contains(const AABB &aabb) const;
|
||||||
|
bool Contains(const OBB &obb) const;
|
||||||
|
bool Contains(const Frustum &frustum) const;
|
||||||
|
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(). */
|
||||||
|
float Distance(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). */
|
||||||
bool Intersects(const Ray& ray) const;
|
bool Intersects(const Ray& ray) const;
|
||||||
//bool Intersects(const Line& line) const;
|
//bool Intersects(const Line& line) const;
|
||||||
bool Intersects(const LineSegment& lineSegment) const;
|
bool Intersects(const LineSegment& lineSegment) const;
|
||||||
@@ -229,7 +374,13 @@ namespace J3ML::Geometry
|
|||||||
bool Intersects(const Capsule& obb) const;
|
bool Intersects(const Capsule& obb) const;
|
||||||
bool Intersects(const Frustum& plane) const;
|
bool Intersects(const Frustum& plane) const;
|
||||||
bool Intersects(const Polyhedron& triangle) const;
|
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 ProjectToAxis(const Vector3 &direction, float &outMin, float &outMax) const;
|
||||||
|
|
||||||
void GetCornerPoints(Vector3 *outPointArray) const;
|
void GetCornerPoints(Vector3 *outPointArray) const;
|
||||||
@@ -240,4 +391,8 @@ namespace J3ML::Geometry
|
|||||||
|
|
||||||
bool Intersects(const Line &line) const;
|
bool Intersects(const Line &line) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Frustum operator * (const Matrix3x3& transform, const Frustum& frustum);
|
||||||
|
Frustum operator * (const Matrix4x4& transform, const Frustum& frustum);
|
||||||
|
Frustum operator * (const Quaternion& transform, const Frustum& frustum);
|
||||||
}
|
}
|
12
include/J3ML/Geometry/KDTree.h
Normal file
12
include/J3ML/Geometry/KDTree.h
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
namespace J3ML::Geometry
|
||||||
|
{
|
||||||
|
|
||||||
|
/// A KD-tree accelleration structure for static geometry.
|
||||||
|
class KdTree
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
@@ -11,11 +11,10 @@
|
|||||||
|
|
||||||
namespace J3ML::LinearAlgebra {
|
namespace J3ML::LinearAlgebra {
|
||||||
|
|
||||||
/// A 4-by-4 matrix for affine transformations and perspective projections of 3D geometry.
|
/// @brief A 4-by-4 matrix for affine transformations and perspective projections of 3D geometry.
|
||||||
/* This matrix can represent the most generic form of transformations for 3D objects,
|
/// This matrix can represent the most generic form of transformations for 3D objects,
|
||||||
* including perspective projections, which a 4-by-3 cannot store,
|
/// including perspective projections, which a 4-by-3 cannot store, and translations, which a 3-by-3 cannot represent.
|
||||||
* and translations, which a 3-by-3 cannot represent.
|
/* The elements of this matrix are
|
||||||
* The elements of this matrix are
|
|
||||||
* m_00, m_01, m_02, m_03
|
* m_00, m_01, m_02, m_03
|
||||||
* m_10, m_11, m_12, m_13
|
* m_10, m_11, m_12, m_13
|
||||||
* m_20, m_21, m_22, m_23,
|
* m_20, m_21, m_22, m_23,
|
||||||
@@ -227,9 +226,19 @@ namespace J3ML::LinearAlgebra {
|
|||||||
static Matrix4x4 D3DPerspProjLH(float nearPlane, float farPlane, float hViewportSize, float vViewportSize);
|
static Matrix4x4 D3DPerspProjLH(float nearPlane, float farPlane, float hViewportSize, float vViewportSize);
|
||||||
static Matrix4x4 D3DPerspProjRH(float nearPlane, float farPlane, float hViewportSize, float vViewportSize);
|
static Matrix4x4 D3DPerspProjRH(float nearPlane, float farPlane, float hViewportSize, float vViewportSize);
|
||||||
|
|
||||||
|
/// Computes a left-handled orthographic projection matrix for OpenGL.
|
||||||
|
/// @note Use the M*v multiplication order to project points with this matrix.
|
||||||
static Matrix4x4 OpenGLOrthoProjLH(float n, float f, float h, float v);
|
static Matrix4x4 OpenGLOrthoProjLH(float n, float f, float h, float v);
|
||||||
|
/// Computes a right-handled orthographic projection matrix for OpenGL.
|
||||||
|
/// @note Use the M*v multiplication order to project points with this matrix.
|
||||||
static Matrix4x4 OpenGLOrthoProjRH(float n, float f, float h, float v);
|
static Matrix4x4 OpenGLOrthoProjRH(float n, float f, float h, float v);
|
||||||
|
|
||||||
|
/// Computes a left-handed perspective projection matrix for OpenGL.
|
||||||
|
/// @note Use the M*v multiplication order to project points with this matrix.
|
||||||
static Matrix4x4 OpenGLPerspProjLH(float n, float f, float h, float v);
|
static Matrix4x4 OpenGLPerspProjLH(float n, float f, float h, float v);
|
||||||
|
/// Identical to http://www.opengl.org/sdk/docs/man/xhtml/gluPerspective.xml , except uses viewport sizes instead of FOV to set up the
|
||||||
|
/// projection matrix.
|
||||||
|
/// @note Use the M*v multiplication order to project points with this matrix.
|
||||||
static Matrix4x4 OpenGLPerspProjRH(float n, float f, float h, float v);
|
static Matrix4x4 OpenGLPerspProjRH(float n, float f, float h, float v);
|
||||||
|
|
||||||
Vector4 operator[](int row);
|
Vector4 operator[](int row);
|
||||||
|
@@ -8,11 +8,9 @@
|
|||||||
|
|
||||||
namespace J3ML::LinearAlgebra {
|
namespace J3ML::LinearAlgebra {
|
||||||
|
|
||||||
// A 3D (x, y, z) ordered pair.
|
/// A 3D (x, y, z) ordered pair.
|
||||||
class Vector3 {
|
class Vector3 {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
float x = 0;
|
float x = 0;
|
||||||
float y = 0;
|
float y = 0;
|
||||||
float z = 0;
|
float z = 0;
|
||||||
|
@@ -197,12 +197,12 @@ namespace J3ML::Geometry {
|
|||||||
return aabb;
|
return aabb;
|
||||||
}
|
}
|
||||||
|
|
||||||
float AABB::GetVolume() const {
|
float AABB::Volume() const {
|
||||||
Vector3 sz = Size();
|
Vector3 sz = Size();
|
||||||
return sz.x * sz.y * sz.z;
|
return sz.x * sz.y * sz.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
float AABB::GetSurfaceArea() const {
|
float AABB::SurfaceArea() const {
|
||||||
Vector3 size = Size();
|
Vector3 size = Size();
|
||||||
return 2.f * (size.x*size.y + size.x*size.z + size.y*size.z);
|
return 2.f * (size.x*size.y + size.x*size.z + size.y*size.z);
|
||||||
}
|
}
|
||||||
|
@@ -293,4 +293,25 @@ namespace J3ML::Geometry
|
|||||||
{
|
{
|
||||||
return this->ToPolyhedron().Intersects(polyhedron);
|
return this->ToPolyhedron().Intersects(polyhedron);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Frustum::Frustum()
|
||||||
|
: type(FrustumType::Invalid),
|
||||||
|
pos(Vector3::NaN),
|
||||||
|
front(Vector3::NaN),
|
||||||
|
up(Vector3::NaN),
|
||||||
|
nearPlaneDistance(NAN),
|
||||||
|
farPlaneDistance(NAN),
|
||||||
|
worldMatrix(Matrix4x4::NaN),
|
||||||
|
viewProjectionMatrix(Matrix4x4::NaN)
|
||||||
|
{
|
||||||
|
// For conveniency, allow automatic initialization of the graphics API and handedness in use.
|
||||||
|
// If neither of the #defines are set, user must specify per-instance.
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 Frustum::WorldRight() const {
|
||||||
|
if (handedness == FrustumHandedness::Right)
|
||||||
|
return Vector3::Cross(front, up);
|
||||||
|
else
|
||||||
|
return Vector3::Cross(up, front);
|
||||||
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user