first commit
This commit is contained in:
184
include/framework/geometry/bounding_box.h
Normal file
184
include/framework/geometry/bounding_box.h
Normal file
@ -0,0 +1,184 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
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__
|
||||
|
||||
Reference in New Issue
Block a user