// HARFANG(R) Copyright (C) 2022 NWNC. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. #pragma once #include "foundation/axis.h" #include "foundation/cext.h" #include "foundation/vector3.h" namespace hg { struct Mat4; struct MinMax { MinMax() : mn(Vec3::Max), mx(Vec3::Min) {} MinMax(const Vec3 &min, const Vec3 &max) : mn(min), mx(max) {} Vec3 mn, mx; }; /// Get the min-max area. inline float GetArea(const MinMax &mm) { return (mm.mx.x - mm.mn.x) * (mm.mx.y - mm.mn.y) * (mm.mx.z - mm.mn.z); } /// Return the minmax center. inline Vec3 GetCenter(const MinMax &mm) { return (mm.mn + mm.mx) * 0.5f; } /// Return the minmax size. inline Vec3 GetSize(const MinMax &mm) { return mm.mx - mm.mn; } /// Fill an array of vector3 with the position of the minmax vertices. void GetMinMaxVertices(const MinMax &minmax, Vec3 out[8]); /// Return the origin and radius of the minmax bounding sphere. void ComputeMinMaxBoundingSphere(const MinMax &minmax, Vec3 &origin, float &radius); /// Test minmax overlap on a specific axis. inline bool Overlap(const MinMax &a, const MinMax &b, Axis axis) { return !(b.mn[axis] > a.mx[axis] || b.mx[axis] < a.mn[axis]); } /// Return whether two MinMax overlap at a given time. inline bool Overlap(const MinMax &a, const MinMax &b) { return !(a.mx.x < b.mn.x || a.mx.y < b.mn.y || a.mx.z < b.mn.z || b.mx.x < a.mn.x || b.mx.y < a.mn.y || b.mx.z < a.mn.z); } inline bool operator==(const MinMax &a, const MinMax &b) { return a.mn == b.mn && a.mx == b.mx; } inline bool operator!=(const MinMax &a, const MinMax &b) { return a.mn != b.mn || a.mx != b.mx; } /// Returns true if the provided position is inside the bounding volume, false otherwise. inline bool Contains(const MinMax &mm, const Vec3 &p) { return !(p.x < mm.mn.x || p.y < mm.mn.y || p.z < mm.mn.z || p.x > mm.mx.x || p.y > mm.mx.y || p.z > mm.mx.z); } /// Return the union of two minmax. inline MinMax Union(const MinMax &a, const MinMax &b) { return {Min(a.mn, b.mn), Max(a.mx, b.mx)}; } /// Return the union of a minmax and vector. inline MinMax Union(const MinMax &mm, const Vec3 &p) { return {Min(mm.mn, p), Max(mm.mx, p)}; } /// Return a transformed copy of a minmax instance. MinMax operator*(const Mat4 &m, const MinMax &mm); /// Intersect ray with this minmax. bool IntersectRay(const MinMax &mm, const Vec3 &o, const Vec3 &d, float &tmin, float &tmax); bool IntersectRay(const MinMax &mm, const Vec3 &o, const Vec3 &d); /// Returns whether a line intersect with the MinMax. bool ClassifyLine(const MinMax &mm, const Vec3 &p, const Vec3 &d, Vec3 &i, Vec3 *n = nullptr); /// Returns whether a segment intersect with the MinMax. bool ClassifySegment(const MinMax &mm, const Vec3 &p1, const Vec3 &p2, Vec3 &itr, Vec3 *n = nullptr); /// Set from position and size. inline MinMax MinMaxFromPositionSize(const Vec3 &p, const Vec3 &s) { return {p - s * 0.5f, p + s * 0.5f}; } } // namespace hg