2 * ICE / OPCODE - Optimized Collision Detection
3 * http://www.codercorner.com/Opcode.htm
5 * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com
7 This software is provided 'as-is', without any express or implied warranty.
8 In no event will the authors be held liable for any damages arising from the use of this software.
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it freely,
11 subject to the following restrictions:
13 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
14 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
15 3. This notice may not be removed or altered from any source distribution.
17 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
19 * Contains OBB-related code. (oriented bounding box)
21 * \author Pierre Terdiman
22 * \date January, 13, 2000
24 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
26 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
31 // Forward declarations
34 class ICEMATHS_API OBB
40 inline_ OBB(const Point& center, const Point& extents, const Matrix3x3& rot) : mCenter(center), mExtents(extents), mRot(rot) {}
44 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
46 * Setups an empty OBB.
48 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
52 mExtents.Set(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT);
56 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
58 * Tests if a point is contained within the OBB.
59 * \param p [in] the world point to test
60 * \return true if inside the OBB
62 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
63 bool ContainsPoint(const Point& p) const;
65 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
67 * Builds an OBB from an AABB and a world transform.
68 * \param aabb [in] the aabb
69 * \param mat [in] the world transform
71 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
72 void Create(const AABB& aabb, const Matrix4x4& mat);
74 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
76 * Recomputes the OBB after an arbitrary transform by a 4x4 matrix.
77 * \param mtx [in] the transform matrix
78 * \param obb [out] the transformed OBB
80 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
81 inline_ void Rotate(const Matrix4x4& mtx, OBB& obb) const
83 // The extents remain constant
84 obb.mExtents = mExtents;
85 // The center gets x-formed
86 obb.mCenter = mCenter * mtx;
88 obb.mRot = mRot * Matrix3x3(mtx);
91 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
93 * Checks the OBB is valid.
94 * \return true if the box is valid
96 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
97 inline_ BOOL IsValid() const
99 // Consistency condition for (Center, Extents) boxes: Extents >= 0.0f
100 if(mExtents.x < 0.0f) return FALSE;
101 if(mExtents.y < 0.0f) return FALSE;
102 if(mExtents.z < 0.0f) return FALSE;
106 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
108 * Computes the obb planes.
109 * \param planes [out] 6 box planes
110 * \return true if success
112 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
113 bool ComputePlanes(Plane* planes) const;
115 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
117 * Computes the obb points.
118 * \param pts [out] 8 box points
119 * \return true if success
121 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
122 bool ComputePoints(Point* pts) const;
124 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
126 * Computes vertex normals.
127 * \param pts [out] 8 box points
128 * \return true if success
130 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
131 bool ComputeVertexNormals(Point* pts) const;
133 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
136 * \return 24 indices (12 edges) indexing the list returned by ComputePoints()
138 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
139 const udword* GetEdges() const;
141 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
143 * Returns local edge normals.
144 * \return edge normals in local space
146 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
147 const Point* GetLocalEdgeNormals() const;
149 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
151 * Returns world edge normal
152 * \param edge_index [in] 0 <= edge index < 12
153 * \param world_normal [out] edge normal in world space
155 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
156 void ComputeWorldEdgeNormal(udword edge_index, Point& world_normal) const;
158 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
160 * Computes an LSS surrounding the OBB.
161 * \param lss [out] the LSS
163 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
164 void ComputeLSS(LSS& lss) const;
166 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
168 * Checks the OBB is inside another OBB.
169 * \param box [in] the other OBB
170 * \return TRUE if we're inside the other box
172 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
173 BOOL IsInside(const OBB& box) const;
175 inline_ const Point& GetCenter() const { return mCenter; }
176 inline_ const Point& GetExtents() const { return mExtents; }
177 inline_ const Matrix3x3& GetRot() const { return mRot; }
179 inline_ void GetRotatedExtents(Matrix3x3& extents) const
182 extents.Scale(mExtents);
185 Point mCenter; //!< B for Box
186 Point mExtents; //!< B for Bounding
187 Matrix3x3 mRot; //!< O for Oriented
189 // Orientation is stored in row-major format,
190 // i.e. rows = eigen vectors of the covariance matrix
193 #endif // __ICEOBB_H__