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