/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Contains OBB-related code. * \file IceOBB.cpp * \author Pierre Terdiman * \date January, 29, 2000 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * An Oriented Bounding Box (OBB). * \class OBB * \author Pierre Terdiman * \version 1.0 */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Precompiled Header #include "Stdafx.h" using namespace Meshmerizer; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Tests if a point is contained within the OBB. * \param p [in] the world point to test * \return true if inside the OBB */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool OBB::ContainsPoint(const Point& p) const { // Point in OBB test using lazy evaluation and early exits // Translate to box space Point RelPoint = p - mCenter; // Point * mRot maps from box space to world space // mRot * Point maps from world space to box space (what we need here) float f = mRot2.m[0][0] * RelPoint.x + mRot2.m[0][1] * RelPoint.y + mRot2.m[0][2] * RelPoint.z; if(f >= mExtents.x || f <= -mExtents.x) return false; f = mRot2.m[1][0] * RelPoint.x + mRot2.m[1][1] * RelPoint.y + mRot2.m[1][2] * RelPoint.z; if(f >= mExtents.y || f <= -mExtents.y) return false; f = mRot2.m[2][0] * RelPoint.x + mRot2.m[2][1] * RelPoint.y + mRot2.m[2][2] * RelPoint.z; if(f >= mExtents.z || f <= -mExtents.z) return false; return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Builds an OBB from an AABB and a world transform. * \param aabb [in] the aabb * \param mat [in] the world transform */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void OBB::Create(const AABB& aabb, const Matrix4x4& mat) { // Note: must be coherent with Rotate() aabb.GetCenter(mCenter); aabb.GetExtents(mExtents); // Here we have the same as OBB::Rotate(mat) where the obb is (mCenter, mExtents, Identity). // So following what's done in Rotate: // - x-form the center mCenter *= mat; // - combine rotation with identity, i.e. just use given matrix mRot2 = mat; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the obb planes. * \param planes [out] 6 box planes * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool OBB::ComputePlanes(Plane* planes) const { // Checkings if(!planes) return false; Point Axis0 = *mRot2[0]; Point Axis1 = *mRot2[1]; Point Axis2 = *mRot2[2]; // Writes normals planes[0].n = Axis0; planes[1].n = -Axis0; planes[2].n = Axis1; planes[3].n = -Axis1; planes[4].n = Axis2; planes[5].n = -Axis2; // Compute a point on each plane Point p0 = mCenter + Axis0 * mExtents.x; Point p1 = mCenter - Axis0 * mExtents.x; Point p2 = mCenter + Axis1 * mExtents.y; Point p3 = mCenter - Axis1 * mExtents.y; Point p4 = mCenter + Axis2 * mExtents.z; Point p5 = mCenter - Axis2 * mExtents.z; // Compute d planes[0].d = -(planes[0].n|p0); planes[1].d = -(planes[1].n|p1); planes[2].d = -(planes[2].n|p2); planes[3].d = -(planes[3].n|p3); planes[4].d = -(planes[4].n|p4); planes[5].d = -(planes[5].n|p5); return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes the obb points. * \param pts [out] 8 box points * \return true if success */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool OBB::ComputePoints(Point* pts) const { // Checkings if(!pts) return false; Point Axis0 = *mRot2[0]; Point Axis1 = *mRot2[1]; Point Axis2 = *mRot2[2]; pts[0] = mCenter - Axis0*mExtents.x + Axis1*mExtents.y + Axis2*mExtents.z; pts[1] = mCenter + Axis0*mExtents.x + Axis1*mExtents.y + Axis2*mExtents.z; pts[2] = mCenter + Axis0*mExtents.x - Axis1*mExtents.y + Axis2*mExtents.z; pts[3] = mCenter - Axis0*mExtents.x - Axis1*mExtents.y + Axis2*mExtents.z; pts[4] = mCenter - Axis0*mExtents.x + Axis1*mExtents.y - Axis2*mExtents.z; pts[5] = mCenter + Axis0*mExtents.x + Axis1*mExtents.y - Axis2*mExtents.z; pts[6] = mCenter + Axis0*mExtents.x - Axis1*mExtents.y - Axis2*mExtents.z; pts[7] = mCenter - Axis0*mExtents.x - Axis1*mExtents.y - Axis2*mExtents.z; return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Returns a list of indices used to draw the OBB. * \return 48 indices for the list returned by ComputePoints() */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// const udword* OBB::GetLineIndices() const { static udword Indices[] = { 0, 1, 1, 2, 2, 3, 3, 0, 1, 5, 5, 6, 6, 2, 2, 1, 7, 6, 6, 5, 5, 4, 4, 7, 3, 7, 7, 4, 4, 0, 0, 3, 4, 5, 5, 1, 1, 0, 0, 4, 3, 2, 2, 6, 6, 7, 7, 3, }; return Indices; }