PlaneTests.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  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/Math/Plane.h>
  9. #include <AzCore/Math/Transform.h>
  10. #include <AzCore/Math/Vector2.h>
  11. #include <AzCore/Math/Vector3.h>
  12. #include <AzCore/Math/Vector4.h>
  13. #include <AzCore/UnitTest/TestTypes.h>
  14. #include <AZTestShared/Math/MathTestHelpers.h>
  15. #include <Math/MathTest.h>
  16. using namespace AZ;
  17. namespace UnitTest
  18. {
  19. TEST(MATH_Plane, TestCreateFromNormalAndDistance)
  20. {
  21. Plane pl = Plane::CreateFromNormalAndDistance(Vector3(1.0f, 0.0f, 0.0f), -100.0f);
  22. EXPECT_NEAR(pl.GetDistance(), -100.0f, 2e-3f);
  23. EXPECT_NEAR(pl.GetNormal().GetX(), 1.0f, 2e-3f);
  24. EXPECT_NEAR(pl.GetNormal().GetY(), 0.0f, 2e-3f);
  25. EXPECT_NEAR(pl.GetNormal().GetZ(), 0.0f, 2e-3f);
  26. }
  27. TEST(MATH_Plane, TestCreateFromNormalAndPoint)
  28. {
  29. Plane pl = Plane::CreateFromNormalAndPoint(Vector3(0.0f, 1.0f, 0.0f), Vector3(10, 10, 10));
  30. EXPECT_NEAR(pl.GetDistance(), -10.0f, 2e-3f);
  31. EXPECT_NEAR(pl.GetNormal().GetX(), 0.0f, 2e-3f);
  32. EXPECT_NEAR(pl.GetNormal().GetY(), 1.0f, 2e-3f);
  33. EXPECT_NEAR(pl.GetNormal().GetZ(), 0.0f, 2e-3f);
  34. }
  35. TEST(MATH_Plane, TestCreateFromCoefficients)
  36. {
  37. Plane pl = Plane::CreateFromCoefficients(0.0f, -1.0f, 0.0f, -5.0f);
  38. EXPECT_NEAR(pl.GetDistance(), -5.0f, 2e-3f);
  39. EXPECT_NEAR(pl.GetNormal().GetX(), 0.0f, 2e-3f);
  40. EXPECT_NEAR(pl.GetNormal().GetY(), -1.0f, 2e-3f);
  41. EXPECT_NEAR(pl.GetNormal().GetZ(), 0.0f, 2e-3f);
  42. }
  43. TEST(MATH_Plane, TestSet)
  44. {
  45. Plane pl;
  46. AZ_MATH_TEST_START_TRACE_SUPPRESSION;
  47. pl.Set(12.0f, 13.0f, 14.0f, 15.0f);
  48. AZ_MATH_TEST_STOP_TRACE_SUPPRESSION(1);
  49. EXPECT_NEAR(pl.GetDistance(), 15.0f, 2e-3f);
  50. EXPECT_NEAR(pl.GetNormal().GetX(), 12.0f, 2e-3f);
  51. EXPECT_NEAR(pl.GetNormal().GetY(), 13.0f, 2e-3f);
  52. EXPECT_NEAR(pl.GetNormal().GetZ(), 14.0f, 2e-3f);
  53. }
  54. TEST(MATH_Plane, TestSetVector3)
  55. {
  56. Plane pl;
  57. AZ_MATH_TEST_START_TRACE_SUPPRESSION;
  58. pl.Set(Vector3(22.0f, 23.0f, 24.0f), 25.0f);
  59. AZ_MATH_TEST_STOP_TRACE_SUPPRESSION(1);
  60. EXPECT_NEAR(pl.GetDistance(), 25.0f, 2e-3f);
  61. EXPECT_NEAR(pl.GetNormal().GetX(), 22.0f, 2e-3f);
  62. EXPECT_NEAR(pl.GetNormal().GetY(), 23.0f, 2e-3f);
  63. EXPECT_NEAR(pl.GetNormal().GetZ(), 24.0f, 2e-3f);
  64. }
  65. TEST(MATH_Plane, TestSetVector4)
  66. {
  67. Plane pl;
  68. pl.Set(Vector4(32.0f, 33.0f, 34.0f, 35.0f));
  69. EXPECT_NEAR(pl.GetDistance(), 35.0f, 2e-3f);
  70. EXPECT_NEAR(pl.GetNormal().GetX(), 32.0f, 2e-3f);
  71. EXPECT_NEAR(pl.GetNormal().GetY(), 33.0f, 2e-3f);
  72. EXPECT_NEAR(pl.GetNormal().GetZ(), 34.0f, 2e-3f);
  73. }
  74. TEST(MATH_Plane, TestSetNormalAndDistance)
  75. {
  76. Plane pl;
  77. pl.SetNormal(Vector3(0.0f, 0.0f, 1.0f));
  78. EXPECT_NEAR(pl.GetNormal().GetX(), 0.0f, 2e-3f);
  79. EXPECT_NEAR(pl.GetNormal().GetY(), 0.0f, 2e-3f);
  80. EXPECT_NEAR(pl.GetNormal().GetZ(), 1.0f, 2e-3f);
  81. pl.SetDistance(55.0f);
  82. EXPECT_NEAR(pl.GetDistance(), 55.0f, 2e-3f);
  83. EXPECT_NEAR(pl.GetPlaneEquationCoefficients().GetW(), 55.0f, 2e-3f);
  84. EXPECT_NEAR(pl.GetPlaneEquationCoefficients().GetX(), 0.0f, 2e-3f);
  85. EXPECT_NEAR(pl.GetPlaneEquationCoefficients().GetY(), 0.0f, 2e-3f);
  86. EXPECT_NEAR(pl.GetPlaneEquationCoefficients().GetZ(), 1.0f, 2e-3f);
  87. }
  88. TEST(MATH_Plane, TestGetTransform)
  89. {
  90. Plane pl;
  91. pl.Set(Vector3(0.0f, 0.0f, 1.0f), 55.0f);
  92. Transform tm = Transform::CreateRotationY(DegToRad(90.0f));
  93. pl = pl.GetTransform(tm);
  94. EXPECT_NEAR(pl.GetPlaneEquationCoefficients().GetW(), 55.0f, 2e-3f);
  95. EXPECT_NEAR(pl.GetPlaneEquationCoefficients().GetX(), 1.0f, 2e-3f);
  96. EXPECT_NEAR(pl.GetPlaneEquationCoefficients().GetY(), 0.0f, 2e-3f);
  97. EXPECT_NEAR(pl.GetPlaneEquationCoefficients().GetZ(), 0.0f, 2e-3f);
  98. float dist = pl.GetPointDist(Vector3(10.0f, 0.0f, 0.0f));
  99. EXPECT_NEAR(dist, 65.0f, 2e-3f); // 55 + 10
  100. }
  101. TEST(MATH_Plane, TestApplyTransform)
  102. {
  103. Plane pl;
  104. pl.Set(Vector3(0.0f, 0.0f, 1.0f), 55.0f);
  105. Transform tm1 = Transform::CreateRotationY(DegToRad(90.0f));
  106. Transform tm2 = Transform::CreateRotationZ(DegToRad(45.0f));
  107. pl.ApplyTransform(tm1);
  108. pl.ApplyTransform(tm2);
  109. EXPECT_NEAR(pl.GetPlaneEquationCoefficients().GetW(), 55.0f, 2e-3f);
  110. EXPECT_NEAR(pl.GetPlaneEquationCoefficients().GetX(), 0.707f, 2e-3f);
  111. EXPECT_NEAR(pl.GetPlaneEquationCoefficients().GetY(), 0.707f, 2e-3f);
  112. EXPECT_NEAR(pl.GetPlaneEquationCoefficients().GetZ(), 0.0f, 2e-3f);
  113. }
  114. TEST(MATH_Plane, TestGetProjected)
  115. {
  116. Plane pl;
  117. pl.Set(Vector3(0.0f, 0.0f, 1.0f), 55.0f);
  118. Vector3 v1 = pl.GetProjected(Vector3(10.0f, 15.0f, 20.0f));
  119. EXPECT_THAT(v1, IsCloseTolerance(Vector3(10.0f, 15.0f, 0.0f), 1e-6f));
  120. }
  121. TEST(MATH_Plane, TestCastRay)
  122. {
  123. Vector3 hitPoint;
  124. Plane pl;
  125. pl.Set(0.0f, 0.0f, 1.0f, 10.0f);
  126. bool hit = pl.CastRay(Vector3(0.0f, 0.0f, 0.0f), Vector3(0.0f, 0.0f, 1.0f), hitPoint);
  127. EXPECT_TRUE(hit);
  128. EXPECT_THAT(hitPoint, IsClose(Vector3(0.0f, 0.0f, -10.0f)));
  129. pl.Set(0.0f, 1.0f, 0.0f, 10.0f);
  130. float time;
  131. hit = pl.CastRay(Vector3(0.0f, 1.0f, 0.0f), Vector3(0.0f, -1.0f, 0.0f), time);
  132. EXPECT_TRUE(hit);
  133. EXPECT_NEAR(time, 10.999f, 2e-3f);
  134. pl.Set(1.0f, 0.0f, 0.0f, 5.0f);
  135. hit = pl.CastRay(Vector3(0.0f, 1.0f, 0.0f), Vector3(0.0f, -1.0f, 0.0f), time);
  136. EXPECT_FALSE(hit);
  137. }
  138. TEST(MATH_Plane, TestIntersectSegment)
  139. {
  140. Vector3 hitPoint;
  141. Plane pl;
  142. pl.Set(1.0f, 0.0f, 0.0f, 0.0f);
  143. bool hit = pl.IntersectSegment(Vector3(-1.0f, 0.0f, 0.0f), Vector3(1.0f, 0.0f, 0.0f), hitPoint);
  144. EXPECT_TRUE(hit);
  145. EXPECT_THAT(hitPoint, IsClose(Vector3(0.0f, 0.0f, 0.0f)));
  146. float time;
  147. pl.Set(0.0f, 1.0f, 0.0f, 0.0f);
  148. hit = pl.IntersectSegment(Vector3(0.0f, -10.0f, 0.0f), Vector3(0.0f, 10.0f, 0.0f), time);
  149. EXPECT_TRUE(hit);
  150. EXPECT_NEAR(time, 0.5f, 2e-3f);
  151. pl.Set(0.0f, 1.0f, 0.0f, 20.0f);
  152. hit = pl.IntersectSegment(Vector3(-1.0f, 0.0f, 0.0f), Vector3(1.0f, 0.0f, 0.0f), time);
  153. EXPECT_FALSE(hit);
  154. }
  155. // use of infinity with fast math is simply not supported
  156. #if !defined(O3DE_USING_FAST_MATH)
  157. TEST(MATH_Plane, TestIsFinite)
  158. {
  159. Plane pl;
  160. pl.Set(1.0f, 0.0f, 0.0f, 0.0f);
  161. EXPECT_TRUE(pl.IsFinite());
  162. const float infinity = std::numeric_limits<float>::infinity();
  163. AZ_MATH_TEST_START_TRACE_SUPPRESSION;
  164. pl.Set(infinity, infinity, infinity, infinity);
  165. AZ_MATH_TEST_STOP_TRACE_SUPPRESSION(1);
  166. EXPECT_FALSE(pl.IsFinite());
  167. }
  168. #endif // !defined(O3DE_USING_FAST_MATH)
  169. TEST(MATH_Plane, CreateFromVectorCoefficients_IsEquivalentToCreateFromCoefficients)
  170. {
  171. AZ_MATH_TEST_START_TRACE_SUPPRESSION;
  172. Plane planeFromCoefficients = Plane::CreateFromCoefficients(1.0, 2.0, 3.0, 4.0);
  173. AZ_MATH_TEST_STOP_TRACE_SUPPRESSION(1);
  174. Vector4 coefficients(1.0, 2.0, 3.0, 4.0);
  175. Plane planeFromVectorCoefficients = Plane::CreateFromVectorCoefficients(coefficients);
  176. EXPECT_EQ(planeFromVectorCoefficients, planeFromCoefficients);
  177. }
  178. }