TerrainSurfaceGradientListTests.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  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 <Components/TerrainSurfaceGradientListComponent.h>
  9. #include <Terrain/MockTerrainLayerSpawner.h>
  10. #include <GradientSignal/Ebuses/MockGradientRequestBus.h>
  11. #include <TerrainTestFixtures.h>
  12. using ::testing::NiceMock;
  13. using ::testing::Return;
  14. namespace UnitTest
  15. {
  16. class TerrainSurfaceGradientListTest
  17. : public TerrainTestFixture
  18. {
  19. protected:
  20. const AZStd::string surfaceTag1 = "testtag1";
  21. const AZStd::string surfaceTag2 = "testtag2";
  22. UnitTest::MockTerrainLayerSpawnerComponent* AddRequiredComponentsToEntity(AZ::Entity* entity)
  23. {
  24. auto layerSpawnerComponent = entity->CreateComponent<UnitTest::MockTerrainLayerSpawnerComponent>();
  25. return layerSpawnerComponent;
  26. }
  27. };
  28. TEST_F(TerrainSurfaceGradientListTest, SurfaceGradientMissingRequirementsActivateFails)
  29. {
  30. auto entity = CreateEntity();
  31. entity->CreateComponent<Terrain::TerrainSurfaceGradientListComponent>();
  32. const AZ::Entity::DependencySortOutcome sortOutcome = entity->EvaluateDependenciesGetDetails();
  33. EXPECT_FALSE(sortOutcome.IsSuccess());
  34. }
  35. TEST_F(TerrainSurfaceGradientListTest, SurfaceGradientActivateSuccess)
  36. {
  37. auto entity = CreateEntity();
  38. AddRequiredComponentsToEntity(entity.get());
  39. entity->CreateComponent<Terrain::TerrainSurfaceGradientListComponent>();
  40. ActivateEntity(entity.get());
  41. EXPECT_EQ(entity->GetState(), AZ::Entity::State::Active);
  42. }
  43. TEST_F(TerrainSurfaceGradientListTest, SurfaceGradientReturnsSurfaceWeights)
  44. {
  45. // When there is more than one surface/weight defined and added to the component, they should all
  46. // be returned. The component isn't required to return them in descending order.
  47. auto entity = CreateEntity();
  48. AddRequiredComponentsToEntity(entity.get());
  49. auto gradientEntity1 = CreateEntity();
  50. auto gradientEntity2 = CreateEntity();
  51. const float gradient1Value = 0.3f;
  52. NiceMock<UnitTest::MockGradientRequests> mockGradientRequests1(gradientEntity1->GetId());
  53. ON_CALL(mockGradientRequests1, GetValue).WillByDefault(Return(gradient1Value));
  54. const float gradient2Value = 1.0f;
  55. NiceMock<UnitTest::MockGradientRequests> mockGradientRequests2(gradientEntity2->GetId());
  56. ON_CALL(mockGradientRequests2, GetValue).WillByDefault(Return(gradient2Value));
  57. AzFramework::SurfaceData::SurfaceTagWeightList weightList;
  58. Terrain::TerrainAreaSurfaceRequestBus::Event(
  59. entity->GetId(), &Terrain::TerrainAreaSurfaceRequestBus::Events::GetSurfaceWeights, AZ::Vector3::CreateZero(), weightList);
  60. AZ::Crc32 expectedCrcList[] = { AZ::Crc32(surfaceTag1), AZ::Crc32(surfaceTag2) };
  61. const float expectedWeightList[] = { gradient1Value, gradient2Value };
  62. int index = 0;
  63. for (const auto& surfaceWeight : weightList)
  64. {
  65. EXPECT_EQ(surfaceWeight.m_surfaceType, expectedCrcList[index]);
  66. EXPECT_NEAR(surfaceWeight.m_weight, expectedWeightList[index], 0.01f);
  67. index++;
  68. }
  69. }
  70. TEST_F(TerrainSurfaceGradientListTest, SurfaceGradientGetSurfaceWeightsAndGetSurfaceWeightsFromListMatch)
  71. {
  72. // The GetSurfaceWeights and GetSurfaceWeightsFromList APIs should return the same values for the given inputs.
  73. auto entity = CreateEntity();
  74. AddRequiredComponentsToEntity(entity.get());
  75. // Create a deterministic but varying result for our mock gradient - return the fractional part of the X position.
  76. auto gradientEntity1 = CreateEntity();
  77. NiceMock<UnitTest::MockGradientRequests> mockGradientRequests1(gradientEntity1->GetId());
  78. ON_CALL(mockGradientRequests1, GetValue)
  79. .WillByDefault(
  80. [](const GradientSignal::GradientSampleParams& params) -> float
  81. {
  82. double intpart;
  83. return aznumeric_cast<float>(modf(params.m_position.GetX(), &intpart));
  84. });
  85. // Return varying result for this mock too, but this time return the Y position fraction.
  86. auto gradientEntity2 = CreateEntity();
  87. NiceMock<UnitTest::MockGradientRequests> mockGradientRequests2(gradientEntity2->GetId());
  88. ON_CALL(mockGradientRequests2, GetValue)
  89. .WillByDefault(
  90. [](const GradientSignal::GradientSampleParams& params) -> float
  91. {
  92. double intpart;
  93. return aznumeric_cast<float>(modf(params.m_position.GetY(), &intpart));
  94. });
  95. // Build up a list of input positions to query with.
  96. AZStd::vector<AZ::Vector3> inPositions;
  97. for (float y = 0.0f; y <= 10.0f; y += 0.1f)
  98. {
  99. for (float x = 0.0f; x <= 10.0f; x += 0.1f)
  100. {
  101. inPositions.emplace_back(x, y, 0.0f);
  102. }
  103. }
  104. // Call GetSurfaceWeightsFromList to get the set of output SurfaceWeightList values
  105. AZStd::vector<AzFramework::SurfaceData::SurfaceTagWeightList> weightsList(inPositions.size());
  106. Terrain::TerrainAreaSurfaceRequestBus::Event(
  107. entity->GetId(), &Terrain::TerrainAreaSurfaceRequestBus::Events::GetSurfaceWeightsFromList, inPositions, weightsList);
  108. // For each result returned from GetSurfaceWeightsFromList, verify that it matches the result from GetSurfaceWeights
  109. for (size_t index = 0; index < inPositions.size(); index++)
  110. {
  111. AzFramework::SurfaceData::SurfaceTagWeightList weightList;
  112. Terrain::TerrainAreaSurfaceRequestBus::Event(
  113. entity->GetId(), &Terrain::TerrainAreaSurfaceRequestBus::Events::GetSurfaceWeights, inPositions[index], weightList);
  114. // Verify that we're returning the same values in the same order.
  115. ASSERT_EQ(weightsList[index].size(), weightList.size());
  116. for (size_t weightIndex = 0; weightIndex < weightsList[index].size(); weightIndex++)
  117. {
  118. ASSERT_EQ(weightsList[index][weightIndex].m_surfaceType, weightList[weightIndex].m_surfaceType);
  119. ASSERT_EQ(weightsList[index][weightIndex].m_weight, weightList[weightIndex].m_weight);
  120. }
  121. }
  122. }
  123. } // namespace UnitTest