24#ifndef JAU_FRUSTUM_HPP_
25#define JAU_FRUSTUM_HPP_
94 constexpr static const int LEFT = 0;
96 constexpr static const int RIGHT = 1;
98 constexpr static const int BOTTOM = 2;
100 constexpr static const int TOP = 3;
102 constexpr static const int NEAR = 4;
104 constexpr static const int FAR = 5;
137 return "FrustumFovDesc["+
fovhv.toStringInDegrees()+
", Z["+std::to_string(
zNear)+
" - "+std::to_string(
zFar)+
"]]";
178 n.cross(v, u).normalize();
191 d = (
n * -1.0f).dot(p0);
205 constexpr void toFloats(
float out[])
const noexcept {
227 constexpr float distanceTo(
const float x,
const float y,
const float z)
const noexcept {
228 return n.x * x +
n.y * y +
n.z * z +
d;
237 return "Plane[ [ " +
n.toString() +
" ], " + std::to_string(
d) +
"]";
268 planes[
LEFT ].toVec4f(out[0]);
269 planes[
RIGHT ].toVec4f(out[1]);
270 planes[
BOTTOM].toVec4f(out[2]);
271 planes[
TOP ].toVec4f(out[3]);
272 planes[
NEAR ].toVec4f(out[4]);
273 planes[
FAR ].toVec4f(out[5]);
288 planes[
LEFT ].toFloats( out +
static_cast<ptrdiff_t
>(4*0) );
289 planes[
RIGHT ].toFloats( out +
static_cast<ptrdiff_t
>(4*1) );
290 planes[
BOTTOM].toFloats( out +
static_cast<ptrdiff_t
>(4*2) );
291 planes[
TOP ].toFloats( out +
static_cast<ptrdiff_t
>(4*3) );
292 planes[
NEAR ].toFloats( out +
static_cast<ptrdiff_t
>(4*4) );
293 planes[
FAR ].toFloats( out +
static_cast<ptrdiff_t
>(4*5) );
371 p.
n.
set( m.m30 + m.m00,
381 p.
n.
set( m.m30 - m.m00,
391 p.
n.
set( m.m30 + m.m10,
401 p.
n.
set( m.m30 - m.m10,
411 p.
n.
set( m.m30 + m.m20,
421 p.
n.
set( m.m30 - m.m20,
428 for (
int i = 0; i < 6; ++i) {
430 const float invLen = 1.0f / p.
n.
length();
438 static bool intersects(
const Plane& p,
const AABBox3f& box)
noexcept {
439 const Vec3f& lo = box.low();
440 const Vec3f& hi = box.high();
442 return p.distanceTo(lo.
x, lo.
y, lo.
z) > 0.0f ||
443 p.distanceTo(hi.
x, lo.
y, lo.
z) > 0.0f ||
444 p.distanceTo(lo.
x, hi.
y, lo.
z) > 0.0f ||
445 p.distanceTo(hi.
x, hi.
y, lo.
z) > 0.0f ||
446 p.distanceTo(lo.
x, lo.
y, hi.
z) > 0.0f ||
447 p.distanceTo(hi.
x, lo.
y, hi.
z) > 0.0f ||
448 p.distanceTo(lo.
x, hi.
y, hi.
z) > 0.0f ||
449 p.distanceTo(hi.
x, hi.
y, hi.
z) > 0.0f;
461 return !intersects(planes[0], box) ||
462 !intersects(planes[1], box) ||
463 !intersects(planes[2], box) ||
464 !intersects(planes[3], box) ||
465 !intersects(planes[4], box) ||
466 !intersects(planes[5], box);
480 for (
int i = 0; i < 6; ++i) {
481 const float d = planes[i].distanceTo(p);
484 }
else if ( d == 0.0f ) {
498 return planes[0].distanceTo(p) < 0.0f ||
499 planes[1].distanceTo(p) < 0.0f ||
500 planes[2].distanceTo(p) < 0.0f ||
501 planes[3].distanceTo(p) < 0.0f ||
502 planes[4].distanceTo(p) < 0.0f ||
503 planes[5].distanceTo(p) < 0.0f;
516 for (
int i = 0; i < 6; ++i) {
517 const float d = planes[i].distanceTo(p);
521 }
else if (d < radius ) {
542 s.append(
"Frustum[Planes[").append(
"\n")
543 .append(
" L: ").append(planes[0].
toString()).append(
",\n")
544 .append(
" R: ").append(planes[1].
toString()).append(
",\n")
545 .append(
" B: ").append(planes[2].
toString()).append(
",\n")
546 .append(
" T: ").append(planes[3].
toString()).append(
",\n")
547 .append(
" N: ").append(planes[4].
toString()).append(
",\n")
548 .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.