colmath.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : WWMath *
  23. * *
  24. * $Archive:: /Commando/Code/wwmath/colmath.h $*
  25. * *
  26. * Author:: Greg Hjelstrom *
  27. * *
  28. * $Modtime:: 5/04/01 8:25p $*
  29. * *
  30. * $Revision:: 19 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #if defined(_MSC_VER)
  36. #pragma once
  37. #endif
  38. #ifndef COLMATH_H
  39. #define COLMATH_H
  40. #ifndef ALWAYS_H
  41. #include "always.h"
  42. #endif
  43. #ifndef VECTOR3_H
  44. #include "vector3.h"
  45. #endif
  46. #ifndef CASTRES_H
  47. #include "castres.h"
  48. #endif
  49. class AAPlaneClass;
  50. class PlaneClass;
  51. class LineSegClass;
  52. class TriClass;
  53. class SphereClass;
  54. class AABoxClass;
  55. class OBBoxClass;
  56. class FrustumClass;
  57. const float COLLISION_EPSILON = 0.001f;
  58. /*
  59. ** #define COLMATH_STAT_TRACKING to enable stat tracking for the collision math functions
  60. */
  61. #ifdef WWDEBUG
  62. #define COLMATH_STAT_TRACKING
  63. #endif
  64. /**
  65. ** CollisionMath
  66. ** This is a collection of the low-level math functions for collision detection.
  67. */
  68. class CollisionMath
  69. {
  70. public:
  71. ////////////////////////////////////////////////////////////////////////////////////////
  72. // Intersect Functions.
  73. // These functions simply return a bool indicating whether the two operands intersect.
  74. ////////////////////////////////////////////////////////////////////////////////////////
  75. static bool Intersection_Test(const AABoxClass & box,const TriClass & tri);
  76. static bool Intersection_Test(const AABoxClass & box,const AABoxClass & box2);
  77. static bool Intersection_Test(const AABoxClass & box,const OBBoxClass & box2);
  78. static bool Intersection_Test(const OBBoxClass & box,const TriClass & tri);
  79. static bool Intersection_Test(const OBBoxClass & box,const AABoxClass & box2);
  80. static bool Intersection_Test(const OBBoxClass & box,const OBBoxClass & box2);
  81. static bool Intersection_Test(const SphereClass & sphere,const AABoxClass & box);
  82. static bool Intersection_Test(const SphereClass & sphere,const OBBoxClass & box);
  83. ////////////////////////////////////////////////////////////////////////////////////////
  84. // Overlap Functions.
  85. // Classify the second operand with respect to the first operand.
  86. // For example Overlap_Test(plane,point) tests whether 'point' is in front of or
  87. // behind 'plane'.
  88. // OverlapType: This enumeration is the result of an overlap test.
  89. // It indicates whether the the object is in the positive (front/outside) space
  90. // of the volume, the negative (back/inside) space of the volume, or both (overlapping)
  91. ////////////////////////////////////////////////////////////////////////////////////////
  92. enum OverlapType
  93. {
  94. POS = 0x01,
  95. NEG = 0x02,
  96. ON = 0x04,
  97. BOTH = 0x08,
  98. OUTSIDE = POS,
  99. INSIDE = NEG,
  100. OVERLAPPED = BOTH,
  101. FRONT = POS,
  102. BACK = NEG
  103. };
  104. // AAPlane functions. Where is operand B with respect to this AAPlane
  105. static OverlapType Overlap_Test(const AAPlaneClass & plane,const Vector3 & point);
  106. static OverlapType Overlap_Test(const AAPlaneClass & plane,const LineSegClass & line);
  107. static OverlapType Overlap_Test(const AAPlaneClass & plane,const TriClass & tri);
  108. static OverlapType Overlap_Test(const AAPlaneClass & plane,const SphereClass & sphere);
  109. static OverlapType Overlap_Test(const AAPlaneClass & plane,const AABoxClass & box);
  110. static OverlapType Overlap_Test(const AAPlaneClass & plane,const OBBoxClass & box);
  111. // Plane functions. Where is operand B with respect to the plane
  112. static OverlapType Overlap_Test(const PlaneClass & plane,const Vector3 & point);
  113. static OverlapType Overlap_Test(const PlaneClass & plane,const LineSegClass & line);
  114. static OverlapType Overlap_Test(const PlaneClass & plane,const TriClass & tri);
  115. static OverlapType Overlap_Test(const PlaneClass & plane,const SphereClass & sphere);
  116. static OverlapType Overlap_Test(const PlaneClass & plane,const Vector3 & center,const Vector3 & extent);
  117. inline static OverlapType Overlap_Test(const PlaneClass & plane,const AABoxClass & box);
  118. static OverlapType Overlap_Test(const PlaneClass & plane,const OBBoxClass & box);
  119. // Sphere functions. Where is operand B with respect to the sphere
  120. static OverlapType Overlap_Test(const SphereClass & sphere,const Vector3 & point);
  121. static OverlapType Overlap_Test(const SphereClass & sphere,const LineSegClass & line);
  122. static OverlapType Overlap_Test(const SphereClass & sphere,const TriClass & tri);
  123. static OverlapType Overlap_Test(const SphereClass & sphere,const SphereClass & sphere2);
  124. static OverlapType Overlap_Test(const SphereClass & sphere,const AABoxClass & aabox);
  125. static OverlapType Overlap_Test(const SphereClass & sphere,const OBBoxClass & obbox);
  126. // AABox functions. Where is operand B with respect to the AABox
  127. static OverlapType Overlap_Test(const AABoxClass & box,const Vector3 & point);
  128. static OverlapType Overlap_Test(const AABoxClass & box,const LineSegClass & line);
  129. static OverlapType Overlap_Test(const AABoxClass & box,const TriClass & tri);
  130. static OverlapType Overlap_Test(const AABoxClass & box,const AABoxClass & box2);
  131. static OverlapType Overlap_Test(const AABoxClass & box,const OBBoxClass & obbox);
  132. static OverlapType Overlap_Test(const AABoxClass & box,const SphereClass & sphere);
  133. // OBBox functions, where is operand B with respect to the OBBox
  134. static OverlapType Overlap_Test(const OBBoxClass & box,const Vector3 & point);
  135. static OverlapType Overlap_Test(const OBBoxClass & box,const LineSegClass & line);
  136. static OverlapType Overlap_Test(const OBBoxClass & box,const TriClass & tri);
  137. static OverlapType Overlap_Test(const OBBoxClass & box,const AABoxClass & box2);
  138. static OverlapType Overlap_Test(const OBBoxClass & box,const OBBoxClass & box2);
  139. // Frustum functions
  140. static OverlapType Overlap_Test(const FrustumClass & frustum,const Vector3 & point);
  141. static OverlapType Overlap_Test(const FrustumClass & frustum,const TriClass & tri);
  142. static OverlapType Overlap_Test(const FrustumClass & frustum,const SphereClass & sphere);
  143. static OverlapType Overlap_Test(const FrustumClass & frustum,const AABoxClass & box);
  144. static OverlapType Overlap_Test(const FrustumClass & frustum,const OBBoxClass & box);
  145. // Frustum functions for hierachical culling systems.
  146. // At your root node, just pass in planes_passed = 0, then the variable will be modified to
  147. // indicate which planes that volume was inside. You can then pass that value in for the
  148. // test of all child nodes and optimize away some of the tests. See AABTreeCullSystemClass
  149. // for an example usage.
  150. static OverlapType Overlap_Test(const FrustumClass & frustum,const AABoxClass & box,int & planes_passed);
  151. static OverlapType Overlap_Test(const FrustumClass & frustum,const OBBoxClass & box,int & planes_passed);
  152. // Miscellaneous other Overlap tests
  153. static OverlapType Overlap_Test(const Vector3 & min,const Vector3 & max,const LineSegClass & line);
  154. ////////////////////////////////////////////////////////////////////////////////////////
  155. // Collision Functions.
  156. // Collide the first operand into the last operand.
  157. // For example Collide(box,move,tri) tests for collision between a box moving into
  158. // a triangle.
  159. ////////////////////////////////////////////////////////////////////////////////////////
  160. // Line segment functions. Intersect this line segment with the given object
  161. static bool Collide(const LineSegClass & line,const AAPlaneClass & plane,CastResultStruct * result);
  162. static bool Collide(const LineSegClass & line,const PlaneClass & plane,CastResultStruct * result);
  163. static bool Collide(const LineSegClass & line,const TriClass & tri,CastResultStruct * result);
  164. static bool Collide(const LineSegClass & line,const SphereClass & sphere,CastResultStruct * result);
  165. static bool Collide(const LineSegClass & line,const AABoxClass & box,CastResultStruct * result);
  166. static bool Collide(const LineSegClass & line,const OBBoxClass & box,CastResultStruct * result);
  167. // AABox functions
  168. static bool Collide(const AABoxClass & box,const Vector3 & move,const PlaneClass & plane,CastResultStruct * result);
  169. static bool Collide(const AABoxClass & box,const Vector3 & move,const TriClass & tri,CastResultStruct * result);
  170. static bool Collide(const AABoxClass & box,const Vector3 & move,const AABoxClass & box2,CastResultStruct * result);
  171. static bool Collide(const AABoxClass & box,const Vector3 & move,const OBBoxClass & box2,const Vector3 & move2,CastResultStruct * result);
  172. // OBBox functions
  173. static bool Collide(const OBBoxClass & box,const Vector3 & move,const PlaneClass & plane,CastResultStruct * result);
  174. static bool Collide(const OBBoxClass & box,const Vector3 & move,const TriClass & tri,const Vector3 & move2,CastResultStruct * result);
  175. static bool Collide(const OBBoxClass & box,const Vector3 & move,const AABoxClass & box2,const Vector3 & move2,CastResultStruct * result);
  176. static bool Collide(const OBBoxClass & box,const Vector3 & move,const OBBoxClass & box2,const Vector3 & move2,CastResultStruct * result);
  177. ////////////////////////////////////////////////////////////////////////////////////////
  178. // Stats
  179. // Note that these functions will only work if you have stat tracking enabled
  180. ////////////////////////////////////////////////////////////////////////////////////////
  181. struct ColmathStatsStruct
  182. {
  183. ColmathStatsStruct(void);
  184. void Reset(void);
  185. int TotalCollisionCount;
  186. int TotalCollisionHitCount;
  187. int CollisionRayTriCount;
  188. int CollisionRayTriHitCount;
  189. int CollisionAABoxTriCount;
  190. int CollisionAABoxTriHitCount;
  191. int CollisionAABoxAABoxCount;
  192. int CollisionAABoxAABoxHitCount;
  193. int CollisionOBBoxTriCount;
  194. int CollisionOBBoxTriHitCount;
  195. int CollisionOBBoxAABoxCount;
  196. int CollisionOBBoxAABoxHitCount;
  197. int CollisionOBBoxOBBoxCount;
  198. int CollisionOBBoxOBBoxHitCount;
  199. };
  200. static void Reset_Stats(void) { Stats.Reset(); }
  201. static const ColmathStatsStruct & Get_Current_Stats(void) { return Stats; }
  202. private:
  203. static OverlapType eval_overlap_mask(int mask);
  204. static OverlapType eval_overlap_collision(const CastResultStruct & res);
  205. static const float COINCIDENCE_EPSILON;
  206. static ColmathStatsStruct Stats;
  207. };
  208. inline CollisionMath::OverlapType CollisionMath::eval_overlap_mask(int mask)
  209. {
  210. // check if all verts are "ON"
  211. if (mask == ON) {
  212. return ON;
  213. }
  214. // check if all verts are either "ON" or "POS"
  215. if ((mask & ~(POS | ON)) == 0) {
  216. return POS;
  217. }
  218. // check if all verts are either "ON" or "BACK"
  219. if ((mask & ~(NEG | ON)) == 0) {
  220. return NEG;
  221. }
  222. // otherwise, poly spans the plane.
  223. return BOTH;
  224. }
  225. inline CollisionMath::OverlapType CollisionMath::eval_overlap_collision(const CastResultStruct & res)
  226. {
  227. if (res.Fraction < 1.0f) {
  228. return BOTH;
  229. } else {
  230. if (res.StartBad) {
  231. return NEG;
  232. } else {
  233. return POS;
  234. }
  235. }
  236. }
  237. /*
  238. ** Stat tracking Macros
  239. */
  240. #ifdef COLMATH_STAT_TRACKING
  241. #define TRACK_COLLISION_RAY_TRI Stats.CollisionRayTriCount++; Stats.TotalCollisionCount++;
  242. #define TRACK_COLLISION_RAY_TRI_HIT Stats.CollisionRayTriHitCount++; Stats.TotalCollisionHitCount;
  243. #define TRACK_COLLISION_AABOX_TRI Stats.CollisionAABoxTriCount++; Stats.TotalCollisionCount++;
  244. #define TRACK_COLLISION_AABOX_TRI_HIT Stats.CollisionAABoxTriHitCount++; Stats.TotalCollisionHitCount++;
  245. #define TRACK_COLLISION_AABOX_AABOX Stats.CollisionAABoxAABoxCount++; Stats.TotalCollisionCount++;
  246. #define TRACK_COLLISION_AABOX_AABOX_HIT Stats.CollisionAABoxAABoxHitCount++; Stats.TotalCollisionHitCount++;
  247. #define TRACK_COLLISION_OBBOX_TRI Stats.CollisionOBBoxTriCount++; Stats.TotalCollisionCount++;
  248. #define TRACK_COLLISION_OBBOX_TRI_HIT Stats.CollisionOBBoxTriHitCount++; Stats.TotalCollisionHitCount++;
  249. #define TRACK_COLLISION_OBBOX_AABOX Stats.CollisionOBBoxAABoxCount++; Stats.TotalCollisionCount++;
  250. #define TRACK_COLLISION_OBBOX_AABOX_HIT Stats.CollisionOBBoxAABoxHitCount++; Stats.TotalCollisionHitCount++;
  251. #define TRACK_COLLISION_OBBOX_OBBOX Stats.CollisionOBBoxOBBoxCount++; Stats.TotalCollisionCount++;
  252. #define TRACK_COLLISION_OBBOX_OBBOX_HIT Stats.CollisionOBBoxOBBoxHitCount++; Stats.TotalCollisionHitCount++;
  253. #else
  254. #define TRACK_COLLISION_RAY_TRI
  255. #define TRACK_COLLISION_RAY_TRI_HIT
  256. #define TRACK_COLLISION_AABOX_TRI
  257. #define TRACK_COLLISION_AABOX_TRI_HIT
  258. #define TRACK_COLLISION_AABOX_AABOX
  259. #define TRACK_COLLISION_AABOX_AABOX_HIT
  260. #define TRACK_COLLISION_OBBOX_TRI
  261. #define TRACK_COLLISION_OBBOX_TRI_HIT
  262. #define TRACK_COLLISION_OBBOX_AABOX
  263. #define TRACK_COLLISION_OBBOX_AABOX_HIT
  264. #define TRACK_COLLISION_OBBOX_OBBOX
  265. #define TRACK_COLLISION_OBBOX_OBBOX_HIT
  266. #endif
  267. #endif // COLMATH_H