Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

182 lines
3.8 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $Workfile: $
  6. // $Date: $
  7. // $NoKeywords: $
  8. //=============================================================================//
  9. #ifndef VPLANE_H
  10. #define VPLANE_H
  11. #ifdef _WIN32
  12. #pragma once
  13. #endif
  14. #include "mathlib/vector.h"
  15. typedef int SideType;
  16. // Used to represent sides of things like planes.
  17. #define SIDE_FRONT 0
  18. #define SIDE_BACK 1
  19. #define SIDE_ON 2
  20. #define VP_EPSILON 0.01f
  21. class VPlane
  22. {
  23. public:
  24. VPlane();
  25. VPlane(const Vector &vNormal, vec_t dist);
  26. void Init(const Vector &vNormal, vec_t dist);
  27. // Return the distance from the point to the plane.
  28. vec_t DistTo(const Vector &vVec) const;
  29. // Copy.
  30. VPlane& operator=(const VPlane &thePlane);
  31. // Returns SIDE_ON, SIDE_FRONT, or SIDE_BACK.
  32. // The epsilon for SIDE_ON can be passed in.
  33. SideType GetPointSide(const Vector &vPoint, vec_t sideEpsilon=VP_EPSILON) const;
  34. // Returns SIDE_FRONT or SIDE_BACK.
  35. SideType GetPointSideExact(const Vector &vPoint) const;
  36. // Classify the box with respect to the plane.
  37. // Returns SIDE_ON, SIDE_FRONT, or SIDE_BACK
  38. SideType BoxOnPlaneSide(const Vector &vMin, const Vector &vMax) const;
  39. #ifndef VECTOR_NO_SLOW_OPERATIONS
  40. // Flip the plane.
  41. VPlane Flip();
  42. // Get a point on the plane (normal*dist).
  43. Vector GetPointOnPlane() const;
  44. // Snap the specified point to the plane (along the plane's normal).
  45. Vector SnapPointToPlane(const Vector &vPoint) const;
  46. #endif
  47. public:
  48. Vector m_Normal;
  49. vec_t m_Dist;
  50. #ifdef VECTOR_NO_SLOW_OPERATIONS
  51. private:
  52. // No copy constructors allowed if we're in optimal mode
  53. VPlane(const VPlane& vOther);
  54. #endif
  55. };
  56. //-----------------------------------------------------------------------------
  57. // Inlines.
  58. //-----------------------------------------------------------------------------
  59. inline VPlane::VPlane()
  60. {
  61. }
  62. inline VPlane::VPlane(const Vector &vNormal, vec_t dist)
  63. {
  64. m_Normal = vNormal;
  65. m_Dist = dist;
  66. }
  67. inline void VPlane::Init(const Vector &vNormal, vec_t dist)
  68. {
  69. m_Normal = vNormal;
  70. m_Dist = dist;
  71. }
  72. inline vec_t VPlane::DistTo(const Vector &vVec) const
  73. {
  74. return vVec.Dot(m_Normal) - m_Dist;
  75. }
  76. inline VPlane& VPlane::operator=(const VPlane &thePlane)
  77. {
  78. m_Normal = thePlane.m_Normal;
  79. m_Dist = thePlane.m_Dist;
  80. return *this;
  81. }
  82. #ifndef VECTOR_NO_SLOW_OPERATIONS
  83. inline VPlane VPlane::Flip()
  84. {
  85. return VPlane(-m_Normal, -m_Dist);
  86. }
  87. inline Vector VPlane::GetPointOnPlane() const
  88. {
  89. return m_Normal * m_Dist;
  90. }
  91. inline Vector VPlane::SnapPointToPlane(const Vector &vPoint) const
  92. {
  93. return vPoint - m_Normal * DistTo(vPoint);
  94. }
  95. #endif
  96. inline SideType VPlane::GetPointSide(const Vector &vPoint, vec_t sideEpsilon) const
  97. {
  98. vec_t fDist;
  99. fDist = DistTo(vPoint);
  100. if(fDist >= sideEpsilon)
  101. return SIDE_FRONT;
  102. else if(fDist <= -sideEpsilon)
  103. return SIDE_BACK;
  104. else
  105. return SIDE_ON;
  106. }
  107. inline SideType VPlane::GetPointSideExact(const Vector &vPoint) const
  108. {
  109. return DistTo(vPoint) > 0.0f ? SIDE_FRONT : SIDE_BACK;
  110. }
  111. // BUGBUG: This should either simply use the implementation in mathlib or cease to exist.
  112. // mathlib implementation is much more efficient. Check to see that VPlane isn't used in
  113. // performance critical code.
  114. inline SideType VPlane::BoxOnPlaneSide(const Vector &vMin, const Vector &vMax) const
  115. {
  116. int i, firstSide, side;
  117. TableVector vPoints[8] =
  118. {
  119. { vMin.x, vMin.y, vMin.z },
  120. { vMin.x, vMin.y, vMax.z },
  121. { vMin.x, vMax.y, vMax.z },
  122. { vMin.x, vMax.y, vMin.z },
  123. { vMax.x, vMin.y, vMin.z },
  124. { vMax.x, vMin.y, vMax.z },
  125. { vMax.x, vMax.y, vMax.z },
  126. { vMax.x, vMax.y, vMin.z },
  127. };
  128. firstSide = GetPointSideExact(vPoints[0]);
  129. for(i=1; i < 8; i++)
  130. {
  131. side = GetPointSideExact(vPoints[i]);
  132. // Does the box cross the plane?
  133. if(side != firstSide)
  134. return SIDE_ON;
  135. }
  136. // Ok, they're all on the same side, return that.
  137. return firstSide;
  138. }
  139. #endif // VPLANE_H