diff options
Diffstat (limited to 'public/mathlib/vplane.h')
| -rw-r--r-- | public/mathlib/vplane.h | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/public/mathlib/vplane.h b/public/mathlib/vplane.h new file mode 100644 index 0000000..dd3d4a9 --- /dev/null +++ b/public/mathlib/vplane.h @@ -0,0 +1,182 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// $NoKeywords: $ +//=============================================================================// + +#ifndef VPLANE_H +#define VPLANE_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "mathlib/vector.h" + +typedef int SideType; + +// Used to represent sides of things like planes. +#define SIDE_FRONT 0 +#define SIDE_BACK 1 +#define SIDE_ON 2 + +#define VP_EPSILON 0.01f + + +class VPlane +{ +public: + VPlane(); + VPlane(const Vector &vNormal, vec_t dist); + + void Init(const Vector &vNormal, vec_t dist); + + // Return the distance from the point to the plane. + vec_t DistTo(const Vector &vVec) const; + + // Copy. + VPlane& operator=(const VPlane &thePlane); + + // Returns SIDE_ON, SIDE_FRONT, or SIDE_BACK. + // The epsilon for SIDE_ON can be passed in. + SideType GetPointSide(const Vector &vPoint, vec_t sideEpsilon=VP_EPSILON) const; + + // Returns SIDE_FRONT or SIDE_BACK. + SideType GetPointSideExact(const Vector &vPoint) const; + + // Classify the box with respect to the plane. + // Returns SIDE_ON, SIDE_FRONT, or SIDE_BACK + SideType BoxOnPlaneSide(const Vector &vMin, const Vector &vMax) const; + +#ifndef VECTOR_NO_SLOW_OPERATIONS + // Flip the plane. + VPlane Flip(); + + // Get a point on the plane (normal*dist). + Vector GetPointOnPlane() const; + + // Snap the specified point to the plane (along the plane's normal). + Vector SnapPointToPlane(const Vector &vPoint) const; +#endif + +public: + Vector m_Normal; + vec_t m_Dist; + +#ifdef VECTOR_NO_SLOW_OPERATIONS +private: + // No copy constructors allowed if we're in optimal mode + VPlane(const VPlane& vOther); +#endif +}; + + +//----------------------------------------------------------------------------- +// Inlines. +//----------------------------------------------------------------------------- +inline VPlane::VPlane() +{ +} + +inline VPlane::VPlane(const Vector &vNormal, vec_t dist) +{ + m_Normal = vNormal; + m_Dist = dist; +} + +inline void VPlane::Init(const Vector &vNormal, vec_t dist) +{ + m_Normal = vNormal; + m_Dist = dist; +} + +inline vec_t VPlane::DistTo(const Vector &vVec) const +{ + return vVec.Dot(m_Normal) - m_Dist; +} + +inline VPlane& VPlane::operator=(const VPlane &thePlane) +{ + m_Normal = thePlane.m_Normal; + m_Dist = thePlane.m_Dist; + return *this; +} + +#ifndef VECTOR_NO_SLOW_OPERATIONS + +inline VPlane VPlane::Flip() +{ + return VPlane(-m_Normal, -m_Dist); +} + +inline Vector VPlane::GetPointOnPlane() const +{ + return m_Normal * m_Dist; +} + +inline Vector VPlane::SnapPointToPlane(const Vector &vPoint) const +{ + return vPoint - m_Normal * DistTo(vPoint); +} + +#endif + +inline SideType VPlane::GetPointSide(const Vector &vPoint, vec_t sideEpsilon) const +{ + vec_t fDist; + + fDist = DistTo(vPoint); + if(fDist >= sideEpsilon) + return SIDE_FRONT; + else if(fDist <= -sideEpsilon) + return SIDE_BACK; + else + return SIDE_ON; +} + +inline SideType VPlane::GetPointSideExact(const Vector &vPoint) const +{ + return DistTo(vPoint) > 0.0f ? SIDE_FRONT : SIDE_BACK; +} + + +// BUGBUG: This should either simply use the implementation in mathlib or cease to exist. +// mathlib implementation is much more efficient. Check to see that VPlane isn't used in +// performance critical code. +inline SideType VPlane::BoxOnPlaneSide(const Vector &vMin, const Vector &vMax) const +{ + int i, firstSide, side; + TableVector vPoints[8] = + { + { vMin.x, vMin.y, vMin.z }, + { vMin.x, vMin.y, vMax.z }, + { vMin.x, vMax.y, vMax.z }, + { vMin.x, vMax.y, vMin.z }, + + { vMax.x, vMin.y, vMin.z }, + { vMax.x, vMin.y, vMax.z }, + { vMax.x, vMax.y, vMax.z }, + { vMax.x, vMax.y, vMin.z }, + }; + + firstSide = GetPointSideExact(vPoints[0]); + for(i=1; i < 8; i++) + { + side = GetPointSideExact(vPoints[i]); + + // Does the box cross the plane? + if(side != firstSide) + return SIDE_ON; + } + + // Ok, they're all on the same side, return that. + return firstSide; +} + + + + +#endif // VPLANE_H |