ObbTests.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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 <AZTestShared/Math/MathTestHelpers.h>
  9. #include <AzCore/Math/Aabb.h>
  10. #include <AzCore/Math/Obb.h>
  11. #include <AzCore/Math/Transform.h>
  12. #include <AzCore/Math/Vector3.h>
  13. #include <AzCore/UnitTest/TestTypes.h>
  14. using namespace AZ;
  15. namespace UnitTest::ObbTests
  16. {
  17. const Vector3 position(1.0f, 2.0f, 3.0f);
  18. const Quaternion rotation = Quaternion::CreateRotationZ(Constants::QuarterPi);
  19. const Vector3 halfLengths(0.5f);
  20. TEST(MATH_Obb, TestCreateFromPositionRotationAndHalfLengths)
  21. {
  22. const Obb obb = Obb::CreateFromPositionRotationAndHalfLengths(position, rotation, halfLengths);
  23. EXPECT_THAT(obb.GetPosition(), IsClose(position));
  24. EXPECT_THAT(obb.GetRotation(), IsClose(rotation));
  25. EXPECT_THAT(obb.GetHalfLengths(), IsClose(halfLengths));
  26. }
  27. TEST(MATH_Obb, TestCreateFromAabb)
  28. {
  29. const Vector3 min(-100.0f, 50.0f, 0.0f);
  30. const Vector3 max(120.0f, 300.0f, 50.0f);
  31. const Aabb aabb = Aabb::CreateFromMinMax(min, max);
  32. const Obb obb = Obb::CreateFromAabb(aabb);
  33. EXPECT_THAT(obb.GetPosition(), IsClose(Vector3(10.0f, 175.0f, 25.0f)));
  34. EXPECT_THAT(obb.GetAxisX(), IsClose(Vector3(1.0f, 0.0f, 0.0f)));
  35. EXPECT_THAT(obb.GetAxisY(), IsClose(Vector3(0.0f, 1.0f, 0.0f)));
  36. EXPECT_THAT(obb.GetAxisZ(), IsClose(Vector3(0.0f, 0.0f, 1.0f)));
  37. }
  38. TEST(MATH_Obb, TestTransform)
  39. {
  40. Obb obb = Obb::CreateFromPositionRotationAndHalfLengths(position, rotation, halfLengths);
  41. Transform transform = Transform::CreateRotationY(DegToRad(90.0f));
  42. obb = transform * obb;
  43. EXPECT_THAT(obb.GetPosition(), IsClose(Vector3(3.0f, 2.0f, -1.0f)));
  44. EXPECT_THAT(obb.GetAxisX(), IsClose(Vector3(0.0f, 0.707f, -0.707f)));
  45. EXPECT_THAT(obb.GetAxisY(), IsClose(Vector3(0.0f, 0.707f, 0.707f)));
  46. EXPECT_THAT(obb.GetAxisZ(), IsClose(Vector3(1.0f, 0.0f, 0.0f)));
  47. }
  48. TEST(MATH_Obb, TestScaleTransform)
  49. {
  50. Obb obb = Obb::CreateFromPositionRotationAndHalfLengths(position, rotation, halfLengths);
  51. float scale = 3.0f;
  52. Transform transform = Transform::CreateUniformScale(scale);
  53. obb = transform * obb;
  54. EXPECT_THAT(obb.GetPosition(), IsClose(Vector3(3.0f, 6.0f, 9.0f)));
  55. EXPECT_THAT(obb.GetHalfLengths(), IsClose(Vector3(1.5f, 1.5f, 1.5f)));
  56. }
  57. TEST(MATH_Obb, TestSetPosition)
  58. {
  59. Obb obb;
  60. obb.SetPosition(position);
  61. EXPECT_THAT(obb.GetPosition(), IsClose(position));
  62. }
  63. TEST(MATH_Obb, TestSetHalfLengthX)
  64. {
  65. Obb obb;
  66. obb.SetHalfLengthX(2.0f);
  67. EXPECT_NEAR(obb.GetHalfLengthX(), 2.0f, AZ::Constants::Tolerance);
  68. }
  69. TEST(MATH_Obb, TestSetHalfLengthY)
  70. {
  71. Obb obb;
  72. obb.SetHalfLengthY(3.0f);
  73. EXPECT_NEAR(obb.GetHalfLengthY(), 3.0f, AZ::Constants::Tolerance);
  74. }
  75. TEST(MATH_Obb, TestSetHalfLengthZ)
  76. {
  77. Obb obb;
  78. obb.SetHalfLengthZ(4.0f);
  79. EXPECT_NEAR(obb.GetHalfLengthZ(), 4.0f, AZ::Constants::Tolerance);
  80. }
  81. TEST(MATH_Obb, TestSetHalfLengthIndex)
  82. {
  83. Obb obb;
  84. obb.SetHalfLength(2, 5.0f);
  85. EXPECT_NEAR(obb.GetHalfLength(2), 5.0f, AZ::Constants::Tolerance);
  86. }
  87. // use of infinity with fast math is simply not supported
  88. #if !defined(O3DE_USING_FAST_MATH)
  89. TEST(MATH_Obb, TestIsFinite)
  90. {
  91. Obb obb = Obb::CreateFromPositionRotationAndHalfLengths(position, rotation, halfLengths);
  92. EXPECT_TRUE(obb.IsFinite());
  93. const float infinity = std::numeric_limits<float>::infinity();
  94. const Vector3 infiniteV3 = Vector3(infinity);
  95. // Test to make sure that setting properties of the bounding box
  96. // properly mark it as infinite, and when reset it becomes finite again.
  97. obb.SetPosition(infiniteV3);
  98. EXPECT_FALSE(obb.IsFinite());
  99. obb.SetPosition(position);
  100. EXPECT_TRUE(obb.IsFinite());
  101. obb.SetHalfLengthY(infinity);
  102. EXPECT_FALSE(obb.IsFinite());
  103. }
  104. #endif
  105. TEST(MATH_Obb, Contains)
  106. {
  107. const Vector3 testPosition(1.0f, 2.0f, 3.0f);
  108. const Quaternion testRotation = Quaternion::CreateRotationZ(DegToRad(30.0f));
  109. const Vector3 testHalfLengths(2.0f, 1.0f, 2.5f);
  110. const Obb obb = Obb::CreateFromPositionRotationAndHalfLengths(testPosition, testRotation, testHalfLengths);
  111. // test some pairs of points which should be just either side of the Obb boundary
  112. EXPECT_TRUE(obb.Contains(Vector3(1.35f, 3.35f, 3.5f)));
  113. EXPECT_FALSE(obb.Contains(Vector3(1.35f, 3.4f, 3.5f)));
  114. EXPECT_TRUE(obb.Contains(Vector3(-1.1f, 1.7f, 2.0f)));
  115. EXPECT_FALSE(obb.Contains(Vector3(-1.2f, 1.7f, 2.0f)));
  116. EXPECT_TRUE(obb.Contains(Vector3(1.7f, 1.8f, 5.45f)));
  117. EXPECT_FALSE(obb.Contains(Vector3(1.7f, 1.8f, 5.55f)));
  118. }
  119. TEST(MATH_Obb, GetDistance)
  120. {
  121. const Vector3 testPosition(5.0f, 3.0f, 2.0f);
  122. const Quaternion testRotation = Quaternion::CreateRotationX(DegToRad(60.0f));
  123. const Vector3 testHalfLengths(0.5f, 2.0f, 1.5f);
  124. const Obb obb = Obb::CreateFromPositionRotationAndHalfLengths(testPosition, testRotation, testHalfLengths);
  125. EXPECT_NEAR(obb.GetDistance(Vector3(5.3f, 3.2f, 1.8f)), 0.0f, 1e-3f);
  126. EXPECT_NEAR(obb.GetDistance(Vector3(5.1f, 1.1f, 3.7f)), 0.9955f, 1e-3f);
  127. EXPECT_NEAR(obb.GetDistance(Vector3(4.7f, 4.5f, 4.2f)), 0.6553f, 1e-3f);
  128. EXPECT_NEAR(obb.GetDistance(Vector3(3.9f, 3.6f, -3.0f)), 2.6059f, 1e-3f);
  129. }
  130. TEST(MATH_Obb, GetDistanceSq)
  131. {
  132. const Vector3 testPosition(1.0f, 4.0f, 3.0f);
  133. const Quaternion testRotation = Quaternion::CreateRotationY(DegToRad(45.0f));
  134. const Vector3 testHalfLengths(1.5f, 3.0f, 1.0f);
  135. const Obb obb = Obb::CreateFromPositionRotationAndHalfLengths(testPosition, testRotation, testHalfLengths);
  136. EXPECT_NEAR(obb.GetDistanceSq(Vector3(1.1f, 4.3f, 2.7f)), 0.0f, 1e-3f);
  137. EXPECT_NEAR(obb.GetDistanceSq(Vector3(-0.7f, 3.5f, 2.0f)), 0.8266f, 1e-3f);
  138. EXPECT_NEAR(obb.GetDistanceSq(Vector3(2.4f, 0.5f, 1.5f)), 0.5532f, 1e-3f);
  139. EXPECT_NEAR(obb.GetDistanceSq(Vector3(1.1f, 7.3f, 5.8f)), 1.3612f, 1e-3f);
  140. }
  141. } // namespace UnitTest::ObbTests