178 lines
9.5 KiB
C++
178 lines
9.5 KiB
C++
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
* Contains OBB-related code. (oriented bounding box)
|
|
* \file IceOBB.h
|
|
* \author Pierre Terdiman
|
|
* \date January, 13, 2000
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Include Guard
|
|
#ifndef __ICEOBB_H__
|
|
#define __ICEOBB_H__
|
|
|
|
// Forward declarations
|
|
class LSS;
|
|
|
|
class ICEMATHS_API OBB
|
|
{
|
|
public:
|
|
//! Constructor
|
|
inline_ OBB() {}
|
|
//! Constructor
|
|
inline_ OBB(const Point& center, const Point& extents, const Matrix3x3& rot) : mCenter(center), mExtents(extents), mRot(rot) {}
|
|
//! Destructor
|
|
inline_ ~OBB() {}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
* Setups an empty OBB.
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
void SetEmpty()
|
|
{
|
|
mCenter.Zero();
|
|
mExtents.Set(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT);
|
|
mRot.Identity();
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
* Tests if a point is contained within the OBB.
|
|
* \param p [in] the world point to test
|
|
* \return true if inside the OBB
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
bool ContainsPoint(const Point& p) const;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
* Builds an OBB from an AABB and a world transform.
|
|
* \param aabb [in] the aabb
|
|
* \param mat [in] the world transform
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
void Create(const AABB& aabb, const Matrix4x4& mat);
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
* Recomputes the OBB after an arbitrary transform by a 4x4 matrix.
|
|
* \param mtx [in] the transform matrix
|
|
* \param obb [out] the transformed OBB
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
inline_ void Rotate(const Matrix4x4& mtx, OBB& obb) const
|
|
{
|
|
// The extents remain constant
|
|
obb.mExtents = mExtents;
|
|
// The center gets x-formed
|
|
obb.mCenter = mCenter * mtx;
|
|
// Combine rotations
|
|
obb.mRot = mRot * Matrix3x3(mtx);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
* Checks the OBB is valid.
|
|
* \return true if the box is valid
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
inline_ BOOL IsValid() const
|
|
{
|
|
// Consistency condition for (Center, Extents) boxes: Extents >= 0.0f
|
|
if(mExtents.x < 0.0f) return FALSE;
|
|
if(mExtents.y < 0.0f) return FALSE;
|
|
if(mExtents.z < 0.0f) return FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
* Computes the obb planes.
|
|
* \param planes [out] 6 box planes
|
|
* \return true if success
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
bool ComputePlanes(Plane* planes) const;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
* Computes the obb points.
|
|
* \param pts [out] 8 box points
|
|
* \return true if success
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
bool ComputePoints(Point* pts) const;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
* Computes vertex normals.
|
|
* \param pts [out] 8 box points
|
|
* \return true if success
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
bool ComputeVertexNormals(Point* pts) const;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
* Returns edges.
|
|
* \return 24 indices (12 edges) indexing the list returned by ComputePoints()
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
const udword* GetEdges() const;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
* Returns local edge normals.
|
|
* \return edge normals in local space
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
const Point* GetLocalEdgeNormals() const;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
* Returns world edge normal
|
|
* \param edge_index [in] 0 <= edge index < 12
|
|
* \param world_normal [out] edge normal in world space
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
void ComputeWorldEdgeNormal(udword edge_index, Point& world_normal) const;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
* Computes an LSS surrounding the OBB.
|
|
* \param lss [out] the LSS
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
void ComputeLSS(LSS& lss) const;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
* Checks the OBB is inside another OBB.
|
|
* \param box [in] the other OBB
|
|
* \return TRUE if we're inside the other box
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
BOOL IsInside(const OBB& box) const;
|
|
|
|
inline_ const Point& GetCenter() const { return mCenter; }
|
|
inline_ const Point& GetExtents() const { return mExtents; }
|
|
inline_ const Matrix3x3& GetRot() const { return mRot; }
|
|
|
|
inline_ void GetRotatedExtents(Matrix3x3& extents) const
|
|
{
|
|
extents = mRot;
|
|
extents.Scale(mExtents);
|
|
}
|
|
|
|
Point mCenter; //!< B for Box
|
|
Point mExtents; //!< B for Bounding
|
|
Matrix3x3 mRot; //!< O for Oriented
|
|
|
|
// Orientation is stored in row-major format,
|
|
// i.e. rows = eigen vectors of the covariance matrix
|
|
};
|
|
|
|
#endif // __ICEOBB_H__
|