11#ifndef JAU_MATH_GEOM_FRUSTUM_HPP_
12#define JAU_MATH_GEOM_FRUSTUM_HPP_
81 constexpr static const int LEFT = 0;
83 constexpr static const int RIGHT = 1;
85 constexpr static const int BOTTOM = 2;
87 constexpr static const int TOP = 3;
89 constexpr static const int NEAR = 4;
91 constexpr static const int FAR = 5;
124 return "FrustumFovDesc["+
fovhv.toStringInDegrees()+
", Z["+std::to_string(
zNear)+
" - "+std::to_string(
zFar)+
"]]";
165 n.cross(v, u).normalize();
178 d = (
n * -1.0f).dot(p0);
192 constexpr void toFloats(
float out[])
const noexcept {
214 constexpr float distanceTo(
const float x,
const float y,
const float z)
const noexcept {
215 return n.x * x +
n.y * y +
n.z * z +
d;
224 return "Plane[ [ " +
n.toString() +
" ], " + std::to_string(
d) +
"]";
255 planes[
LEFT ].toVec4f(out[0]);
256 planes[
RIGHT ].toVec4f(out[1]);
257 planes[
BOTTOM].toVec4f(out[2]);
258 planes[
TOP ].toVec4f(out[3]);
259 planes[
NEAR ].toVec4f(out[4]);
260 planes[
FAR ].toVec4f(out[5]);
275 planes[
LEFT ].toFloats( out +
static_cast<ptrdiff_t
>(4*0) );
276 planes[
RIGHT ].toFloats( out +
static_cast<ptrdiff_t
>(4*1) );
277 planes[
BOTTOM].toFloats( out +
static_cast<ptrdiff_t
>(4*2) );
278 planes[
TOP ].toFloats( out +
static_cast<ptrdiff_t
>(4*3) );
279 planes[
NEAR ].toFloats( out +
static_cast<ptrdiff_t
>(4*4) );
280 planes[
FAR ].toFloats( out +
static_cast<ptrdiff_t
>(4*5) );
358 p.
n.
set( m.m30 + m.m00,
368 p.
n.
set( m.m30 - m.m00,
378 p.
n.
set( m.m30 + m.m10,
388 p.
n.
set( m.m30 - m.m10,
398 p.
n.
set( m.m30 + m.m20,
408 p.
n.
set( m.m30 - m.m20,
415 for (
int i = 0; i < 6; ++i) {
417 const float invLen = 1.0f / p.
n.
length();
425 static bool intersects(
const Plane& p,
const AABBox3f& box)
noexcept {
426 const Vec3f& lo = box.low();
427 const Vec3f& hi = box.high();
429 return p.distanceTo(lo.
x, lo.
y, lo.
z) > 0.0f ||
430 p.distanceTo(hi.
x, lo.
y, lo.
z) > 0.0f ||
431 p.distanceTo(lo.
x, hi.
y, lo.
z) > 0.0f ||
432 p.distanceTo(hi.
x, hi.
y, lo.
z) > 0.0f ||
433 p.distanceTo(lo.
x, lo.
y, hi.
z) > 0.0f ||
434 p.distanceTo(hi.
x, lo.
y, hi.
z) > 0.0f ||
435 p.distanceTo(lo.
x, hi.
y, hi.
z) > 0.0f ||
436 p.distanceTo(hi.
x, hi.
y, hi.
z) > 0.0f;
448 return !intersects(planes[0], box) ||
449 !intersects(planes[1], box) ||
450 !intersects(planes[2], box) ||
451 !intersects(planes[3], box) ||
452 !intersects(planes[4], box) ||
453 !intersects(planes[5], box);
467 for (
int i = 0; i < 6; ++i) {
468 const float d = planes[i].distanceTo(p);
471 }
else if ( d == 0.0f ) {
485 return planes[0].distanceTo(p) < 0.0f ||
486 planes[1].distanceTo(p) < 0.0f ||
487 planes[2].distanceTo(p) < 0.0f ||
488 planes[3].distanceTo(p) < 0.0f ||
489 planes[4].distanceTo(p) < 0.0f ||
490 planes[5].distanceTo(p) < 0.0f;
503 for (
int i = 0; i < 6; ++i) {
504 const float d = planes[i].distanceTo(p);
508 }
else if (d < radius ) {
529 s.append(
"Frustum[Planes[").append(
"\n")
530 .append(
" L: ").append(planes[0].
toString()).append(
",\n")
531 .append(
" R: ").append(planes[1].
toString()).append(
",\n")
532 .append(
" B: ").append(planes[2].
toString()).append(
",\n")
533 .append(
" T: ").append(planes[3].
toString()).append(
",\n")
534 .append(
" N: ").append(planes[4].
toString()).append(
",\n")
535 .append(
" F: ").append(planes[5].
toString()).append(
"],\n")
Horizontal and vertical field of view (FOV) halves, allowing a non-centered projection.
Matrix4 & setToPerspective(const value_type fovy_rad, const value_type aspect, const value_type zNear, const value_type zFar)
Set this matrix to perspective frustum projection.
constexpr Vector3F & set(const Vec2f &o, const value_type z_) noexcept
TODO constexpr bool operator<=>(const vec3f_t& rhs ) const noexcept { return ... }...
constexpr value_type length() const noexcept
Return the length of a vector, a.k.a the norm or magnitude
Axis Aligned Bounding Box.
Frustum description by fovhv and zNear, zFar.
FovDesc & operator=(const FovDesc &) noexcept=default
constexpr FovDesc(FovDesc &&o) noexcept=default
FovHVHalves fovhv
Field of view in both directions, may not be centered, either FovHVHalves#inTangents or radians.
FovDesc(const FovHVHalves &fovhv_, const float zNear_, const float zFar_)
constexpr FovDesc(const FovDesc &o) noexcept=default
FovDesc & operator=(FovDesc &&) noexcept=default
std::string toString() noexcept
Plane equation := dot(n, x - p) = 0 -> Ax + By + Cz + d == 0.
float d
Distance to origin.
constexpr void toFloats(float out[]) const noexcept
Sets the given [float[off]..float[off+4]) out to ( n, d ).
constexpr jau::math::Vec4f & toVec4f(jau::math::Vec4f &out) const noexcept
Sets the given vec4f out to ( n, d ).
constexpr Plane & set(const jau::math::Vec3f &n_, const jau::math::Vec3f &p0) noexcept
Setup of plane using given normal and one point on plane.
constexpr Plane & operator=(Plane &&) noexcept=default
constexpr Plane & set(const jau::math::Vec3f &p0, const jau::math::Vec3f &p1, const jau::math::Vec3f &p2) noexcept
Setup of plane using 3 points.
jau::math::Vec3f n
Normal of the plane.
constexpr Plane(Plane &&o) noexcept=default
constexpr Plane & operator=(const Plane &) noexcept=default
std::string toString() const noexcept
constexpr Plane() noexcept
constexpr float distanceTo(const jau::math::Vec3f &p) const noexcept
Return distance of plane to given point, see distanceTo(float, float, float).
constexpr float distanceTo(const float x, const float y, const float z) const noexcept
Return signed distance of plane to given point.
constexpr Plane(const Plane &o) noexcept=default
static constexpr const int LEFT
Index for left plane: {@value}.
Mat4f & updateByFovDesc(jau::math::Mat4f &m, const FovDesc &fovDesc)
Calculate the frustum planes in world coordinates using the passed FovDesc.
Frustum & setFromMat(const jau::math::Mat4f &m) noexcept
Calculate the frustum planes in world coordinates using the given column major order matrix,...
location_t classifySphere(const Vec3f &p, const float radius) const noexcept
Classifies the given sphere whether it is is outside, intersecting or inside of this frustum.
constexpr void getPlanes(float out[]) const noexcept
Sets the given [float[off]..float[off+4*6]) out to ( n, d ).
constexpr void updateByPlanes(const Plane src[]) noexcept
Copy the given src planes into this this instance's planes.
bool isOutside(const Vec3f &p) const noexcept
Returns whether the given Vec3f point is completely outside of this frustum.
constexpr Frustum() noexcept=default
Creates an undefined instance w/o calculating the frustum.
static constexpr const int FAR
Index for far plane: {@value}.
static constexpr const int TOP
Index for top plane: {@value}.
static constexpr const int NEAR
Index for near plane: {@value}.
constexpr jau::math::Vec4f * getPlanes(jau::math::Vec4f out[]) const noexcept
Sets each of the given Vec4f[6] out to Plane#toVec4f(Vec4f) in the order LEFT, RIGHT,...
static constexpr const int BOTTOM
Index for bottom plane: {@value}.
bool isSphereOutside(const Vec3f &p, const float radius) const noexcept
Returns whether the given sphere is completely outside of this frustum.
location_t classifyPoint(const Vec3f &p) const noexcept
Classifies the given Vec3f point whether it is outside, inside or on a plane of this frustum.
static constexpr const int RIGHT
Index for right plane: {@value}.
constexpr Plane * getPlanes() noexcept
Planes are ordered in the returned array as follows:
bool isOutside(const AABBox3f &&box) const noexcept
Returns whether the given AABBox is completely outside of this frustum.
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.