📄 bbox.h
字号:
#ifndef N_BBOX_H
#define N_BBOX_H
//------------------------------------------------------------------------------
/**
(non-oriented) bounding box
@author
- RadonLabs GmbH
@since
- 2005.7.06
@remarks
- 瘤肯 眠啊
*/
#include "vector.h"
#include "matrix.h"
#include "line.h"
//------------------------------------------------------------------------------
// bbox3
//------------------------------------------------------------------------------
class bbox3
{
public:
/// clip codes
enum
{
ClipLeft = (1<<0),
ClipRight = (1<<1),
ClipBottom = (1<<2),
ClipTop = (1<<3),
ClipNear = (1<<4),
ClipFar = (1<<5),
};
/// clip status
enum ClipStatus
{
Outside,
Inside,
Clipped,
};
enum {
OUTSIDE = 0,
ISEQUAL = (1<<0),
ISCONTAINED = (1<<1),
CONTAINS = (1<<2),
CLIPS = (1<<3),
};
/// constructor 1
bbox3();
/// constructor 3
bbox3(const vector3& center, const vector3& extents);
/// construct bounding box from matrix44
bbox3(const matrix44& m);
/// get center point
vector3 center() const;
/// get extents of box
vector3 extents() const;
/// get size of box
vector3 size() const;
/// set from matrix44
void set(const matrix44& m);
/// set from center point and extents
void set(const vector3& center, const vector3& extents);
/// begin extending the box
void begin_extend();
/// extend the box
void extend(const vector3& v);
/// extend the box
void extend(float x, float y, float z);
/// extend the box
void extend(const bbox3& box);
/// transform axis aligned bounding box
void transform(const matrix44& m);
/// check for intersection with axis aligned bounding box
bool intersects(const bbox3& box) const;
/// check if this box completely contains the parameter box
bool contains(const bbox3& box) const;
/// return true if this box contains the position
bool contains(const vector3& pos) const;
/// check for intersection with other bounding box
ClipStatus clipstatus(const bbox3& other) const;
/// check for intersection with projection volume
ClipStatus clipstatus(const matrix44& viewProjection) const;
/// create a matrix which transforms a unit cube to this bounding box
matrix44 to_matrix44() const;
int line_test(float v0, float v1, float w0, float w1);
int intersect(bbox3 box);
/**
@brief Gets closest intersection with AABB.
If the line starts inside the box, start point is returned in ipos.
@param line the pick ray
@param ipos closest point of intersection if successful, trash otherwise
@return true if an intersection occurs
*/
bool intersect(const line3& line, vector3& ipos) const;
// get point of intersection of 3d line with planes
// on const x,y,z
bool isect_const_x(const float x, const line3& l, vector3& out) const
{
if (l.m.x != 0.0f)
{
float t = (x - l.b.x) / l.m.x;
if ((t>=0.0f) && (t<=1.0f))
{
// point of intersection...
out = l.ipol(t);
return true;
}
}
return false;
}
bool isect_const_y(const float y, const line3& l, vector3& out) const
{
if (l.m.y != 0.0f)
{
float t = (y - l.b.y) / l.m.y;
if ((t>=0.0f) && (t<=1.0f))
{
// point of intersection...
out = l.ipol(t);
return true;
}
}
return false;
}
bool isect_const_z(const float z, const line3& l, vector3& out) const
{
if (l.m.z != 0.0f)
{
float t = (z - l.b.z) / l.m.z;
if ((t>=0.0f) && (t<=1.0f))
{
// point of intersection...
out = l.ipol(t);
return true;
}
}
return false;
}
// point in polygon check for sides with constant x,y and z
bool pip_const_x(const vector3& p) const
{
if ((p.y>=vmin.y)&&(p.y<=vmax.y)&&(p.z>=vmin.z)&&(p.z<=vmax.z)) return true;
else return false;
}
bool pip_const_y(const vector3& p) const
{
if ((p.x>=vmin.x)&&(p.x<=vmax.x)&&(p.z>=vmin.z)&&(p.z<=vmax.z)) return true;
else return false;
}
bool pip_const_z(const vector3& p) const
{
if ((p.x>=vmin.x)&&(p.x<=vmax.x)&&(p.y>=vmin.y)&&(p.y<=vmax.y)) return true;
else return false;
}
vector3 vmin;
vector3 vmax;
};
//------------------------------------------------------------------------------
/**
*/
inline
bbox3::bbox3()
{
// empty
}
//------------------------------------------------------------------------------
/**
*/
inline
bbox3::bbox3(const vector3& center, const vector3& extents)
{
vmin = center - extents;
vmax = center + extents;
}
//------------------------------------------------------------------------------
/**
Construct a bounding box around a 4x4 matrix. The translational part
defines the center point, and the x,y,z vectors of the matrix
define the extents.
*/
inline
void
bbox3::set(const matrix44& m)
{
// get extents
float xExtent = n_max(n_max(n_abs(m.M11), n_abs(m.M21)), n_abs(m.M31));
float yExtent = n_max(n_max(n_abs(m.M12), n_abs(m.M22)), n_abs(m.M32));
float zExtent = n_max(n_max(n_abs(m.M13), n_abs(m.M23)), n_abs(m.M33));
vector3 extent(xExtent, yExtent, zExtent);
vector3 center = m.pos_component();
this->vmin = center - extent;
this->vmax = center + extent;
}
//------------------------------------------------------------------------------
/**
*/
inline
bbox3::bbox3(const matrix44& m)
{
this->set(m);
}
//------------------------------------------------------------------------------
/**
*/
inline
vector3
bbox3::center() const
{
return vector3((vmin + vmax) * 0.5f);
}
//------------------------------------------------------------------------------
/**
*/
inline
vector3
bbox3::extents() const
{
return vector3((vmax - vmin) * 0.5f);
}
//------------------------------------------------------------------------------
/**
*/
inline
vector3
bbox3::size() const
{
return vector3(vmax - vmin);
}
//------------------------------------------------------------------------------
/**
*/
inline
void
bbox3::set(const vector3& center, const vector3& extents)
{
vmin = center - extents;
vmax = center + extents;
}
//------------------------------------------------------------------------------
/**
*/
inline
void
bbox3::begin_extend()
{
vmin.set(+1000000.0f,+1000000.0f,+1000000.0f);
vmax.set(-1000000.0f,-1000000.0f,-1000000.0f);
}
//------------------------------------------------------------------------------
/**
*/
inline
void
bbox3::extend(const vector3& v)
{
if (v.x < vmin.x) vmin.x = v.x;
if (v.x > vmax.x) vmax.x = v.x;
if (v.y < vmin.y) vmin.y = v.y;
if (v.y > vmax.y) vmax.y = v.y;
if (v.z < vmin.z) vmin.z = v.z;
if (v.z > vmax.z) vmax.z = v.z;
}
//------------------------------------------------------------------------------
/**
*/
inline
void
bbox3::extend(float x, float y, float z)
{
if (x < vmin.x) vmin.x = x;
if (x > vmax.x) vmax.x = x;
if (y < vmin.y) vmin.y = y;
if (y > vmax.y) vmax.y = y;
if (z < vmin.z) vmin.z = z;
if (z > vmax.z) vmax.z = z;
}
//------------------------------------------------------------------------------
/**
*/
inline
void
bbox3::extend(const bbox3& box)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -