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.

275 lines
6.6 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "stdafx.h"
  8. #include "BoundBox.h"
  9. #include "hammer_mathlib.h"
  10. #include "MapDefs.h"
  11. // memdbgon must be the last include file in a .cpp file!!!
  12. #include "tier0/memdbgon.h"
  13. //-----------------------------------------------------------------------------
  14. // Purpose:
  15. //-----------------------------------------------------------------------------
  16. BoundBox::BoundBox(void)
  17. {
  18. ResetBounds();
  19. }
  20. BoundBox::BoundBox(const Vector &mins, const Vector &maxs)
  21. {
  22. bmins = mins;
  23. bmaxs = maxs;
  24. }
  25. //-----------------------------------------------------------------------------
  26. // Purpose: Sets the box to an uninitialized state, so that calls to UpdateBounds
  27. // will properly set the mins and maxs.
  28. //-----------------------------------------------------------------------------
  29. void BoundBox::ResetBounds(void)
  30. {
  31. bmins[0] = bmins[1] = bmins[2] = COORD_NOTINIT;
  32. bmaxs[0] = bmaxs[1] = bmaxs[2] = -COORD_NOTINIT;
  33. }
  34. //-----------------------------------------------------------------------------
  35. // Purpose:
  36. // Input : pt -
  37. //-----------------------------------------------------------------------------
  38. void BoundBox::UpdateBounds(const Vector& pt)
  39. {
  40. if(pt[0] < bmins[0])
  41. bmins[0] = pt[0];
  42. if(pt[1] < bmins[1])
  43. bmins[1] = pt[1];
  44. if(pt[2] < bmins[2])
  45. bmins[2] = pt[2];
  46. if(pt[0] > bmaxs[0])
  47. bmaxs[0] = pt[0];
  48. if(pt[1] > bmaxs[1])
  49. bmaxs[1] = pt[1];
  50. if(pt[2] > bmaxs[2])
  51. bmaxs[2] = pt[2];
  52. }
  53. //-----------------------------------------------------------------------------
  54. // Purpose:
  55. // Input : bmins -
  56. // bmaxs -
  57. //-----------------------------------------------------------------------------
  58. void BoundBox::UpdateBounds(const Vector& mins, const Vector& maxs)
  59. {
  60. if(mins[0] < bmins[0])
  61. bmins[0] = mins[0];
  62. if(mins[1] < bmins[1])
  63. bmins[1] = mins[1];
  64. if(mins[2] < bmins[2])
  65. bmins[2] = mins[2];
  66. if(maxs[0] > bmaxs[0])
  67. bmaxs[0] = maxs[0];
  68. if(maxs[1] > bmaxs[1])
  69. bmaxs[1] = maxs[1];
  70. if(maxs[2] > bmaxs[2])
  71. bmaxs[2] = maxs[2];
  72. }
  73. //-----------------------------------------------------------------------------
  74. // Purpose:
  75. // Input : pBox -
  76. //-----------------------------------------------------------------------------
  77. void BoundBox::UpdateBounds(const BoundBox *pBox)
  78. {
  79. UpdateBounds(pBox->bmins, pBox->bmaxs);
  80. }
  81. //-----------------------------------------------------------------------------
  82. // Purpose:
  83. // Input : ptdest -
  84. //-----------------------------------------------------------------------------
  85. void BoundBox::GetBoundsCenter(Vector& ptdest)
  86. {
  87. ptdest = (bmins + bmaxs)/2.0f;
  88. }
  89. //-----------------------------------------------------------------------------
  90. // Purpose:
  91. // Input : pt -
  92. // Output : Returns true on success, false on failure.
  93. //-----------------------------------------------------------------------------
  94. bool BoundBox::ContainsPoint(const Vector& pt) const
  95. {
  96. for (int i = 0; i < 3; i++)
  97. {
  98. if (pt[i] < bmins[i] || pt[i] > bmaxs[i])
  99. {
  100. return(false);
  101. }
  102. }
  103. return(true);
  104. }
  105. //-----------------------------------------------------------------------------
  106. // Purpose:
  107. // Input : pfMins -
  108. // pfMaxs -
  109. // Output : Returns true on success, false on failure.
  110. //-----------------------------------------------------------------------------
  111. bool BoundBox::IsIntersectingBox(const Vector& pfMins, const Vector& pfMaxs) const
  112. {
  113. if ((bmins[0] >= pfMaxs[0]) || (bmaxs[0] <= pfMins[0]))
  114. {
  115. return(false);
  116. }
  117. if ((bmins[1] >= pfMaxs[1]) || (bmaxs[1] <= pfMins[1]))
  118. {
  119. return(false);
  120. }
  121. if ((bmins[2] >= pfMaxs[2]) || (bmaxs[2] <= pfMins[2]))
  122. {
  123. return(false);
  124. }
  125. return(true);
  126. }
  127. //-----------------------------------------------------------------------------
  128. // Purpose:
  129. // Input : pfMins -
  130. // pfMaxs -
  131. // Output : Returns true on success, false on failure.
  132. //-----------------------------------------------------------------------------
  133. bool BoundBox::IsInsideBox(const Vector& pfMins, const Vector& pfMaxs) const
  134. {
  135. if ((bmins[0] < pfMins[0]) || (bmaxs[0] > pfMaxs[0]))
  136. {
  137. return(false);
  138. }
  139. if ((bmins[1] < pfMins[1]) || (bmaxs[1] > pfMaxs[1]))
  140. {
  141. return(false);
  142. }
  143. if ((bmins[2] < pfMins[2]) || (bmaxs[2] > pfMaxs[2]))
  144. {
  145. return(false);
  146. }
  147. return(true);
  148. }
  149. //-----------------------------------------------------------------------------
  150. // Purpose: Returns whether this bounding box is valid, ie maxs >= mins.
  151. //-----------------------------------------------------------------------------
  152. bool BoundBox::IsValidBox(void) const
  153. {
  154. for (int i = 0; i < 3; i++)
  155. {
  156. if (bmins[i] > bmaxs[i])
  157. {
  158. return(false);
  159. }
  160. }
  161. return(true);
  162. }
  163. //-----------------------------------------------------------------------------
  164. // Purpose:
  165. // Input : size -
  166. //-----------------------------------------------------------------------------
  167. void BoundBox::GetBoundsSize(Vector& size)
  168. {
  169. size[0] = bmaxs[0] - bmins[0];
  170. size[1] = bmaxs[1] - bmins[1];
  171. size[2] = bmaxs[2] - bmins[2];
  172. }
  173. //-----------------------------------------------------------------------------
  174. // Purpose:
  175. // Input : iValue -
  176. // iGridSize -
  177. // Output :
  178. //-----------------------------------------------------------------------------
  179. static int Snap(/*int*/ float iValue, int iGridSize)
  180. {
  181. return (int)(V_rint(iValue/iGridSize) * iGridSize);
  182. }
  183. //-----------------------------------------------------------------------------
  184. // Purpose:
  185. // Input : iGridSize -
  186. //-----------------------------------------------------------------------------
  187. void BoundBox::SnapToGrid(int iGridSize)
  188. {
  189. // does not alter the size of the box .. snaps its minimal coordinates
  190. // to the grid size specified in iGridSize
  191. Vector size;
  192. GetBoundsSize(size);
  193. for(int i = 0; i < 3; i++)
  194. {
  195. bmins[i] = (float)Snap(/* YWB (int)*/bmins[i], iGridSize);
  196. bmaxs[i] = bmins[i] + size[i];
  197. }
  198. }
  199. //-----------------------------------------------------------------------------
  200. // Purpose:
  201. // Input : axis -
  202. //-----------------------------------------------------------------------------
  203. void BoundBox::Rotate90(int axis)
  204. {
  205. int e1 = AXIS_X, e2 = AXIS_Y;
  206. // get bounds center first
  207. Vector center;
  208. GetBoundsCenter(center);
  209. switch(axis)
  210. {
  211. case AXIS_Z:
  212. e1 = AXIS_X;
  213. e2 = AXIS_Y;
  214. break;
  215. case AXIS_X:
  216. e1 = AXIS_Y;
  217. e2 = AXIS_Z;
  218. break;
  219. case AXIS_Y:
  220. e1 = AXIS_X;
  221. e2 = AXIS_Z;
  222. break;
  223. }
  224. float tmp1, tmp2;
  225. tmp1 = bmins[e1] - center[e1] + center[e2];
  226. tmp2 = bmaxs[e1] - center[e1] + center[e2];
  227. bmins[e1] = bmins[e2] - center[e2] + center[e1];
  228. bmaxs[e1] = bmaxs[e2] - center[e2] + center[e1];
  229. bmins[e2] = tmp1;
  230. bmaxs[e2] = tmp2;
  231. }