ShapeIntersectionTests.cpp 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <AzCore/UnitTest/TestTypes.h>
  9. #include <AzCore/Math/Quaternion.h>
  10. #include <AzCore/Math/Frustum.h>
  11. #include <AzCore/Math/Sphere.h>
  12. #include <AzCore/Math/ShapeIntersection.h>
  13. #include <AZTestShared/Math/MathTestHelpers.h>
  14. namespace UnitTest
  15. {
  16. TEST(MATH_ShapeIntersection, Test)
  17. {
  18. //Assumes +x runs to the 'right', +y runs 'out' and +z points 'up'
  19. //A frustum is defined by 6 planes. In this case a box shape.
  20. AZ::Plane near_value = AZ::Plane::CreateFromNormalAndPoint(AZ::Vector3(0.f, 1.f, 0.f), AZ::Vector3(0.f, -5.f, 0.f));
  21. AZ::Plane far_value = AZ::Plane::CreateFromNormalAndPoint(AZ::Vector3(0.f, -1.f, 0.f), AZ::Vector3(0.f, 5.f, 0.f));
  22. AZ::Plane left = AZ::Plane::CreateFromNormalAndPoint(AZ::Vector3(1.f, 0.f, 0.f), AZ::Vector3(-5.f, 0.f, 0.f));
  23. AZ::Plane right = AZ::Plane::CreateFromNormalAndPoint(AZ::Vector3(-1.f, 0.f, 0.f), AZ::Vector3(5.f, 0.f, 0.f));
  24. AZ::Plane top = AZ::Plane::CreateFromNormalAndPoint(AZ::Vector3(0.f, 0.f, -1.f), AZ::Vector3(0.f, 0.f, 5.f));
  25. AZ::Plane bottom = AZ::Plane::CreateFromNormalAndPoint(AZ::Vector3(0.f, 0.f, 1.f), AZ::Vector3(0.f, 0.f, -5.f));
  26. AZ::Frustum frustum(near_value, far_value, left, right, top, bottom);
  27. AZ::Plane near1 = AZ::Plane::CreateFromNormalAndPoint(AZ::Vector3(0.f, 1.f, 0.f), AZ::Vector3(0.f, -2.f, 0.f));
  28. AZ::Plane far1 = AZ::Plane::CreateFromNormalAndPoint(AZ::Vector3(0.f, -1.f, 0.f), AZ::Vector3(0.f, 2.f, 0.f));
  29. AZ::Plane left1 = AZ::Plane::CreateFromNormalAndPoint(AZ::Vector3(1.f, 0.f, 0.f), AZ::Vector3(-2.f, 0.f, 0.f));
  30. AZ::Plane right1 = AZ::Plane::CreateFromNormalAndPoint(AZ::Vector3(-1.f, 0.f, 0.f), AZ::Vector3(2.f, 0.f, 0.f));
  31. AZ::Plane top1 = AZ::Plane::CreateFromNormalAndPoint(AZ::Vector3(0.f, 0.f, -1.f), AZ::Vector3(0.f, 0.f, 2.f));
  32. AZ::Plane bottom1 = AZ::Plane::CreateFromNormalAndPoint(AZ::Vector3(0.f, 0.f, 1.f), AZ::Vector3(0.f, 0.f, -2.f));
  33. AZ::Frustum frustum1(near1, far1, left1, right1, top1, bottom1);
  34. AZ::Sphere unitSphere = AZ::Sphere::CreateUnitSphere();
  35. AZ::Sphere sphere1(AZ::Vector3(10.f, 10.f, 10.f), 20.f);
  36. AZ::Sphere sphere2(AZ::Vector3(12.f, 12.f, 12.f), 13.f);
  37. AZ::Aabb unitBox = AZ::Aabb::CreateCenterHalfExtents(AZ::Vector3::CreateZero(), AZ::Vector3(1.f, 1.f, 1.f));
  38. AZ::Aabb aabb = AZ::Aabb::CreateCenterHalfExtents(AZ::Vector3(10.f, 10.f, 10.f), AZ::Vector3(1.f, 1.f, 1.f));
  39. AZ::Aabb aabb1 = AZ::Aabb::CreateCenterHalfExtents(AZ::Vector3(10.f, 10.f, 10.f), AZ::Vector3(100.f, 100.f, 100.f));
  40. AZ::Aabb maxSizeAabb = AZ::Aabb::CreateFromMinMax(AZ::Vector3(-AZ::Constants::FloatMax), AZ::Vector3(AZ::Constants::FloatMax));
  41. AZ::Vector3 point(0.f, 0.f, 0.f);
  42. AZ::Vector3 point1(10.f, 10.f, 10.f);
  43. {
  44. AZ::Vector3 intersectionPoint;
  45. EXPECT_TRUE(AZ::ShapeIntersection::IntersectThreePlanes(near_value, left, bottom, intersectionPoint));
  46. EXPECT_THAT(intersectionPoint, IsClose(AZ::Vector3(-5.f, -5.f, -5.f)));
  47. EXPECT_FALSE(AZ::ShapeIntersection::IntersectThreePlanes(near_value, far_value, bottom, intersectionPoint));
  48. }
  49. {
  50. AZ::Vector3 intersectionPoint;
  51. EXPECT_TRUE(AZ::ShapeIntersection::IntersectThreePlanes(near_value, left, bottom, intersectionPoint));
  52. EXPECT_THAT(intersectionPoint, IsClose(AZ::Vector3(-5.f, -5.f, -5.f)));
  53. EXPECT_FALSE(AZ::ShapeIntersection::IntersectThreePlanes(near_value, far_value, bottom, intersectionPoint));
  54. }
  55. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(aabb, aabb1));
  56. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(aabb1, aabb));
  57. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(unitSphere, unitBox));
  58. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(unitSphere, unitBox));
  59. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(unitSphere, aabb1));
  60. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(unitSphere, frustum));
  61. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(sphere1, frustum));
  62. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(unitSphere, sphere1));
  63. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(sphere1, unitSphere));
  64. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(frustum, unitBox));
  65. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(frustum, aabb1));
  66. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(sphere1, far_value));
  67. // Verify that an AABB that covers the max floating point range successfully overlaps with a frustum and doesn't hit any
  68. // floating-point math overflows.
  69. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(frustum, maxSizeAabb));
  70. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(frustum, aabb));
  71. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(unitSphere, aabb));
  72. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(unitSphere, sphere2));
  73. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(unitSphere, near_value));
  74. EXPECT_FALSE(AZ::ShapeIntersection::Contains(aabb, aabb1));
  75. EXPECT_TRUE(AZ::ShapeIntersection::Contains(aabb1, aabb));
  76. EXPECT_TRUE(AZ::ShapeIntersection::Contains(unitBox, unitSphere));
  77. EXPECT_FALSE(AZ::ShapeIntersection::Contains(aabb, unitSphere));
  78. EXPECT_TRUE(AZ::ShapeIntersection::Contains(unitBox, unitSphere));
  79. EXPECT_TRUE(AZ::ShapeIntersection::Contains(aabb1, unitSphere));
  80. EXPECT_TRUE(AZ::ShapeIntersection::Contains(frustum, unitSphere));
  81. EXPECT_TRUE(AZ::ShapeIntersection::Contains(unitSphere, unitSphere));
  82. EXPECT_TRUE(AZ::ShapeIntersection::Contains(sphere1, aabb));
  83. EXPECT_TRUE(AZ::ShapeIntersection::Contains(frustum, unitBox));
  84. EXPECT_TRUE(AZ::ShapeIntersection::Contains(unitSphere, point));
  85. EXPECT_TRUE(AZ::ShapeIntersection::Contains(sphere1, point1));
  86. EXPECT_TRUE(AZ::ShapeIntersection::Contains(frustum, point));
  87. EXPECT_FALSE(AZ::ShapeIntersection::Contains(frustum, sphere1));
  88. EXPECT_FALSE(AZ::ShapeIntersection::Contains(unitSphere, unitBox));
  89. EXPECT_FALSE(AZ::ShapeIntersection::Contains(frustum, aabb));
  90. EXPECT_FALSE(AZ::ShapeIntersection::Contains(unitSphere, point1));
  91. EXPECT_FALSE(AZ::ShapeIntersection::Contains(frustum, point1));
  92. {
  93. AZ::Sphere s(AZ::Vector3(0.0f, -4.4f, 0.0f), 0.5f);
  94. AZ::Sphere s1(AZ::Vector3(0.0f, -5.1f, 0.0f), 0.5f);
  95. AZ::Sphere s2(AZ::Vector3(0.0f, -5.6f, 0.0f), 0.5f);
  96. EXPECT_EQ(AZ::ShapeIntersection::Classify(near_value, s), AZ::IntersectResult::Interior);
  97. EXPECT_EQ(AZ::ShapeIntersection::Classify(near_value, s1), AZ::IntersectResult::Overlaps);
  98. EXPECT_EQ(AZ::ShapeIntersection::Classify(near_value, s2), AZ::IntersectResult::Exterior);
  99. EXPECT_EQ(AZ::ShapeIntersection::Classify(frustum, s), AZ::IntersectResult::Interior);
  100. EXPECT_EQ(AZ::ShapeIntersection::Classify(frustum, s1), AZ::IntersectResult::Overlaps);
  101. EXPECT_EQ(AZ::ShapeIntersection::Classify(frustum, s2), AZ::IntersectResult::Exterior);
  102. }
  103. {
  104. AZ::Obb obb = AZ::Obb::CreateFromPositionRotationAndHalfLengths(
  105. AZ::Vector3(0.0f, -3.9f, 0.0f), AZ::Quaternion::CreateIdentity(), AZ::Vector3::CreateOne());
  106. AZ::Obb obb1 = AZ::Obb::CreateFromPositionRotationAndHalfLengths(
  107. AZ::Vector3(0.0f, -5.1f, 0.0f), AZ::Quaternion::CreateIdentity(), AZ::Vector3::CreateOne());
  108. AZ::Obb obb2 = AZ::Obb::CreateFromPositionRotationAndHalfLengths(
  109. AZ::Vector3(0.0f, -6.1f, 0.0f), AZ::Quaternion::CreateIdentity(), AZ::Vector3::CreateOne());
  110. EXPECT_EQ(AZ::ShapeIntersection::Classify(near_value, obb), AZ::IntersectResult::Interior);
  111. EXPECT_EQ(AZ::ShapeIntersection::Classify(near_value, obb1), AZ::IntersectResult::Overlaps);
  112. EXPECT_EQ(AZ::ShapeIntersection::Classify(near_value, obb2), AZ::IntersectResult::Exterior);
  113. }
  114. //Test a bunch of different rotations with the OBBs
  115. AZ::Vector3 rotationAxis = AZ::Vector3(1.0f, 1.0f, 1.0f);
  116. rotationAxis.Normalize();
  117. float rotation = 0.0f;
  118. for(int i = 0; i < 50; ++i, rotation += (2.0f*3.1415f/50.0f))
  119. {
  120. AZ::Quaternion rot = AZ::Quaternion::CreateFromAxisAngle(rotationAxis, rotation);
  121. AZ::Obb obb = AZ::Obb::CreateFromPositionRotationAndHalfLengths(
  122. AZ::Vector3(0.7f, 0.7f, 0.7f), rot, AZ::Vector3::CreateOne());
  123. AZ::Obb obb1 = AZ::Obb::CreateFromPositionRotationAndHalfLengths(
  124. AZ::Vector3(6.8f, 6.8f, 6.8f), rot, AZ::Vector3::CreateOne());
  125. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(frustum, obb));
  126. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(frustum, obb1));
  127. }
  128. }
  129. TEST(MATH_ShapeIntersection, CapsuleCapsuleCapAJustIntersectsCapB)
  130. {
  131. const AZ::Vector3 firstHemisphereCenterA(1.0f, 7.0f, 13.0f);
  132. const AZ::Vector3 secondHemisphereCenterA(2.0f, 3.0f, 5.0f);
  133. const float radiusA = 5.51f;
  134. const AZ::Capsule capsuleA(firstHemisphereCenterA, secondHemisphereCenterA, radiusA);
  135. const AZ::Vector3 firstHemisphereCenterB(3.0f, -1.0f, -3.0f);
  136. const AZ::Vector3 secondHemisphereCenterB(4.0f, -5.0f, -11.0f);
  137. const float radiusB = 3.51f;
  138. const AZ::Capsule capsuleB(firstHemisphereCenterB, secondHemisphereCenterB, radiusB);
  139. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(capsuleA, capsuleB));
  140. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(capsuleB, capsuleA));
  141. }
  142. TEST(MATH_ShapeIntersection, CapsuleCapsuleCapAJustSeparatedFromCapB)
  143. {
  144. const AZ::Vector3 firstHemisphereCenterA(1.0f, 7.0f, 13.0f);
  145. const AZ::Vector3 secondHemisphereCenterA(2.0f, 3.0f, 5.0f);
  146. const float radiusA = 5.49f;
  147. const AZ::Capsule capsuleA(firstHemisphereCenterA, secondHemisphereCenterA, radiusA);
  148. const AZ::Vector3 firstHemisphereCenterB(3.0f, -1.0f, -3.0f);
  149. const AZ::Vector3 secondHemisphereCenterB(4.0f, -5.0f, -11.0f);
  150. const float radiusB = 3.49f;
  151. const AZ::Capsule capsuleB(firstHemisphereCenterB, secondHemisphereCenterB, radiusB);
  152. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(capsuleA, capsuleB));
  153. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(capsuleB, capsuleA));
  154. }
  155. TEST(MATH_ShapeIntersection, CapsuleCapsuleCapAJustIntersectsCylinderB)
  156. {
  157. const AZ::Vector3 firstHemisphereCenterA(1.0f, 3.0f, -5.0f);
  158. const AZ::Vector3 secondHemisphereCenterA(4.0f, 7.0f, 7.0f);
  159. const float radiusA = 1.01f;
  160. const AZ::Capsule capsuleA(firstHemisphereCenterA, secondHemisphereCenterA, radiusA);
  161. const AZ::Vector3 firstHemisphereCenterB(0.5f, 6.5f, 1.0f);
  162. const AZ::Vector3 secondHemisphereCenterB(-3.5f, 9.5f, 1.0f);
  163. const float radiusB = 1.51f;
  164. const AZ::Capsule capsuleB(firstHemisphereCenterB, secondHemisphereCenterB, radiusB);
  165. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(capsuleA, capsuleB));
  166. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(capsuleB, capsuleA));
  167. }
  168. TEST(MATH_ShapeIntersection, CapsuleCapsuleCapAJustSeparatedFromCylinderB)
  169. {
  170. const AZ::Vector3 firstHemisphereCenterA(1.0f, 3.0f, -5.0f);
  171. const AZ::Vector3 secondHemisphereCenterA(4.0f, 7.0f, 7.0f);
  172. const float radiusA = 0.99f;
  173. const AZ::Capsule capsuleA(firstHemisphereCenterA, secondHemisphereCenterA, radiusA);
  174. const AZ::Vector3 firstHemisphereCenterB(0.5f, 6.5f, 1.0f);
  175. const AZ::Vector3 secondHemisphereCenterB(-3.5f, 9.5f, 1.0f);
  176. const float radiusB = 1.49f;
  177. const AZ::Capsule capsuleB(firstHemisphereCenterB, secondHemisphereCenterB, radiusB);
  178. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(capsuleA, capsuleB));
  179. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(capsuleB, capsuleA));
  180. }
  181. TEST(MATH_ShapeIntersection, CapsuleCapsuleCompletelyContainedCapsuleB)
  182. {
  183. const AZ::Vector3 firstHemisphereCenter(1.0f, 2.0f, 3.0f);
  184. const AZ::Vector3 secondHemisphereCenter(5.0f, 7.0f, -4.0f);
  185. const float radiusA = 2.0f;
  186. const float radiusB = 1.5f;
  187. const AZ::Capsule capsuleA(firstHemisphereCenter, secondHemisphereCenter, radiusA);
  188. const AZ::Capsule capsuleB(firstHemisphereCenter, secondHemisphereCenter, radiusB);
  189. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(capsuleA, capsuleB));
  190. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(capsuleB, capsuleA));
  191. }
  192. TEST(MATH_ShapeIntersection, CapsuleCapsuleParallelJustOverlapping)
  193. {
  194. const AZ::Vector3 firstHemisphereCenterA(2.0f, -3.0f, -7.0f);
  195. const AZ::Vector3 secondHemisphereCenterA(11.0f, 17.0f, 5.0f);
  196. const float radiusA = 3.01f;
  197. const AZ::Capsule capsuleA(firstHemisphereCenterA, secondHemisphereCenterA, radiusA);
  198. const AZ::Vector3 firstHemisphereCenterB(-2.0f, -3.0f, -4.0f);
  199. const AZ::Vector3 secondHemisphereCenterB(7.0f, 17.0f, 8.0f);
  200. const float radiusB = 2.01f;
  201. const AZ::Capsule capsuleB(firstHemisphereCenterB, secondHemisphereCenterB, radiusB);
  202. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(capsuleA, capsuleB));
  203. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(capsuleB, capsuleA));
  204. }
  205. TEST(MATH_ShapeIntersection, CapsuleCapsuleParallelJustSeparate)
  206. {
  207. const AZ::Vector3 firstHemisphereCenterA(2.0f, -3.0f, -7.0f);
  208. const AZ::Vector3 secondHemisphereCenterA(11.0f, 17.0f, 5.0f);
  209. const float radiusA = 2.99f;
  210. const AZ::Capsule capsuleA(firstHemisphereCenterA, secondHemisphereCenterA, radiusA);
  211. const AZ::Vector3 firstHemisphereCenterB(-2.0f, -3.0f, -4.0f);
  212. const AZ::Vector3 secondHemisphereCenterB(7.0f, 17.0f, 8.0f);
  213. const float radiusB = 1.99f;
  214. const AZ::Capsule capsuleB(firstHemisphereCenterB, secondHemisphereCenterB, radiusB);
  215. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(capsuleA, capsuleB));
  216. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(capsuleB, capsuleA));
  217. }
  218. TEST(MATH_ShapeIntersection, CapsuleObbCompletelyContainedCapsule)
  219. {
  220. const AZ::Vector3 firstHemisphereCenter(2.0f, 3.0f, 4.0f);
  221. const AZ::Vector3 secondHemisphereCenter(3.0f, 4.0f, 6.0f);
  222. const float radius = 1.0f;
  223. const AZ::Capsule capsule(firstHemisphereCenter, secondHemisphereCenter, radius);
  224. const AZ::Vector3 obbPosition(3.0f, 4.0f, 5.0f);
  225. const AZ::Quaternion obbRotation(0.64f, -0.08f, -0.56f, 0.52f);
  226. const AZ::Vector3 obbHalfLengths(4.0f, 4.0f, 5.0f);
  227. const AZ::Obb obb = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obbPosition, obbRotation, obbHalfLengths);
  228. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(capsule, obb));
  229. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(obb, capsule));
  230. }
  231. TEST(MATH_ShapeIntersection, CapsuleObbCompletelyContainedObb)
  232. {
  233. const AZ::Vector3 firstHemisphereCenter(-1.0f, 4.0f, 3.0f);
  234. const AZ::Vector3 secondHemisphereCenter(5.0f, 0.0f, 7.0f);
  235. const float radius = 4.0f;
  236. const AZ::Capsule capsule(firstHemisphereCenter, secondHemisphereCenter, radius);
  237. const AZ::Vector3 obbPosition(2.0f, 2.0f, 5.0f);
  238. const AZ::Quaternion obbRotation(0.72f, -0.48f, -0.24f, 0.44f);
  239. const AZ::Vector3 obbHalfLengths(2.0f, 1.0f, 2.0f);
  240. const AZ::Obb obb = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obbPosition, obbRotation, obbHalfLengths);
  241. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(capsule, obb));
  242. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(obb, capsule));
  243. }
  244. TEST(MATH_ShapeIntersection, CapsuleObbCapJustOverlappingFace)
  245. {
  246. const AZ::Vector3 firstHemisphereCenter(0.696f, -2.8432f, 1.4576f);
  247. const AZ::Vector3 secondHemisphereCenter(-0.84f, -4.072f, 1.096f);
  248. const float radius = 1.01f;
  249. const AZ::Capsule capsule(firstHemisphereCenter, secondHemisphereCenter, radius);
  250. const AZ::Vector3 obbPosition(3.0f, -1.0f, 2.0f);
  251. const AZ::Quaternion obbRotation(0.48f, -0.60f, 0.0f, 0.64f);
  252. const AZ::Vector3 obbHalfLengths(2.0f, 1.0f, 2.0f);
  253. const AZ::Obb obb = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obbPosition, obbRotation, obbHalfLengths);
  254. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(capsule, obb));
  255. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(obb, capsule));
  256. }
  257. TEST(MATH_ShapeIntersection, CapsuleObbCapJustSeparateFromFace)
  258. {
  259. const AZ::Vector3 firstHemisphereCenter(0.696f, -2.8432f, 1.4576f);
  260. const AZ::Vector3 secondHemisphereCenter(-0.84f, -4.072f, 1.096f);
  261. const float radius = 0.99f;
  262. const AZ::Capsule capsule(firstHemisphereCenter, secondHemisphereCenter, radius);
  263. const AZ::Vector3 obbPosition(3.0f, -1.0f, 2.0f);
  264. const AZ::Quaternion obbRotation(0.48f, -0.60f, 0.0f, 0.64f);
  265. const AZ::Vector3 obbHalfLengths(2.0f, 1.0f, 2.0f);
  266. const AZ::Obb obb = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obbPosition, obbRotation, obbHalfLengths);
  267. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(capsule, obb));
  268. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(obb, capsule));
  269. }
  270. TEST(MATH_ShapeIntersection, CapsuleObbCylinderJustOverlappingFace)
  271. {
  272. const AZ::Vector3 firstHemisphereCenter(-1.7872f, 4.4496f, -1.424f);
  273. const AZ::Vector3 secondHemisphereCenter(1.6368f, 5.2176f, -3.344f);
  274. const float radius = 2.01f;
  275. const AZ::Capsule capsule(firstHemisphereCenter, secondHemisphereCenter, radius);
  276. const AZ::Vector3 obbPosition(1.0f, 1.0f, -2.0f);
  277. const AZ::Quaternion obbRotation(0.12f, -0.96f, 0.08f, 0.24f);
  278. const AZ::Vector3 obbHalfLengths(1.5f, 2.0f, 0.5f);
  279. const AZ::Obb obb = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obbPosition, obbRotation, obbHalfLengths);
  280. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(capsule, obb));
  281. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(obb, capsule));
  282. }
  283. TEST(MATH_ShapeIntersection, CapsuleObbCylinderJustSeparateFromFace)
  284. {
  285. const AZ::Vector3 firstHemisphereCenter(-1.7872f, 4.4496f, -1.424f);
  286. const AZ::Vector3 secondHemisphereCenter(1.6368f, 5.2176f, -3.344f);
  287. const float radius = 1.99f;
  288. const AZ::Capsule capsule(firstHemisphereCenter, secondHemisphereCenter, radius);
  289. const AZ::Vector3 obbPosition(1.0f, 1.0f, -2.0f);
  290. const AZ::Quaternion obbRotation(0.12f, -0.96f, 0.08f, 0.24f);
  291. const AZ::Vector3 obbHalfLengths(1.5f, 2.0f, 0.5f);
  292. const AZ::Obb obb = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obbPosition, obbRotation, obbHalfLengths);
  293. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(capsule, obb));
  294. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(obb, capsule));
  295. }
  296. TEST(MATH_ShapeIntersection, CapsuleObbCapJustOverlappingEdge)
  297. {
  298. const AZ::Vector3 firstHemisphereCenter(-7.64f, -0.534f, -0.088f);
  299. const AZ::Vector3 secondHemisphereCenter(-5.384f, 0.4796f, -0.4528f);
  300. const float radius = 1.26f;
  301. const AZ::Capsule capsule(firstHemisphereCenter, secondHemisphereCenter, radius);
  302. const AZ::Vector3 obbPosition(-2.0f, 2.0f, -1.0f);
  303. const AZ::Quaternion obbRotation(0.70f, -0.02f, -0.14f, 0.70f);
  304. const AZ::Vector3 obbHalfLengths(2.0f, 1.5f, 1.5f);
  305. const AZ::Obb obb = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obbPosition, obbRotation, obbHalfLengths);
  306. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(capsule, obb));
  307. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(obb, capsule));
  308. }
  309. TEST(MATH_ShapeIntersection, CapsuleObbCapJustSeparateFromEdge)
  310. {
  311. const AZ::Vector3 firstHemisphereCenter(-7.64f, -0.534f, -0.088f);
  312. const AZ::Vector3 secondHemisphereCenter(-5.384f, 0.4796f, -0.4528f);
  313. const float radius = 1.24f;
  314. const AZ::Capsule capsule(firstHemisphereCenter, secondHemisphereCenter, radius);
  315. const AZ::Vector3 obbPosition(-2.0f, 2.0f, -1.0f);
  316. const AZ::Quaternion obbRotation(0.70f, -0.02f, -0.14f, 0.70f);
  317. const AZ::Vector3 obbHalfLengths(2.0f, 1.5f, 1.5f);
  318. const AZ::Obb obb = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obbPosition, obbRotation, obbHalfLengths);
  319. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(capsule, obb));
  320. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(obb, capsule));
  321. }
  322. TEST(MATH_ShapeIntersection, CapsuleObbCylinderJustOverlappingEdge)
  323. {
  324. const AZ::Vector3 firstHemisphereCenter(6.3152f, 5.8864f, -1.088f);
  325. const AZ::Vector3 secondHemisphereCenter(6.3664f, -3.6752f, -4.016f);
  326. const float radius = 2.51f;
  327. const AZ::Capsule capsule(firstHemisphereCenter, secondHemisphereCenter, radius);
  328. const AZ::Vector3 obbPosition(3.0f, 0.0f, 1.0f);
  329. const AZ::Quaternion obbRotation(0.16f, 0.92f, -0.16f, 0.32f);
  330. const AZ::Vector3 obbHalfLengths(1.0f, 1.5f, 2.0f);
  331. const AZ::Obb obb = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obbPosition, obbRotation, obbHalfLengths);
  332. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(capsule, obb));
  333. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(obb, capsule));
  334. }
  335. TEST(MATH_ShapeIntersection, CapsuleObbCylinderJustSeparateFromEdge)
  336. {
  337. const AZ::Vector3 firstHemisphereCenter(6.3152f, 5.8864f, -1.088f);
  338. const AZ::Vector3 secondHemisphereCenter(6.3664f, -3.6752f, -4.016f);
  339. const float radius = 2.49f;
  340. const AZ::Capsule capsule(firstHemisphereCenter, secondHemisphereCenter, radius);
  341. const AZ::Vector3 obbPosition(3.0f, 0.0f, 1.0f);
  342. const AZ::Quaternion obbRotation(0.16f, 0.92f, -0.16f, 0.32f);
  343. const AZ::Vector3 obbHalfLengths(1.0f, 1.5f, 2.0f);
  344. const AZ::Obb obb = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obbPosition, obbRotation, obbHalfLengths);
  345. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(capsule, obb));
  346. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(obb, capsule));
  347. }
  348. TEST(MATH_ShapeIntersection, CapsuleObbCapJustOverlappingVertex)
  349. {
  350. const AZ::Vector3 firstHemisphereCenter(-8.92f, 8.56f, -2.4f);
  351. const AZ::Vector3 secondHemisphereCenter(-3.96f, 5.28f, -3.2f);
  352. const float radius = 3.01f;
  353. const AZ::Capsule capsule(firstHemisphereCenter, secondHemisphereCenter, radius);
  354. const AZ::Vector3 obbPosition(1.0f, 2.0f, -4.0f);
  355. const AZ::Quaternion obbRotation(0.4f, 0.4f, 0.64f, 0.52f);
  356. const AZ::Vector3 obbHalfLengths(2.0f, 1.0f, 2.0f);
  357. const AZ::Obb obb = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obbPosition, obbRotation, obbHalfLengths);
  358. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(capsule, obb));
  359. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(obb, capsule));
  360. }
  361. TEST(MATH_ShapeIntersection, CapsuleObbCapJustSeparateFromVertex)
  362. {
  363. const AZ::Vector3 firstHemisphereCenter(-8.92f, 8.56f, -2.4f);
  364. const AZ::Vector3 secondHemisphereCenter(-3.96f, 5.28f, -3.2f);
  365. const float radius = 2.99f;
  366. const AZ::Capsule capsule(firstHemisphereCenter, secondHemisphereCenter, radius);
  367. const AZ::Vector3 obbPosition(1.0f, 2.0f, -4.0f);
  368. const AZ::Quaternion obbRotation(0.4f, 0.4f, 0.64f, 0.52f);
  369. const AZ::Vector3 obbHalfLengths(2.0f, 1.0f, 2.0f);
  370. const AZ::Obb obb = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obbPosition, obbRotation, obbHalfLengths);
  371. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(capsule, obb));
  372. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(obb, capsule));
  373. }
  374. TEST(MATH_ShapeIntersection, CapsuleObbCylinderJustOverlappingVertex)
  375. {
  376. const AZ::Vector3 firstHemisphereCenter(1.5952f, 1.0064f, 9.064f);
  377. const AZ::Vector3 secondHemisphereCenter(-4.4176f, -6.8432f, 6.568f);
  378. const float radius = 3.01f;
  379. const AZ::Capsule capsule(firstHemisphereCenter, secondHemisphereCenter, radius);
  380. const AZ::Vector3 obbPosition(2.0f, -4.0f, 3.0f);
  381. const AZ::Quaternion obbRotation(0.56f, -0.08f, -0.20f, 0.80f);
  382. const AZ::Vector3 obbHalfLengths(2.0f, 2.0f, 1.0f);
  383. const AZ::Obb obb = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obbPosition, obbRotation, obbHalfLengths);
  384. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(capsule, obb));
  385. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(obb, capsule));
  386. }
  387. TEST(MATH_ShapeIntersection, CapsuleObbCylinderJustSeparateFromVertex)
  388. {
  389. const AZ::Vector3 firstHemisphereCenter(1.5952f, 1.0064f, 9.064f);
  390. const AZ::Vector3 secondHemisphereCenter(-4.4176f, -6.8432f, 6.568f);
  391. const float radius = 2.99f;
  392. const AZ::Capsule capsule(firstHemisphereCenter, secondHemisphereCenter, radius);
  393. const AZ::Vector3 obbPosition(2.0f, -4.0f, 3.0f);
  394. const AZ::Quaternion obbRotation(0.56f, -0.08f, -0.20f, 0.80f);
  395. const AZ::Vector3 obbHalfLengths(2.0f, 2.0f, 1.0f);
  396. const AZ::Obb obb = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obbPosition, obbRotation, obbHalfLengths);
  397. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(capsule, obb));
  398. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(obb, capsule));
  399. }
  400. TEST(MATH_ShapeIntersection, SphereObbCompletelyContainedObb)
  401. {
  402. const AZ::Vector3 spherePosition(1.0f, 2.0f, 3.0f);
  403. const float sphereRadius = 5.0f;
  404. const AZ::Sphere sphere(spherePosition, sphereRadius);
  405. const AZ::Vector3 obbPosition(2.0f, 3.0f, 4.0f);
  406. const AZ::Quaternion obbRotation(0.24f, -0.72f, -0.12f, 0.64f);
  407. const AZ::Vector3 obbHalfLengths(1.0f, 2.0f, 1.5f);
  408. const AZ::Obb obb = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obbPosition, obbRotation, obbHalfLengths);
  409. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(sphere, obb));
  410. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(obb, sphere));
  411. }
  412. TEST(MATH_ShapeIntersection, SphereObbCompletelyContainedSphere)
  413. {
  414. const AZ::Vector3 sphereCenter(2.0f, 3.0f, 4.0f);
  415. const float sphereRadius = 2.0f;
  416. const AZ::Sphere sphere(sphereCenter, sphereRadius);
  417. const AZ::Vector3 obbPosition(3.0f, 4.0f, 5.0f);
  418. const AZ::Quaternion obbRotation(0.46f, 0.26f, 0.58f, 0.62f);
  419. const AZ::Vector3 obbHalfLengths(5.0f, 6.0f, 7.0f);
  420. const AZ::Obb obb = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obbPosition, obbRotation, obbHalfLengths);
  421. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(sphere, obb));
  422. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(obb, sphere));
  423. }
  424. TEST(MATH_ShapeIntersection, SphereObbJustIntersectingFace)
  425. {
  426. const AZ::Vector3 sphereCenter(-0.4f, -0.24f, 8.32f);
  427. const float sphereRadius = 2.01f;
  428. const AZ::Sphere sphere(sphereCenter, sphereRadius);
  429. const AZ::Vector3 obbPosition(2.0f, -1.0f, 4.0f);
  430. const AZ::Quaternion obbRotation(0.44f, 0.24f, 0.48f, 0.72f);
  431. const AZ::Vector3 obbHalfLengths(2.0f, 3.0f, 1.0f);
  432. const AZ::Obb obb = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obbPosition, obbRotation, obbHalfLengths);
  433. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(sphere, obb));
  434. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(obb, sphere));
  435. }
  436. TEST(MATH_ShapeIntersection, SphereObbJustSeparateFromFace)
  437. {
  438. const AZ::Vector3 sphereCenter(-0.4f, -0.24f, 8.32f);
  439. const float sphereRadius = 1.99f;
  440. const AZ::Sphere sphere(sphereCenter, sphereRadius);
  441. const AZ::Vector3 obbPosition(2.0f, -1.0f, 4.0f);
  442. const AZ::Quaternion obbRotation(0.44f, 0.24f, 0.48f, 0.72f);
  443. const AZ::Vector3 obbHalfLengths(2.0f, 3.0f, 1.0f);
  444. const AZ::Obb obb = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obbPosition, obbRotation, obbHalfLengths);
  445. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(sphere, obb));
  446. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(obb, sphere));
  447. }
  448. TEST(MATH_ShapeIntersection, SphereObbJustIntersectingEdge)
  449. {
  450. const AZ::Vector3 sphereCenter(3.58f, 1.7264f, 1.2048f);
  451. const float sphereRadius = 5.01f;
  452. const AZ::Sphere sphere(sphereCenter, sphereRadius);
  453. const AZ::Vector3 obbPosition(-2.0f, -1.0f, -3.0f);
  454. const AZ::Quaternion obbRotation(0.16f, 0.20f, 0.40f, 0.88f);
  455. const AZ::Vector3 obbHalfLengths(1.5f, 1.0f, 2.0f);
  456. const AZ::Obb obb = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obbPosition, obbRotation, obbHalfLengths);
  457. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(sphere, obb));
  458. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(obb, sphere));
  459. }
  460. TEST(MATH_ShapeIntersection, SphereObbJustSeparateFromEdge)
  461. {
  462. const AZ::Vector3 sphereCenter(3.58f, 1.7264f, 1.2048f);
  463. const float sphereRadius = 4.99f;
  464. const AZ::Sphere sphere(sphereCenter, sphereRadius);
  465. const AZ::Vector3 obbPosition(-2.0f, -1.0f, -3.0f);
  466. const AZ::Quaternion obbRotation(0.16f, 0.20f, 0.40f, 0.88f);
  467. const AZ::Vector3 obbHalfLengths(1.5f, 1.0f, 2.0f);
  468. const AZ::Obb obb = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obbPosition, obbRotation, obbHalfLengths);
  469. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(sphere, obb));
  470. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(obb, sphere));
  471. }
  472. TEST(MATH_ShapeIntersection, SphereObbJustIntersectingVertex)
  473. {
  474. const AZ::Vector3 sphereCenter(6.84f, 0.12f, -2.8f);
  475. const float sphereRadius = 3.01f;
  476. const AZ::Sphere sphere(sphereCenter, sphereRadius);
  477. const AZ::Vector3 obbPosition(1.0f, -1.0f, -2.0f);
  478. const AZ::Quaternion obbRotation(-0.22f, -0.26f, 0.38f, 0.86f);
  479. const AZ::Vector3 obbHalfLengths(2.0f, 1.0f, 2.0f);
  480. const AZ::Obb obb = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obbPosition, obbRotation, obbHalfLengths);
  481. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(sphere, obb));
  482. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(obb, sphere));
  483. }
  484. TEST(MATH_ShapeIntersection, SphereObbJustSeparateFromVertex)
  485. {
  486. const AZ::Vector3 sphereCenter(6.84f, 0.12f, -2.8f);
  487. const float sphereRadius = 2.99f;
  488. const AZ::Sphere sphere(sphereCenter, sphereRadius);
  489. const AZ::Vector3 obbPosition(1.0f, -1.0f, -2.0f);
  490. const AZ::Quaternion obbRotation(-0.22f, -0.26f, 0.38f, 0.86f);
  491. const AZ::Vector3 obbHalfLengths(2.0f, 1.0f, 2.0f);
  492. const AZ::Obb obb = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obbPosition, obbRotation, obbHalfLengths);
  493. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(sphere, obb));
  494. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(obb, sphere));
  495. }
  496. TEST(MATH_ShapeIntersection, CapsuleSphereCompletelyContainedSphere)
  497. {
  498. const AZ::Vector3 firstHemisphereCenter(0.0f, 3.0f, 1.0f);
  499. const AZ::Vector3 secondHemisphereCenter(2.0f, 1.0f, 1.0f);
  500. const float capsuleRadius = 4.0f;
  501. const AZ::Capsule capsule(firstHemisphereCenter, secondHemisphereCenter, capsuleRadius);
  502. const AZ::Vector3 sphereCenter(1.0f, 2.0f, 1.0f);
  503. const float sphereRadius = 1.5f;
  504. const AZ::Sphere sphere(sphereCenter, sphereRadius);
  505. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(capsule, sphere));
  506. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(sphere, capsule));
  507. }
  508. TEST(MATH_ShapeIntersection, CapsuleSphereCompletelyContainedCapsule)
  509. {
  510. const AZ::Vector3 firstHemisphereCenter(3.0f, -3.0f, 2.0f);
  511. const AZ::Vector3 secondHemisphereCenter(5.0f, -1.0f, 4.0f);
  512. const float capsuleRadius = 2.0f;
  513. const AZ::Capsule capsule(firstHemisphereCenter, secondHemisphereCenter, capsuleRadius);
  514. const AZ::Vector3 sphereCenter(4.0f, -2.0f, 3.0f);
  515. const float sphereRadius = 5.0f;
  516. const AZ::Sphere sphere(sphereCenter, sphereRadius);
  517. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(capsule, sphere));
  518. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(sphere, capsule));
  519. }
  520. TEST(MATH_ShapeIntersection, CapsuleSphereJustIntersectingCap)
  521. {
  522. const AZ::Vector3 firstHemisphereCenter(-1.0f, 3.0f, -3.0f);
  523. const AZ::Vector3 secondHemisphereCenter(3.0f, -1.0f, 4.0f);
  524. const float capsuleRadius = 4.0f;
  525. const AZ::Capsule capsule(firstHemisphereCenter, secondHemisphereCenter, capsuleRadius);
  526. const AZ::Vector3 sphereCenter(7.0f, -5.0f, 11.0f);
  527. const float sphereRadius = 5.01f;
  528. const AZ::Sphere sphere(sphereCenter, sphereRadius);
  529. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(capsule, sphere));
  530. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(sphere, capsule));
  531. }
  532. TEST(MATH_ShapeIntersection, CapsuleSphereJustSeparateFromCap)
  533. {
  534. const AZ::Vector3 firstHemisphereCenter(-1.0f, 3.0f, -3.0f);
  535. const AZ::Vector3 secondHemisphereCenter(3.0f, -1.0f, 4.0f);
  536. const float capsuleRadius = 4.0f;
  537. const AZ::Capsule capsule(firstHemisphereCenter, secondHemisphereCenter, capsuleRadius);
  538. const AZ::Vector3 sphereCenter(7.0f, -5.0f, 11.0f);
  539. const float sphereRadius = 4.99f;
  540. const AZ::Sphere sphere(sphereCenter, sphereRadius);
  541. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(capsule, sphere));
  542. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(sphere, capsule));
  543. }
  544. TEST(MATH_ShapeIntersection, CapsuleSphereJustIntersectingCylinder)
  545. {
  546. const AZ::Vector3 firstHemisphereCenter(2.0f, 5.0f, -3.0f);
  547. const AZ::Vector3 secondHemisphereCenter(8.0f, -3.0f, -1.0f);
  548. const float capsuleRadius = 5.0f;
  549. const AZ::Capsule capsule(firstHemisphereCenter, secondHemisphereCenter, capsuleRadius);
  550. const AZ::Vector3 sphereCenter(5.0f, 4.0f, 4.0f);
  551. const float sphereRadius = 2.01f;
  552. const AZ::Sphere sphere(sphereCenter, sphereRadius);
  553. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(capsule, sphere));
  554. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(sphere, capsule));
  555. }
  556. TEST(MATH_ShapeIntersection, CapsuleSphereJustSeparateFromCylinder)
  557. {
  558. const AZ::Vector3 firstHemisphereCenter(2.0f, 5.0f, -3.0f);
  559. const AZ::Vector3 secondHemisphereCenter(8.0f, -3.0f, -1.0f);
  560. const float capsuleRadius = 5.0f;
  561. const AZ::Capsule capsule(firstHemisphereCenter, secondHemisphereCenter, capsuleRadius);
  562. const AZ::Vector3 sphereCenter(5.0f, 4.0f, 4.0f);
  563. const float sphereRadius = 1.99f;
  564. const AZ::Sphere sphere(sphereCenter, sphereRadius);
  565. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(capsule, sphere));
  566. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(sphere, capsule));
  567. }
  568. TEST(MATH_ShapeIntersection, ObbObbCompletelyContained)
  569. {
  570. const AZ::Vector3 obb1Position(2.0f, -1.0f, 3.0f);
  571. const AZ::Quaternion obb1Rotation(0.34f, -0.46f, -0.58f, 0.58f);
  572. const AZ::Vector3 obb1HalfLengths(4.0f, 5.0f, 6.0f);
  573. const AZ::Obb obb1 = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obb1Position, obb1Rotation, obb1HalfLengths);
  574. const AZ::Vector3 obb2Position(1.0f, 0.0f, 3.0f);
  575. const AZ::Quaternion obb2Rotation(-0.16f, 0.64f, -0.68f, 0.32f);
  576. const AZ::Vector3 obb2HalfLengths(2.0f, 1.0f, 1.5f);
  577. const AZ::Obb obb2 = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obb2Position, obb2Rotation, obb2HalfLengths);
  578. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(obb1, obb2));
  579. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(obb2, obb1));
  580. }
  581. TEST(MATH_ShapeIntersection, ObbObbJustIntersectingFaceFace)
  582. {
  583. const AZ::Vector3 obb1Position(2.0f, 1.0f, -4.0f);
  584. const AZ::Quaternion obb1Rotation(0.24f, 0.08f, -0.48f, 0.84f);
  585. const AZ::Vector3 obb1HalfLengths(1.0f, 3.0f, 2.01f);
  586. const AZ::Obb obb1 = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obb1Position, obb1Rotation, obb1HalfLengths);
  587. const AZ::Vector3 obb2Position(1.52f, -1.4f, 0.36f);
  588. const AZ::Quaternion obb2Rotation(0.82f, 0.1f, 0.26f, 0.5f);
  589. const AZ::Vector3 obb2HalfLengths(2.0f, 3.0f, 1.0f);
  590. const AZ::Obb obb2 = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obb2Position, obb2Rotation, obb2HalfLengths);
  591. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(obb1, obb2));
  592. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(obb2, obb1));
  593. }
  594. TEST(MATH_ShapeIntersection, ObbObbJustSeparateFaceFace)
  595. {
  596. const AZ::Vector3 obb1Position(2.0f, 1.0f, -4.0f);
  597. const AZ::Quaternion obb1Rotation(0.24f, 0.08f, -0.48f, 0.84f);
  598. const AZ::Vector3 obb1HalfLengths(1.0f, 3.0f, 1.99f);
  599. const AZ::Obb obb1 = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obb1Position, obb1Rotation, obb1HalfLengths);
  600. const AZ::Vector3 obb2Position(1.52f, -1.4f, 0.36f);
  601. const AZ::Quaternion obb2Rotation(0.82f, 0.1f, 0.26f, 0.5f);
  602. const AZ::Vector3 obb2HalfLengths(2.0f, 3.0f, 1.0f);
  603. const AZ::Obb obb2 = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obb2Position, obb2Rotation, obb2HalfLengths);
  604. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(obb1, obb2));
  605. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(obb2, obb1));
  606. }
  607. TEST(MATH_ShapeIntersection, ObbObbJustIntersectingFaceEdge)
  608. {
  609. const AZ::Vector3 obb1Position(-1.0f, 1.0f, 3.0f);
  610. const AZ::Quaternion obb1Rotation(0.1f, 0.1f, 0.7f, 0.7f);
  611. const AZ::Vector3 obb1HalfLengths(2.0f, 1.5f, 1.0f);
  612. const AZ::Obb obb1 = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obb1Position, obb1Rotation, obb1HalfLengths);
  613. const AZ::Vector3 obb2Position(-4.84f, 1.0f, 4.12f);
  614. const AZ::Quaternion obb2Rotation(0.14f, 0.02f, 0.98f, 0.14f);
  615. const AZ::Vector3 obb2HalfLengths(2.41f, 0.7f, 3.0f);
  616. const AZ::Obb obb2 = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obb2Position, obb2Rotation, obb2HalfLengths);
  617. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(obb1, obb2));
  618. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(obb2, obb1));
  619. }
  620. TEST(MATH_ShapeIntersection, ObbObbJustSeparateFaceEdge)
  621. {
  622. const AZ::Vector3 obb1Position(-1.0f, 1.0f, 3.0f);
  623. const AZ::Quaternion obb1Rotation(0.1f, 0.1f, 0.7f, 0.7f);
  624. const AZ::Vector3 obb1HalfLengths(2.0f, 1.5f, 1.0f);
  625. const AZ::Obb obb1 = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obb1Position, obb1Rotation, obb1HalfLengths);
  626. const AZ::Vector3 obb2Position(-4.84f, 1.0f, 4.12f);
  627. const AZ::Quaternion obb2Rotation(0.14f, 0.02f, 0.98f, 0.14f);
  628. const AZ::Vector3 obb2HalfLengths(2.39f, 0.7f, 3.0f);
  629. const AZ::Obb obb2 = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obb2Position, obb2Rotation, obb2HalfLengths);
  630. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(obb1, obb2));
  631. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(obb2, obb1));
  632. }
  633. TEST(MATH_ShapeIntersection, ObbObbJustIntersectingFaceVertex)
  634. {
  635. const AZ::Vector3 obb1Position(3.0f, -1.0f, -2.0f);
  636. const AZ::Quaternion obb1Rotation(0.08f, -0.44f, 0.16f, 0.88f);
  637. const AZ::Vector3 obb1HalfLengths(1.0f, 2.0f, 1.0f);
  638. const AZ::Obb obb1 = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obb1Position, obb1Rotation, obb1HalfLengths);
  639. const AZ::Vector3 obb2Position(1.436f, 1.852f, -3.8f);
  640. const AZ::Quaternion obb2Rotation(0.52f, -0.56f, -0.56f, 0.32f);
  641. const AZ::Vector3 obb2HalfLengths(0.31f, 1.7f, 1.4f);
  642. const AZ::Obb obb2 = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obb2Position, obb2Rotation, obb2HalfLengths);
  643. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(obb1, obb2));
  644. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(obb2, obb1));
  645. }
  646. TEST(MATH_ShapeIntersection, ObbObbJustSeparateFaceVertex)
  647. {
  648. const AZ::Vector3 obb1Position(3.0f, -1.0f, -2.0f);
  649. const AZ::Quaternion obb1Rotation(0.08f, -0.44f, 0.16f, 0.88f);
  650. const AZ::Vector3 obb1HalfLengths(1.0f, 2.0f, 1.0f);
  651. const AZ::Obb obb1 = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obb1Position, obb1Rotation, obb1HalfLengths);
  652. const AZ::Vector3 obb2Position(1.436f, 1.852f, -3.8f);
  653. const AZ::Quaternion obb2Rotation(0.52f, -0.56f, -0.56f, 0.32f);
  654. const AZ::Vector3 obb2HalfLengths(0.29f, 1.7f, 1.4f);
  655. const AZ::Obb obb2 = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obb2Position, obb2Rotation, obb2HalfLengths);
  656. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(obb1, obb2));
  657. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(obb2, obb1));
  658. }
  659. TEST(MATH_ShapeIntersection, ObbObbJustIntersectingEdgeEdge)
  660. {
  661. const AZ::Vector3 obb1Position(1.0f, 4.0f, 3.0f);
  662. const AZ::Quaternion obb1Rotation(0.7f, 0.1f, -0.7f, 0.1f);
  663. const AZ::Vector3 obb1HalfLengths(2.0f, 1.0f, 1.0f);
  664. const AZ::Obb obb1 = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obb1Position, obb1Rotation, obb1HalfLengths);
  665. const AZ::Vector3 obb2Position(-2.072f, 3.104f, 0.6f);
  666. const AZ::Quaternion obb2Rotation(0.14f, 0.02f, 0.98f, -0.14f);
  667. const AZ::Vector3 obb2HalfLengths(2.0f, 0.5f, 1.01f);
  668. const AZ::Obb obb2 = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obb2Position, obb2Rotation, obb2HalfLengths);
  669. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(obb1, obb2));
  670. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(obb2, obb1));
  671. }
  672. TEST(MATH_ShapeIntersection, ObbObbJustSeparateEdgeEdge)
  673. {
  674. const AZ::Vector3 obb1Position(1.0f, 4.0f, 3.0f);
  675. const AZ::Quaternion obb1Rotation(0.7f, 0.1f, -0.7f, 0.1f);
  676. const AZ::Vector3 obb1HalfLengths(2.0f, 1.0f, 1.0f);
  677. const AZ::Obb obb1 = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obb1Position, obb1Rotation, obb1HalfLengths);
  678. const AZ::Vector3 obb2Position(-2.072f, 3.104f, 0.6f);
  679. const AZ::Quaternion obb2Rotation(0.14f, 0.02f, 0.98f, -0.14f);
  680. const AZ::Vector3 obb2HalfLengths(2.0f, 0.5f, 0.99f);
  681. const AZ::Obb obb2 = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obb2Position, obb2Rotation, obb2HalfLengths);
  682. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(obb1, obb2));
  683. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(obb2, obb1));
  684. }
  685. TEST(MATH_ShapeIntersection, ObbObbJustIntersectingEdgeVertex)
  686. {
  687. const AZ::Vector3 obb1Position(4.0f, 2.0f, 5.0f);
  688. const AZ::Quaternion obb1Rotation(-0.58f, 0.22f, 0.26f, 0.74f);
  689. const AZ::Vector3 obb1HalfLengths(2.0f, 1.0f, 2.0f);
  690. const AZ::Obb obb1 = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obb1Position, obb1Rotation, obb1HalfLengths);
  691. const AZ::Vector3 obb2Position(0.696f, 5.9216f, 5.3968f);
  692. const AZ::Quaternion obb2Rotation(0.68f, 0.64f, -0.32f, 0.16f);
  693. const AZ::Vector3 obb2HalfLengths(1.01f, 3.0f, 1.01f);
  694. const AZ::Obb obb2 = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obb2Position, obb2Rotation, obb2HalfLengths);
  695. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(obb1, obb2));
  696. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(obb2, obb1));
  697. }
  698. TEST(MATH_ShapeIntersection, ObbObbJustSeparateEdgeVertex)
  699. {
  700. const AZ::Vector3 obb1Position(4.0f, 2.0f, 5.0f);
  701. const AZ::Quaternion obb1Rotation(-0.58f, 0.22f, 0.26f, 0.74f);
  702. const AZ::Vector3 obb1HalfLengths(2.0f, 1.0f, 2.0f);
  703. const AZ::Obb obb1 = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obb1Position, obb1Rotation, obb1HalfLengths);
  704. const AZ::Vector3 obb2Position(0.696f, 5.9216f, 5.3968f);
  705. const AZ::Quaternion obb2Rotation(0.68f, 0.64f, -0.32f, 0.16f);
  706. const AZ::Vector3 obb2HalfLengths(0.99f, 3.0f, 0.99f);
  707. const AZ::Obb obb2 = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obb2Position, obb2Rotation, obb2HalfLengths);
  708. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(obb1, obb2));
  709. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(obb2, obb1));
  710. }
  711. TEST(MATH_ShapeIntersection, ObbObbJustIntersectingVertexVertex)
  712. {
  713. const AZ::Vector3 obb1Position(-1.0f, 5.0f, 3.0f);
  714. const AZ::Quaternion obb1Rotation(0.44f, 0.40f, 0.08f, 0.80f);
  715. const AZ::Vector3 obb1HalfLengths(1.0f, 1.5f, 3.01f);
  716. const AZ::Obb obb1 = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obb1Position, obb1Rotation, obb1HalfLengths);
  717. const AZ::Vector3 obb2Position(3.808f, 0.9208f, 1.4688f);
  718. const AZ::Quaternion obb2Rotation(0.50f, 0.10f, 0.26f, 0.82f);
  719. const AZ::Vector3 obb2HalfLengths(1.0f, 2.0f, 2.0f);
  720. const AZ::Obb obb2 = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obb2Position, obb2Rotation, obb2HalfLengths);
  721. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(obb1, obb2));
  722. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(obb2, obb1));
  723. }
  724. TEST(MATH_ShapeIntersection, ObbObbJustSeparateVertexVertex)
  725. {
  726. const AZ::Vector3 obb1Position(-1.0f, 5.0f, 3.0f);
  727. const AZ::Quaternion obb1Rotation(0.44f, 0.40f, 0.08f, 0.80f);
  728. const AZ::Vector3 obb1HalfLengths(1.0f, 1.5f, 2.99f);
  729. const AZ::Obb obb1 = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obb1Position, obb1Rotation, obb1HalfLengths);
  730. const AZ::Vector3 obb2Position(3.808f, 0.9208f, 1.4688f);
  731. const AZ::Quaternion obb2Rotation(0.50f, 0.10f, 0.26f, 0.82f);
  732. const AZ::Vector3 obb2HalfLengths(1.0f, 2.0f, 2.0f);
  733. const AZ::Obb obb2 = AZ::Obb::CreateFromPositionRotationAndHalfLengths(obb2Position, obb2Rotation, obb2HalfLengths);
  734. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(obb1, obb2));
  735. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(obb2, obb1));
  736. }
  737. TEST(MATH_ShapeIntersection, HemisphereVsSphere)
  738. {
  739. const AZ::Sphere unitSphere = AZ::Sphere::CreateUnitSphere();
  740. const AZ::Sphere sphere1 = AZ::Sphere(AZ::Vector3(2.0f, 2.0f, 2.0f), 2.0f);
  741. // hemisphere overlaps unit sphere, doesn't touch other sphere
  742. const AZ::Hemisphere hemisphere0(AZ::Vector3(0.0f, 0.0f, 0.0f), 1.0f, AZ::Vector3(0.0f, 0.0f, 1.0f));
  743. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(hemisphere0, unitSphere));
  744. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(hemisphere0, sphere1));
  745. // hemisphere doesn't overlap unit sphere, but overlaps other sphere
  746. const AZ::Hemisphere hemisphere1(AZ::Vector3(1.0f, 1.0f, 1.0f), 1.0f, AZ::Vector3(0.0f, 0.0f, 1.0f));
  747. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(hemisphere1, unitSphere));
  748. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(hemisphere1, sphere1));
  749. // hemisphere faces away from unit sphere but is still within range
  750. const AZ::Hemisphere hemisphere2(AZ::Vector3(0.0f, 0.0f, -0.5f), 2.0f, AZ::Vector3(0.0f, 0.0f, -1.0f));
  751. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(hemisphere2, unitSphere));
  752. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(hemisphere2, sphere1));
  753. // hemisphere faces away from unit sphere and off to the side but is still barely within range
  754. const AZ::Hemisphere hemisphere3(AZ::Vector3(0.0f, 2.0f, -0.9f), 2.0f, AZ::Vector3(0.0f, 0.0f, -1.0f));
  755. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(hemisphere3, unitSphere));
  756. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(hemisphere3, sphere1));
  757. // hemisphere faces away from unit sphere but is out of range.
  758. const AZ::Hemisphere hemisphere4(AZ::Vector3(0.0f, 0.0f, -1.0f), 2.0f, AZ::Vector3(0.0f, 0.0f, -1.0f));
  759. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(hemisphere4, unitSphere));
  760. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(hemisphere4, sphere1));
  761. // hemisphere faces towards unit sphere and is in range
  762. const AZ::Hemisphere hemisphere5(AZ::Vector3(0.0f, 0.0f, -1.5f), 1.0f, AZ::Vector3(0.0f, 0.0f, 1.0f));
  763. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(hemisphere5, unitSphere));
  764. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(hemisphere5, sphere1));
  765. }
  766. TEST(MATH_ShapeIntersection, HemisphereVsAabb)
  767. {
  768. const AZ::Aabb unitAabb = AZ::Aabb::CreateCenterHalfExtents(AZ::Vector3::CreateZero(), AZ::Vector3(1.0f));
  769. // hemisphere on top of aabb
  770. const AZ::Hemisphere hemisphere0(AZ::Vector3(0.0f, 0.0f, 0.0f), 1.0f, AZ::Vector3(0.0f, 0.0f, 1.0f));
  771. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(hemisphere0, unitAabb));
  772. // hemisphere just above aabb pointing away
  773. const AZ::Hemisphere hemisphere1(AZ::Vector3(0.0f, 0.0f, 1.1f), 1.0f, AZ::Vector3(0.0f, 0.0f, 1.0f));
  774. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(hemisphere1, unitAabb));
  775. // hemisphere just above aabb pointing towards
  776. const AZ::Hemisphere hemisphere2(AZ::Vector3(0.0f, 0.0f, 1.1f), 1.0f, AZ::Vector3(0.0f, 0.0f, -1.0f));
  777. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(hemisphere2, unitAabb));
  778. // hemisphere farther above aabb pointing towards
  779. const AZ::Hemisphere hemisphere3(AZ::Vector3(0.0f, 0.0f, 2.1f), 1.0f, AZ::Vector3(0.0f, 0.0f, -1.0f));
  780. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(hemisphere3, unitAabb));
  781. // hemisphere just above aabb pointing away, but at an angle so the plane of the hemisphere intersects
  782. const AZ::Hemisphere hemisphere4(AZ::Vector3(0.0f, 0.0f, 1.1f), 1.0f, AZ::Vector3(0.0f, 1.0f, 1.0f).GetNormalized());
  783. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(hemisphere4, unitAabb));
  784. // false positive case - hemisphere points away from aabb at an angle where the plane still intersects the aabb, but not near enough
  785. // to the hemisphere to actually intersect. This typically happens when the hemisphere is much smaller than the aabb.
  786. const AZ::Hemisphere hemisphere5(AZ::Vector3(0.0f, 0.0f, 1.2f), 0.3f, AZ::Vector3(0.0f, 1.0f, 1.0f).GetNormalized());
  787. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(hemisphere5, unitAabb));
  788. }
  789. TEST(MATH_ShapeIntersection, HemisphereContainsAabb)
  790. {
  791. const AZ::Aabb unitAabb = AZ::Aabb::CreateCenterHalfExtents(AZ::Vector3::CreateZero(), AZ::Vector3(1.0f));
  792. // hemisphere intersecting aabb, but not big enough
  793. const AZ::Hemisphere hemisphere0(AZ::Vector3(0.0f, 0.0f, 0.0f), 2.0f, AZ::Vector3(0.0f, 0.0f, 1.0f));
  794. EXPECT_FALSE(AZ::ShapeIntersection::Contains(hemisphere0, unitAabb));
  795. // hemisphere contains aabb
  796. const AZ::Hemisphere hemisphere1(AZ::Vector3(0.0f, 0.0f, -1.0f), 3.0f, AZ::Vector3(0.0f, 0.0f, 1.0f));
  797. EXPECT_TRUE(AZ::ShapeIntersection::Contains(hemisphere1, unitAabb));
  798. // aabb contains hemisphere
  799. const AZ::Hemisphere hemisphere2(AZ::Vector3(0.0f, 0.0f, 0.0f), 0.5f, AZ::Vector3(0.0f, 0.0f, 1.0f));
  800. EXPECT_FALSE(AZ::ShapeIntersection::Contains(hemisphere2, unitAabb));
  801. // just one point of aabb is outside
  802. const AZ::Hemisphere hemisphere3(AZ::Vector3(1.0f, 1.0f, -1.0f), 3.0f, AZ::Vector3(0.0f, 0.0f, 1.0f));
  803. EXPECT_FALSE(AZ::ShapeIntersection::Contains(hemisphere3, unitAabb));
  804. }
  805. TEST(MATH_ShapeIntersection, CapsuleOverlapsAabb)
  806. {
  807. const AZ::Aabb unitAabb = AZ::Aabb::CreateCenterHalfExtents(AZ::Vector3::CreateZero(), AZ::Vector3::CreateOne());
  808. AZ::Capsule capsule;
  809. // Clear overlap (both shapes pass through origin)
  810. capsule = AZ::Capsule(AZ::Vector3(-1.0f, 0.0f, 0.0f), AZ::Vector3(1.0f, 0.0f, 0.0f), 1.0f);
  811. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(capsule, unitAabb));
  812. // Clear no overlap
  813. capsule = AZ::Capsule(AZ::Vector3(-10.0f, 0.0f, 0.0f), AZ::Vector3(-9.0, 0.0f, 0.0f), 1.0f);
  814. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(capsule, unitAabb));
  815. // Large capsule vs small aabb tests
  816. // aabb completely contained in capsule
  817. capsule = AZ::Capsule(AZ::Vector3(-10.0f, 0.0f, 0.0f), AZ::Vector3(10.0, 0.0f, 0.0f), 5.0f);
  818. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(capsule, unitAabb));
  819. // aabb near cap, slightly overlapping
  820. capsule = AZ::Capsule(AZ::Vector3(-10.0f, 0.0f, 0.0f), AZ::Vector3(-5.9f, 0.0f, 0.0f), 5.0f);
  821. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(capsule, unitAabb));
  822. // aabb near cap, but not overlapping
  823. capsule = AZ::Capsule(AZ::Vector3(-10.0f, 0.0f, 0.0f), AZ::Vector3(-6.1f, 0.0f, 0.0f), 5.0f);
  824. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(capsule, unitAabb));
  825. // aabb near side, slightly overlapping
  826. capsule = AZ::Capsule(AZ::Vector3(-10.0f, 5.9f, 0.0f), AZ::Vector3(10.0f, 5.9f, 0.0f), 5.0f);
  827. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(capsule, unitAabb));
  828. // aabb near side, not overlapping
  829. capsule = AZ::Capsule(AZ::Vector3(-10.0f, 6.1f, 0.0f), AZ::Vector3(10.0f, 6.1f, 0.0f), 5.0f);
  830. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(capsule, unitAabb));
  831. // aabb diagonal, overlapping
  832. capsule = AZ::Capsule(AZ::Vector3(-8.0f, -5.0f, 0.0f), AZ::Vector3(5.0f, 8.0f, 0.0f), 0.8f);
  833. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(capsule, unitAabb));
  834. // aabb diagonal, not overlapping
  835. capsule = AZ::Capsule(AZ::Vector3(-8.0f, -5.0f, 0.0f), AZ::Vector3(5.0f, 8.0f, 0.0f), 0.7f);
  836. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(capsule, unitAabb));
  837. }
  838. TEST(MATH_ShapeIntersection, CapsuleOverlapsCapsule)
  839. {
  840. AZ::Capsule capsule;
  841. AZ::Capsule longCapsule = AZ::Capsule(AZ::Vector3(-10.0f, 0.0f, 0.0f), AZ::Vector3(10.0f, 0.0f, 0.0f), 1.0f);
  842. AZ::Capsule shortCapsule = AZ::Capsule(AZ::Vector3(-0.5f, 0.0f, 0.0f), AZ::Vector3(0.5f, 0.0f, 0.0f), 1.0f);
  843. // capsule overlaps self
  844. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(longCapsule, longCapsule));
  845. // narrow perpendicular capsule miss
  846. capsule = AZ::Capsule(AZ::Vector3(0.0f, -10.0f, 2.0f), AZ::Vector3(0.0f, 10.0f, 2.0f), 0.5f);
  847. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(capsule, longCapsule));
  848. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(capsule, shortCapsule));
  849. // narrow perpendicular capsule hit
  850. capsule = AZ::Capsule(AZ::Vector3(0.0f, -10.0f, 1.4f), AZ::Vector3(0.0f, 10.0f, 1.4f), 0.5f);
  851. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(capsule, longCapsule));
  852. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(capsule, shortCapsule));
  853. // wide perpendicular capsule miss
  854. capsule = AZ::Capsule(AZ::Vector3(0.0f, -10.0f, 6.1f), AZ::Vector3(0.0f, 10.0f, 6.1f), 5.0f);
  855. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(capsule, longCapsule));
  856. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(capsule, shortCapsule));
  857. // wide perpendicular capsule hit
  858. capsule = AZ::Capsule(AZ::Vector3(0.0f, -10.0f, 5.9f), AZ::Vector3(0.0f, 10.0f, 5.9f), 5.0f);
  859. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(capsule, longCapsule));
  860. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(capsule, shortCapsule));
  861. // diagonal capsules
  862. {
  863. AZ::Capsule capsule1 = AZ::Capsule(AZ::Vector3(-10.0f, -10.0f, 0.0f), AZ::Vector3(10.0f, 10.0f, 0.0f), 1.0f);
  864. AZ::Capsule capsule2 = AZ::Capsule(AZ::Vector3(10.0f, -10.0f, 1.0f), AZ::Vector3(-10.0f, 10.0f, 1.0f), 1.0f);
  865. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(capsule1, capsule2));
  866. AZ::Capsule capsule3 = AZ::Capsule(AZ::Vector3(-10.0f, -10.0f, 0.0f), AZ::Vector3(10.0f, 10.0f, 0.0f), 2.0f);
  867. AZ::Capsule capsule4 = AZ::Capsule(AZ::Vector3(10.0f, -10.0f, 4.1f), AZ::Vector3(-10.0f, 10.0f, 4.1f), 2.0f);
  868. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(capsule3, capsule4));
  869. }
  870. // parallel capsules, end point intersection
  871. {
  872. AZ::Capsule capsule1 = AZ::Capsule(AZ::Vector3(-10.0f, 0.0, 0.0f), AZ::Vector3(-1.0f, 0.0f, 0.0f), 1.1f);
  873. AZ::Capsule capsule2 = AZ::Capsule(AZ::Vector3(1.0f, 0.0, 0.0f), AZ::Vector3(10.0f, 0.0f, 0.0f), 1.1f);
  874. EXPECT_TRUE(AZ::ShapeIntersection::Overlaps(capsule1, capsule2));
  875. AZ::Capsule capsule3 = AZ::Capsule(AZ::Vector3(-10.0f, 0.0, 0.0f), AZ::Vector3(-1.0f, 0.0f, 0.0f), 0.9f);
  876. AZ::Capsule capsule4 = AZ::Capsule(AZ::Vector3(1.0f, 0.0, 0.0f), AZ::Vector3(10.0f, 0.0f, 0.0f), 0.9f);
  877. EXPECT_FALSE(AZ::ShapeIntersection::Overlaps(capsule3, capsule4));
  878. }
  879. }
  880. TEST(MATH_ShapeIntersection, CapsuleContainsSphere)
  881. {
  882. AZ::Capsule capsule = AZ::Capsule(AZ::Vector3(-10.0f, 0.0f, 0.0f), AZ::Vector3(10.0f, 0.0f, 0.0f), 1.0f);
  883. AZ::Sphere sphere = AZ::Sphere(AZ::Vector3(0.0f, 0.0f, 0.0f), 1.0f);
  884. EXPECT_TRUE(AZ::ShapeIntersection::Contains(capsule, sphere));
  885. sphere = AZ::Sphere(AZ::Vector3(-10.0f, 0.0f, 0.0f), 0.5f);
  886. EXPECT_TRUE(AZ::ShapeIntersection::Contains(capsule, sphere));
  887. sphere = AZ::Sphere(AZ::Vector3(10.0f, 0.0f, 0.0f), 1.5f);
  888. EXPECT_FALSE(AZ::ShapeIntersection::Contains(capsule, sphere));
  889. sphere = AZ::Sphere(AZ::Vector3(10.0f, 10.0f, 0.0f), 0.5f);
  890. EXPECT_FALSE(AZ::ShapeIntersection::Contains(capsule, sphere));
  891. }
  892. TEST(MATH_ShapeIntersection, CapsuleContainsAabb)
  893. {
  894. AZ::Capsule capsule = AZ::Capsule(AZ::Vector3(-1.0f, 0.0f, 0.0f), AZ::Vector3(1.0f, 0.0f, 0.0f), 2.0f);
  895. AZ::Aabb unitAabb = AZ::Aabb::CreateCenterHalfExtents(AZ::Vector3::CreateZero(), AZ::Vector3::CreateOne());
  896. EXPECT_TRUE(AZ::ShapeIntersection::Contains(capsule, unitAabb));
  897. capsule = AZ::Capsule(AZ::Vector3(-1.0f, 0.0f, 0.0f), AZ::Vector3(1.0f, 0.0f, 0.0f), 1.0f);
  898. EXPECT_FALSE(AZ::ShapeIntersection::Contains(capsule, unitAabb));
  899. // long thin aabb inside long capsule
  900. capsule = AZ::Capsule(AZ::Vector3(-10.0f, 0.0f, 0.0f), AZ::Vector3(10.0f, 0.0f, 0.0f), 2.0f);
  901. AZ::Aabb longAabb = AZ::Aabb::CreateCenterHalfExtents(AZ::Vector3::CreateZero(), AZ::Vector3(10.0f, 1.0f, 1.0f));
  902. EXPECT_TRUE(AZ::ShapeIntersection::Contains(capsule, longAabb));
  903. longAabb = AZ::Aabb::CreateCenterHalfExtents(AZ::Vector3::CreateZero(), AZ::Vector3(11.0f, 1.0f, 10.0f));
  904. EXPECT_FALSE(AZ::ShapeIntersection::Contains(capsule, longAabb));
  905. }
  906. } // namespace UnitTest