ObbTests.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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. TEST(MATH_Obb, TestIsFinite)
  88. {
  89. Obb obb = Obb::CreateFromPositionRotationAndHalfLengths(position, rotation, halfLengths);
  90. EXPECT_TRUE(obb.IsFinite());
  91. const float infinity = std::numeric_limits<float>::infinity();
  92. const Vector3 infiniteV3 = Vector3(infinity);
  93. // Test to make sure that setting properties of the bounding box
  94. // properly mark it as infinite, and when reset it becomes finite again.
  95. obb.SetPosition(infiniteV3);
  96. EXPECT_FALSE(obb.IsFinite());
  97. obb.SetPosition(position);
  98. EXPECT_TRUE(obb.IsFinite());
  99. obb.SetHalfLengthY(infinity);
  100. EXPECT_FALSE(obb.IsFinite());
  101. }
  102. TEST(MATH_Obb, Contains)
  103. {
  104. const Vector3 testPosition(1.0f, 2.0f, 3.0f);
  105. const Quaternion testRotation = Quaternion::CreateRotationZ(DegToRad(30.0f));
  106. const Vector3 testHalfLengths(2.0f, 1.0f, 2.5f);
  107. const Obb obb = Obb::CreateFromPositionRotationAndHalfLengths(testPosition, testRotation, testHalfLengths);
  108. // test some pairs of points which should be just either side of the Obb boundary
  109. EXPECT_TRUE(obb.Contains(Vector3(1.35f, 3.35f, 3.5f)));
  110. EXPECT_FALSE(obb.Contains(Vector3(1.35f, 3.4f, 3.5f)));
  111. EXPECT_TRUE(obb.Contains(Vector3(-1.1f, 1.7f, 2.0f)));
  112. EXPECT_FALSE(obb.Contains(Vector3(-1.2f, 1.7f, 2.0f)));
  113. EXPECT_TRUE(obb.Contains(Vector3(1.7f, 1.8f, 5.45f)));
  114. EXPECT_FALSE(obb.Contains(Vector3(1.7f, 1.8f, 5.55f)));
  115. }
  116. TEST(MATH_Obb, GetDistance)
  117. {
  118. const Vector3 testPosition(5.0f, 3.0f, 2.0f);
  119. const Quaternion testRotation = Quaternion::CreateRotationX(DegToRad(60.0f));
  120. const Vector3 testHalfLengths(0.5f, 2.0f, 1.5f);
  121. const Obb obb = Obb::CreateFromPositionRotationAndHalfLengths(testPosition, testRotation, testHalfLengths);
  122. EXPECT_NEAR(obb.GetDistance(Vector3(5.3f, 3.2f, 1.8f)), 0.0f, 1e-3f);
  123. EXPECT_NEAR(obb.GetDistance(Vector3(5.1f, 1.1f, 3.7f)), 0.9955f, 1e-3f);
  124. EXPECT_NEAR(obb.GetDistance(Vector3(4.7f, 4.5f, 4.2f)), 0.6553f, 1e-3f);
  125. EXPECT_NEAR(obb.GetDistance(Vector3(3.9f, 3.6f, -3.0f)), 2.6059f, 1e-3f);
  126. }
  127. TEST(MATH_Obb, GetDistanceSq)
  128. {
  129. const Vector3 testPosition(1.0f, 4.0f, 3.0f);
  130. const Quaternion testRotation = Quaternion::CreateRotationY(DegToRad(45.0f));
  131. const Vector3 testHalfLengths(1.5f, 3.0f, 1.0f);
  132. const Obb obb = Obb::CreateFromPositionRotationAndHalfLengths(testPosition, testRotation, testHalfLengths);
  133. EXPECT_NEAR(obb.GetDistanceSq(Vector3(1.1f, 4.3f, 2.7f)), 0.0f, 1e-3f);
  134. EXPECT_NEAR(obb.GetDistanceSq(Vector3(-0.7f, 3.5f, 2.0f)), 0.8266f, 1e-3f);
  135. EXPECT_NEAR(obb.GetDistanceSq(Vector3(2.4f, 0.5f, 1.5f)), 0.5532f, 1e-3f);
  136. EXPECT_NEAR(obb.GetDistanceSq(Vector3(1.1f, 7.3f, 5.8f)), 1.3612f, 1e-3f);
  137. }
  138. } // namespace UnitTest::ObbTests