Files
Webcam/include/framework/geometry/bounding_box.h
2026-06-22 11:49:35 +02:00

185 lines
4.4 KiB
C++

/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
------------------------------------------------------------------------------*/
#ifndef __NBOUNDINGBOX__
#define __NBOUNDINGBOX__
#include "math/matrix3.h"
namespace GS {
/*!
@short AABB.
@author Emmanuel Julien (ejulien@nworks.fr)
*/
class MinMax
{
protected:
enum
{
ClipNone = 0,
ClipRight = 1,
ClipLeft = 2,
ClipTop = 4,
ClipBottom = 8,
ClipFront = 16,
ClipBack = 32
};
/// Internal use.
uint cc_oc(const Vector4 &min, const Vector4 &max, const Vector4 &p) const
{
uint oc = ClipNone;
if (p.x > max.x) oc |= ClipRight;
else if (p.x < min.x) oc |= ClipLeft;
if (p.y > max.y) oc |= ClipTop;
else if (p.y < min.y) oc |= ClipBottom;
if (p.z > max.z) oc |= ClipBack;
else if (p.z < min.z) oc |= ClipFront;
return oc;
}
/// Internal use.
uint ss_oc(const Vector4 &p) const
{
uint oc = ClipNone;
oc |= p.x > 0 ? ClipRight : ClipLeft;
oc |= p.y > 0 ? ClipTop : ClipBottom;
oc |= p.z > 0 ? ClipBack : ClipFront;
return oc;
}
public:
Vector4 mn, mx;
/// Return the start of the interval on a given axis.
float GetMin(uint axis) const
{ return mn[axis]; }
/// Return the end of the interval on a given axis.
float GetMax(uint axis) const
{ return mx[axis]; }
/// Return whether the MinMax object overlap with another one.
bool TestAxisOverlap(const MinMax &b, uint axis) const
{ return (b.mn[axis] > mx[axis]) || (b.mx[axis] < mn[axis]) ? false : true; }
/// Intersect ray with this minmax.
bool IntersectRay(const Vector4 &o, const Vector4 &d, float &tmin, float &tmax);
/// Returns whether a line intersect with the MinMax.
bool ClassifyLine(const Vector4 &p, const Vector4 &d, Vector4 &i, Vector4 *n = 0) const;
/// Returns whether a segment intersect with the MinMax.
bool ClassifySegment(const Vector4 &p0, const Vector4 &p1, Vector4 &i, Vector4 *n = 0) const;
/// Return whether two MinMax overlap at a given time.
bool TestOverlap(const MinMax &b) const
{
if (mx.x < b.mn.x) return false;
if (mx.y < b.mn.y) return false;
if (mx.z < b.mn.z) return false;
if (b.mx.x < mn.x) return false;
if (b.mx.y < mn.y) return false;
if (b.mx.z < mn.z) return false;
return true;
}
/// Test position.
inline bool IsInside(const Vector4 &p) const
{ return (p.x < mn.x) || (p.y < mn.y) || (p.z < mn.z) || (p.x > mx.x) || (p.y > mx.y) || (p.z > mx.z) ? false : true; }
/// Grow the min~max boundaries to include another min~max structure.
void Grow(const MinMax &b)
{
mn = Vector4::Minimum(b.mn, mn);
mx = Vector4::Maximum(b.mx, mx);
}
/// Grow the min~max boundaries to include a vector.
void Grow(const Vector4 &p)
{
mn = Vector4::Minimum(p, mn);
mx = Vector4::Maximum(p, mx);
}
/// Get the min-max area.
float GetArea() const
{ return (mx.x - mn.x) * (mx.y - mn.y) * (mx.z - mn.z); }
/// Get the min-max center.
Vector4 GetCenter() const
{ return (mn + mx) * 0.5f; }
/// Set min-max.
void Set(const Vector4 &min, const Vector4 &max)
{ mn = min; mx = max; }
/// Set from position and size.
void SetFromPositionSize(const Vector4 &p, const Vector4 &s)
{
mn = p - s * 0.5f;
mx = p + s * 0.5f;
}
void Reset()
{ mn.Set(); mx.Set(); }
/*!
@name Serialization
@{
*/
bool FromMetaTag(NML::Tag &tag);
NML::Tag *AsMetaTag();
/// @}
MinMax() : mn(0, 0, 0), mx(0, 0, 0) {}
MinMax(const Vector4 &min, const Vector4 &max) : mn(min), mx(max) {}
};
/*!
@short Oriented bounding box.
@author Emmanuel Julien (ejulien@nworks.fr)
*/
struct OBB
{
Vector4 bb_position;
Vector4 bb_scale;
Matrix3 bb_rotation;
/// Compute the min/max of the OBB.
void ComputeMinMax(MinMax &minmax);
/*!
@short Transform OBB.
@warning Scaling is not supported.
*/
void Transform(const Matrix4 &mtx);
/// OBB from min~max.
static OBB FromMinMax(const MinMax &minmax)
{ return OBB((minmax.mn + minmax.mx) * 0.5f, minmax.mx - minmax.mn); }
bool FromMetaTag(NML::Tag &tag);
NML::Tag *AsMetaTag();
OBB(const MinMax &minmax)
{ *this = FromMinMax(minmax); }
OBB(const Vector4 &p, const Vector4 &s, const Matrix3 *m = 0)
{
bb_position = p;
bb_scale = s;
if (m)
bb_rotation = *m;
}
OBB() {}
};
} // GS
#endif // __NBOUNDINGBOX__