Counter Strike : Global Offensive Source Code
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.

288 lines
6.9 KiB

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