1 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 /** 3 * Contains OBB-related code. (oriented bounding box) 4 * \file IceOBB.h 5 * \author Pierre Terdiman 6 * \date January, 13, 2000 7 */ 8 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 9 10 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 11 // Include Guard 12 #ifndef __ICEOBB_H__ 13 #define __ICEOBB_H__ 14 15 // Forward declarations 16 class LSS; 17 18 class ICEMATHS_API OBB 19 { 20 public: 21 //! Constructor OBB()22 inline_ OBB() {} 23 //! Constructor OBB(const Point & center,const Point & extents,const Matrix3x3 & rot)24 inline_ OBB(const Point& center, const Point& extents, const Matrix3x3& rot) : mCenter(center), mExtents(extents), mRot(rot) {} 25 //! Destructor ~OBB()26 inline_ ~OBB() {} 27 28 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 29 /** 30 * Setups an empty OBB. 31 */ 32 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// SetEmpty()33 void SetEmpty() 34 { 35 mCenter.Zero(); 36 mExtents.Set(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT); 37 mRot.Identity(); 38 } 39 40 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 41 /** 42 * Tests if a point is contained within the OBB. 43 * \param p [in] the world point to test 44 * \return true if inside the OBB 45 */ 46 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 47 bool ContainsPoint(const Point& p) const; 48 49 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 50 /** 51 * Builds an OBB from an AABB and a world transform. 52 * \param aabb [in] the aabb 53 * \param mat [in] the world transform 54 */ 55 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 56 void Create(const AABB& aabb, const Matrix4x4& mat); 57 58 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 59 /** 60 * Recomputes the OBB after an arbitrary transform by a 4x4 matrix. 61 * \param mtx [in] the transform matrix 62 * \param obb [out] the transformed OBB 63 */ 64 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Rotate(const Matrix4x4 & mtx,OBB & obb)65 inline_ void Rotate(const Matrix4x4& mtx, OBB& obb) const 66 { 67 // The extents remain constant 68 obb.mExtents = mExtents; 69 // The center gets x-formed 70 obb.mCenter = mCenter * mtx; 71 // Combine rotations 72 obb.mRot = mRot * Matrix3x3(mtx); 73 } 74 75 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 76 /** 77 * Checks the OBB is valid. 78 * \return true if the box is valid 79 */ 80 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// IsValid()81 inline_ BOOL IsValid() const 82 { 83 // Consistency condition for (Center, Extents) boxes: Extents >= 0.0f 84 if(mExtents.x < 0.0f) return FALSE; 85 if(mExtents.y < 0.0f) return FALSE; 86 if(mExtents.z < 0.0f) return FALSE; 87 return TRUE; 88 } 89 90 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 91 /** 92 * Computes the obb planes. 93 * \param planes [out] 6 box planes 94 * \return true if success 95 */ 96 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 97 bool ComputePlanes(Plane* planes) const; 98 99 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 100 /** 101 * Computes the obb points. 102 * \param pts [out] 8 box points 103 * \return true if success 104 */ 105 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 106 bool ComputePoints(Point* pts) const; 107 108 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 109 /** 110 * Computes vertex normals. 111 * \param pts [out] 8 box points 112 * \return true if success 113 */ 114 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 115 bool ComputeVertexNormals(Point* pts) const; 116 117 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 118 /** 119 * Returns edges. 120 * \return 24 indices (12 edges) indexing the list returned by ComputePoints() 121 */ 122 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 123 const udword* GetEdges() const; 124 125 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 126 /** 127 * Returns local edge normals. 128 * \return edge normals in local space 129 */ 130 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 131 const Point* GetLocalEdgeNormals() const; 132 133 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 134 /** 135 * Returns world edge normal 136 * \param edge_index [in] 0 <= edge index < 12 137 * \param world_normal [out] edge normal in world space 138 */ 139 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 140 void ComputeWorldEdgeNormal(udword edge_index, Point& world_normal) const; 141 142 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 143 /** 144 * Computes an LSS surrounding the OBB. 145 * \param lss [out] the LSS 146 */ 147 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 148 void ComputeLSS(LSS& lss) const; 149 150 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 151 /** 152 * Checks the OBB is inside another OBB. 153 * \param box [in] the other OBB 154 * \return TRUE if we're inside the other box 155 */ 156 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 157 BOOL IsInside(const OBB& box) const; 158 GetCenter()159 inline_ const Point& GetCenter() const { return mCenter; } GetExtents()160 inline_ const Point& GetExtents() const { return mExtents; } GetRot()161 inline_ const Matrix3x3& GetRot() const { return mRot; } 162 GetRotatedExtents(Matrix3x3 & extents)163 inline_ void GetRotatedExtents(Matrix3x3& extents) const 164 { 165 extents = mRot; 166 extents.Scale(mExtents); 167 } 168 169 Point mCenter; //!< B for Box 170 Point mExtents; //!< B for Bounding 171 Matrix3x3 mRot; //!< O for Oriented 172 173 // Orientation is stored in row-major format, 174 // i.e. rows = eigen vectors of the covariance matrix 175 }; 176 177 #endif // __ICEOBB_H__ 178