DirectXCollision.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. //-------------------------------------------------------------------------------------
  2. // DirectXCollision.h -- C++ Collision Math library
  3. //
  4. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  5. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  6. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  7. // PARTICULAR PURPOSE.
  8. //
  9. // Copyright (c) Microsoft Corporation. All rights reserved.
  10. //
  11. // http://go.microsoft.com/fwlink/?LinkID=615560
  12. //-------------------------------------------------------------------------------------
  13. #pragma once
  14. #include "DirectXMath.h"
  15. namespace DirectX
  16. {
  17. enum ContainmentType
  18. {
  19. DISJOINT = 0,
  20. INTERSECTS = 1,
  21. CONTAINS = 2,
  22. };
  23. enum PlaneIntersectionType
  24. {
  25. FRONT = 0,
  26. INTERSECTING = 1,
  27. BACK = 2,
  28. };
  29. struct BoundingBox;
  30. struct BoundingOrientedBox;
  31. struct BoundingFrustum;
  32. #pragma warning(push)
  33. #pragma warning(disable:4324 4820)
  34. // C4324: alignment padding warnings
  35. // C4820: Off by default noise
  36. //-------------------------------------------------------------------------------------
  37. // Bounding sphere
  38. //-------------------------------------------------------------------------------------
  39. struct BoundingSphere
  40. {
  41. XMFLOAT3 Center; // Center of the sphere.
  42. float Radius; // Radius of the sphere.
  43. // Creators
  44. BoundingSphere() : Center(0,0,0), Radius( 1.f ) {}
  45. XM_CONSTEXPR BoundingSphere( _In_ const XMFLOAT3& center, _In_ float radius )
  46. : Center(center), Radius(radius) {}
  47. BoundingSphere( _In_ const BoundingSphere& sp )
  48. : Center(sp.Center), Radius(sp.Radius) {}
  49. // Methods
  50. BoundingSphere& operator=( _In_ const BoundingSphere& sp ) { Center = sp.Center; Radius = sp.Radius; return *this; }
  51. void XM_CALLCONV Transform( _Out_ BoundingSphere& Out, _In_ FXMMATRIX M ) const;
  52. void XM_CALLCONV Transform( _Out_ BoundingSphere& Out, _In_ float Scale, _In_ FXMVECTOR Rotation, _In_ FXMVECTOR Translation ) const;
  53. // Transform the sphere
  54. ContainmentType XM_CALLCONV Contains( _In_ FXMVECTOR Point ) const;
  55. ContainmentType XM_CALLCONV Contains( _In_ FXMVECTOR V0, _In_ FXMVECTOR V1, _In_ FXMVECTOR V2 ) const;
  56. ContainmentType Contains( _In_ const BoundingSphere& sh ) const;
  57. ContainmentType Contains( _In_ const BoundingBox& box ) const;
  58. ContainmentType Contains( _In_ const BoundingOrientedBox& box ) const;
  59. ContainmentType Contains( _In_ const BoundingFrustum& fr ) const;
  60. bool Intersects( _In_ const BoundingSphere& sh ) const;
  61. bool Intersects( _In_ const BoundingBox& box ) const;
  62. bool Intersects( _In_ const BoundingOrientedBox& box ) const;
  63. bool Intersects( _In_ const BoundingFrustum& fr ) const;
  64. bool XM_CALLCONV Intersects( _In_ FXMVECTOR V0, _In_ FXMVECTOR V1, _In_ FXMVECTOR V2 ) const;
  65. // Triangle-sphere test
  66. PlaneIntersectionType XM_CALLCONV Intersects( _In_ FXMVECTOR Plane ) const;
  67. // Plane-sphere test
  68. bool XM_CALLCONV Intersects( _In_ FXMVECTOR Origin, _In_ FXMVECTOR Direction, _Out_ float& Dist ) const;
  69. // Ray-sphere test
  70. ContainmentType XM_CALLCONV ContainedBy( _In_ FXMVECTOR Plane0, _In_ FXMVECTOR Plane1, _In_ FXMVECTOR Plane2,
  71. _In_ GXMVECTOR Plane3, _In_ HXMVECTOR Plane4, _In_ HXMVECTOR Plane5 ) const;
  72. // Test sphere against six planes (see BoundingFrustum::GetPlanes)
  73. // Static methods
  74. static void CreateMerged( _Out_ BoundingSphere& Out, _In_ const BoundingSphere& S1, _In_ const BoundingSphere& S2 );
  75. static void CreateFromBoundingBox( _Out_ BoundingSphere& Out, _In_ const BoundingBox& box );
  76. static void CreateFromBoundingBox( _Out_ BoundingSphere& Out, _In_ const BoundingOrientedBox& box );
  77. static void CreateFromPoints( _Out_ BoundingSphere& Out, _In_ size_t Count,
  78. _In_reads_bytes_(sizeof(XMFLOAT3)+Stride*(Count-1)) const XMFLOAT3* pPoints, _In_ size_t Stride );
  79. static void CreateFromFrustum( _Out_ BoundingSphere& Out, _In_ const BoundingFrustum& fr );
  80. };
  81. //-------------------------------------------------------------------------------------
  82. // Axis-aligned bounding box
  83. //-------------------------------------------------------------------------------------
  84. struct BoundingBox
  85. {
  86. static const size_t CORNER_COUNT = 8;
  87. XMFLOAT3 Center; // Center of the box.
  88. XMFLOAT3 Extents; // Distance from the center to each side.
  89. // Creators
  90. BoundingBox() : Center(0,0,0), Extents( 1.f, 1.f, 1.f ) {}
  91. XM_CONSTEXPR BoundingBox( _In_ const XMFLOAT3& center, _In_ const XMFLOAT3& extents )
  92. : Center(center), Extents(extents) {}
  93. BoundingBox( _In_ const BoundingBox& box ) : Center(box.Center), Extents(box.Extents) {}
  94. // Methods
  95. BoundingBox& operator=( _In_ const BoundingBox& box) { Center = box.Center; Extents = box.Extents; return *this; }
  96. void XM_CALLCONV Transform( _Out_ BoundingBox& Out, _In_ FXMMATRIX M ) const;
  97. void XM_CALLCONV Transform( _Out_ BoundingBox& Out, _In_ float Scale, _In_ FXMVECTOR Rotation, _In_ FXMVECTOR Translation ) const;
  98. void GetCorners( _Out_writes_(8) XMFLOAT3* Corners ) const;
  99. // Gets the 8 corners of the box
  100. ContainmentType XM_CALLCONV Contains( _In_ FXMVECTOR Point ) const;
  101. ContainmentType XM_CALLCONV Contains( _In_ FXMVECTOR V0, _In_ FXMVECTOR V1, _In_ FXMVECTOR V2 ) const;
  102. ContainmentType Contains( _In_ const BoundingSphere& sh ) const;
  103. ContainmentType Contains( _In_ const BoundingBox& box ) const;
  104. ContainmentType Contains( _In_ const BoundingOrientedBox& box ) const;
  105. ContainmentType Contains( _In_ const BoundingFrustum& fr ) const;
  106. bool Intersects( _In_ const BoundingSphere& sh ) const;
  107. bool Intersects( _In_ const BoundingBox& box ) const;
  108. bool Intersects( _In_ const BoundingOrientedBox& box ) const;
  109. bool Intersects( _In_ const BoundingFrustum& fr ) const;
  110. bool XM_CALLCONV Intersects( _In_ FXMVECTOR V0, _In_ FXMVECTOR V1, _In_ FXMVECTOR V2 ) const;
  111. // Triangle-Box test
  112. PlaneIntersectionType XM_CALLCONV Intersects( _In_ FXMVECTOR Plane ) const;
  113. // Plane-box test
  114. bool XM_CALLCONV Intersects( _In_ FXMVECTOR Origin, _In_ FXMVECTOR Direction, _Out_ float& Dist ) const;
  115. // Ray-Box test
  116. ContainmentType XM_CALLCONV ContainedBy( _In_ FXMVECTOR Plane0, _In_ FXMVECTOR Plane1, _In_ FXMVECTOR Plane2,
  117. _In_ GXMVECTOR Plane3, _In_ HXMVECTOR Plane4, _In_ HXMVECTOR Plane5 ) const;
  118. // Test box against six planes (see BoundingFrustum::GetPlanes)
  119. // Static methods
  120. static void CreateMerged( _Out_ BoundingBox& Out, _In_ const BoundingBox& b1, _In_ const BoundingBox& b2 );
  121. static void CreateFromSphere( _Out_ BoundingBox& Out, _In_ const BoundingSphere& sh );
  122. static void XM_CALLCONV CreateFromPoints( _Out_ BoundingBox& Out, _In_ FXMVECTOR pt1, _In_ FXMVECTOR pt2 );
  123. static void CreateFromPoints( _Out_ BoundingBox& Out, _In_ size_t Count,
  124. _In_reads_bytes_(sizeof(XMFLOAT3)+Stride*(Count-1)) const XMFLOAT3* pPoints, _In_ size_t Stride );
  125. };
  126. //-------------------------------------------------------------------------------------
  127. // Oriented bounding box
  128. //-------------------------------------------------------------------------------------
  129. struct BoundingOrientedBox
  130. {
  131. static const size_t CORNER_COUNT = 8;
  132. XMFLOAT3 Center; // Center of the box.
  133. XMFLOAT3 Extents; // Distance from the center to each side.
  134. XMFLOAT4 Orientation; // Unit quaternion representing rotation (box -> world).
  135. // Creators
  136. BoundingOrientedBox() : Center(0,0,0), Extents( 1.f, 1.f, 1.f ), Orientation(0,0,0, 1.f ) {}
  137. XM_CONSTEXPR BoundingOrientedBox( _In_ const XMFLOAT3& _Center, _In_ const XMFLOAT3& _Extents, _In_ const XMFLOAT4& _Orientation )
  138. : Center(_Center), Extents(_Extents), Orientation(_Orientation) {}
  139. BoundingOrientedBox( _In_ const BoundingOrientedBox& box )
  140. : Center(box.Center), Extents(box.Extents), Orientation(box.Orientation) {}
  141. // Methods
  142. BoundingOrientedBox& operator=( _In_ const BoundingOrientedBox& box ) { Center = box.Center; Extents = box.Extents; Orientation = box.Orientation; return *this; }
  143. void XM_CALLCONV Transform( _Out_ BoundingOrientedBox& Out, _In_ FXMMATRIX M ) const;
  144. void XM_CALLCONV Transform( _Out_ BoundingOrientedBox& Out, _In_ float Scale, _In_ FXMVECTOR Rotation, _In_ FXMVECTOR Translation ) const;
  145. void GetCorners( _Out_writes_(8) XMFLOAT3* Corners ) const;
  146. // Gets the 8 corners of the box
  147. ContainmentType XM_CALLCONV Contains( _In_ FXMVECTOR Point ) const;
  148. ContainmentType XM_CALLCONV Contains( _In_ FXMVECTOR V0, _In_ FXMVECTOR V1, _In_ FXMVECTOR V2 ) const;
  149. ContainmentType Contains( _In_ const BoundingSphere& sh ) const;
  150. ContainmentType Contains( _In_ const BoundingBox& box ) const;
  151. ContainmentType Contains( _In_ const BoundingOrientedBox& box ) const;
  152. ContainmentType Contains( _In_ const BoundingFrustum& fr ) const;
  153. bool Intersects( _In_ const BoundingSphere& sh ) const;
  154. bool Intersects( _In_ const BoundingBox& box ) const;
  155. bool Intersects( _In_ const BoundingOrientedBox& box ) const;
  156. bool Intersects( _In_ const BoundingFrustum& fr ) const;
  157. bool XM_CALLCONV Intersects( _In_ FXMVECTOR V0, _In_ FXMVECTOR V1, _In_ FXMVECTOR V2 ) const;
  158. // Triangle-OrientedBox test
  159. PlaneIntersectionType XM_CALLCONV Intersects( _In_ FXMVECTOR Plane ) const;
  160. // Plane-OrientedBox test
  161. bool XM_CALLCONV Intersects( _In_ FXMVECTOR Origin, _In_ FXMVECTOR Direction, _Out_ float& Dist ) const;
  162. // Ray-OrientedBox test
  163. ContainmentType XM_CALLCONV ContainedBy( _In_ FXMVECTOR Plane0, _In_ FXMVECTOR Plane1, _In_ FXMVECTOR Plane2,
  164. _In_ GXMVECTOR Plane3, _In_ HXMVECTOR Plane4, _In_ HXMVECTOR Plane5 ) const;
  165. // Test OrientedBox against six planes (see BoundingFrustum::GetPlanes)
  166. // Static methods
  167. static void CreateFromBoundingBox( _Out_ BoundingOrientedBox& Out, _In_ const BoundingBox& box );
  168. static void CreateFromPoints( _Out_ BoundingOrientedBox& Out, _In_ size_t Count,
  169. _In_reads_bytes_(sizeof(XMFLOAT3)+Stride*(Count-1)) const XMFLOAT3* pPoints, _In_ size_t Stride );
  170. };
  171. //-------------------------------------------------------------------------------------
  172. // Bounding frustum
  173. //-------------------------------------------------------------------------------------
  174. struct BoundingFrustum
  175. {
  176. static const size_t CORNER_COUNT = 8;
  177. XMFLOAT3 Origin; // Origin of the frustum (and projection).
  178. XMFLOAT4 Orientation; // Quaternion representing rotation.
  179. float RightSlope; // Positive X slope (X/Z).
  180. float LeftSlope; // Negative X slope.
  181. float TopSlope; // Positive Y slope (Y/Z).
  182. float BottomSlope; // Negative Y slope.
  183. float Near, Far; // Z of the near plane and far plane.
  184. // Creators
  185. BoundingFrustum() : Origin(0,0,0), Orientation(0,0,0, 1.f), RightSlope( 1.f ), LeftSlope( -1.f ),
  186. TopSlope( 1.f ), BottomSlope( -1.f ), Near(0), Far( 1.f ) {}
  187. XM_CONSTEXPR BoundingFrustum( _In_ const XMFLOAT3& _Origin, _In_ const XMFLOAT4& _Orientation,
  188. _In_ float _RightSlope, _In_ float _LeftSlope, _In_ float _TopSlope, _In_ float _BottomSlope,
  189. _In_ float _Near, _In_ float _Far )
  190. : Origin(_Origin), Orientation(_Orientation),
  191. RightSlope(_RightSlope), LeftSlope(_LeftSlope), TopSlope(_TopSlope), BottomSlope(_BottomSlope),
  192. Near(_Near), Far(_Far) {}
  193. BoundingFrustum( _In_ const BoundingFrustum& fr )
  194. : Origin(fr.Origin), Orientation(fr.Orientation), RightSlope(fr.RightSlope), LeftSlope(fr.LeftSlope),
  195. TopSlope(fr.TopSlope), BottomSlope(fr.BottomSlope), Near(fr.Near), Far(fr.Far) {}
  196. BoundingFrustum( _In_ CXMMATRIX Projection ) { CreateFromMatrix( *this, Projection ); }
  197. // Methods
  198. BoundingFrustum& operator=( _In_ const BoundingFrustum& fr ) { Origin=fr.Origin; Orientation=fr.Orientation;
  199. RightSlope=fr.RightSlope; LeftSlope=fr.LeftSlope;
  200. TopSlope=fr.TopSlope; BottomSlope=fr.BottomSlope;
  201. Near=fr.Near; Far=fr.Far; return *this; }
  202. void XM_CALLCONV Transform( _Out_ BoundingFrustum& Out, _In_ FXMMATRIX M ) const;
  203. void XM_CALLCONV Transform( _Out_ BoundingFrustum& Out, _In_ float Scale, _In_ FXMVECTOR Rotation, _In_ FXMVECTOR Translation ) const;
  204. void GetCorners( _Out_writes_(8) XMFLOAT3* Corners ) const;
  205. // Gets the 8 corners of the frustum
  206. ContainmentType XM_CALLCONV Contains( _In_ FXMVECTOR Point ) const;
  207. ContainmentType XM_CALLCONV Contains( _In_ FXMVECTOR V0, _In_ FXMVECTOR V1, _In_ FXMVECTOR V2 ) const;
  208. ContainmentType Contains( _In_ const BoundingSphere& sp ) const;
  209. ContainmentType Contains( _In_ const BoundingBox& box ) const;
  210. ContainmentType Contains( _In_ const BoundingOrientedBox& box ) const;
  211. ContainmentType Contains( _In_ const BoundingFrustum& fr ) const;
  212. // Frustum-Frustum test
  213. bool Intersects( _In_ const BoundingSphere& sh ) const;
  214. bool Intersects( _In_ const BoundingBox& box ) const;
  215. bool Intersects( _In_ const BoundingOrientedBox& box ) const;
  216. bool Intersects( _In_ const BoundingFrustum& fr ) const;
  217. bool XM_CALLCONV Intersects( _In_ FXMVECTOR V0, _In_ FXMVECTOR V1, _In_ FXMVECTOR V2 ) const;
  218. // Triangle-Frustum test
  219. PlaneIntersectionType XM_CALLCONV Intersects( _In_ FXMVECTOR Plane ) const;
  220. // Plane-Frustum test
  221. bool XM_CALLCONV Intersects( _In_ FXMVECTOR rayOrigin, _In_ FXMVECTOR Direction, _Out_ float& Dist ) const;
  222. // Ray-Frustum test
  223. ContainmentType XM_CALLCONV ContainedBy( _In_ FXMVECTOR Plane0, _In_ FXMVECTOR Plane1, _In_ FXMVECTOR Plane2,
  224. _In_ GXMVECTOR Plane3, _In_ HXMVECTOR Plane4, _In_ HXMVECTOR Plane5 ) const;
  225. // Test frustum against six planes (see BoundingFrustum::GetPlanes)
  226. void GetPlanes( _Out_opt_ XMVECTOR* NearPlane, _Out_opt_ XMVECTOR* FarPlane, _Out_opt_ XMVECTOR* RightPlane,
  227. _Out_opt_ XMVECTOR* LeftPlane, _Out_opt_ XMVECTOR* TopPlane, _Out_opt_ XMVECTOR* BottomPlane ) const;
  228. // Create 6 Planes representation of Frustum
  229. // Static methods
  230. static void XM_CALLCONV CreateFromMatrix( _Out_ BoundingFrustum& Out, _In_ FXMMATRIX Projection );
  231. };
  232. //-----------------------------------------------------------------------------
  233. // Triangle intersection testing routines.
  234. //-----------------------------------------------------------------------------
  235. namespace TriangleTests
  236. {
  237. bool XM_CALLCONV Intersects( _In_ FXMVECTOR Origin, _In_ FXMVECTOR Direction, _In_ FXMVECTOR V0, _In_ GXMVECTOR V1, _In_ HXMVECTOR V2, _Out_ float& Dist );
  238. // Ray-Triangle
  239. bool XM_CALLCONV Intersects( _In_ FXMVECTOR A0, _In_ FXMVECTOR A1, _In_ FXMVECTOR A2, _In_ GXMVECTOR B0, _In_ HXMVECTOR B1, _In_ HXMVECTOR B2 );
  240. // Triangle-Triangle
  241. PlaneIntersectionType XM_CALLCONV Intersects( _In_ FXMVECTOR V0, _In_ FXMVECTOR V1, _In_ FXMVECTOR V2, _In_ GXMVECTOR Plane );
  242. // Plane-Triangle
  243. ContainmentType XM_CALLCONV ContainedBy( _In_ FXMVECTOR V0, _In_ FXMVECTOR V1, _In_ FXMVECTOR V2,
  244. _In_ GXMVECTOR Plane0, _In_ HXMVECTOR Plane1, _In_ HXMVECTOR Plane2,
  245. _In_ CXMVECTOR Plane3, _In_ CXMVECTOR Plane4, _In_ CXMVECTOR Plane5 );
  246. // Test a triangle against six planes at once (see BoundingFrustum::GetPlanes)
  247. };
  248. #pragma warning(pop)
  249. /****************************************************************************
  250. *
  251. * Implementation
  252. *
  253. ****************************************************************************/
  254. #pragma warning(push)
  255. #pragma warning(disable : 4068 4365 4616 6001)
  256. // C4068/4616: ignore unknown pragmas
  257. // C4365: Off by default noise
  258. // C6001: False positives
  259. #ifdef _PREFAST_
  260. #pragma prefast(push)
  261. #pragma prefast(disable : 25000, "FXMVECTOR is 16 bytes")
  262. #endif
  263. #include "DirectXCollision.inl"
  264. #ifdef _PREFAST_
  265. #pragma prefast(pop)
  266. #endif
  267. #pragma warning(pop)
  268. }; // namespace DirectX