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.

285 lines
6.7 KiB

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