12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007 |
- /*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
- #include <AzCore/std/parallel/semaphore.h>
- #include <AzTest/AzTest.h>
- #include <TerrainSystem/TerrainSystem.h>
- #include <TerrainTestFixtures.h>
- namespace UnitTest::TerrainTest
- {
- /* The TerrainBulkQueryTest suite of tests exist to verify that all of our different query APIs produce the same results.
- * These tests were added after discovering that the async queries could sometimes produce intermittently incorrect results due
- * to a lack of proper thread safety. However, it's also possible that optimizations to the different queries could accidentally
- * produce different results as well, so it's good to have this safety net here.
- */
- class TerrainBulkQueryTest
- : public TerrainTestFixture
- {
- protected:
- // Use the ProcessHeightsFromRegion API as our baseline that we'll compare the other query APIs against.
- void GenerateBaselineHeightData(
- const AZ::Aabb& inputQueryRegion,
- const AZ::Vector2& inputQueryStepSize,
- AzFramework::Terrain::TerrainDataRequests::Sampler sampler,
- AZStd::vector<AZ::Vector3>& queryPositions,
- AZStd::vector<AZ::Vector3>& resultPositions,
- AZStd::vector<bool>& resultExistsFlags)
- {
- queryPositions.clear();
- resultPositions.clear();
- resultExistsFlags.clear();
- auto perPositionCallback = [&queryPositions, &resultPositions, &resultExistsFlags](
- [[maybe_unused]] size_t xIndex, [[maybe_unused]] size_t yIndex,
- const AzFramework::SurfaceData::SurfacePoint& surfacePoint, bool terrainExists)
- {
- queryPositions.emplace_back(surfacePoint.m_position.GetX(), surfacePoint.m_position.GetY(), 0.0f);
- resultPositions.emplace_back(surfacePoint.m_position);
- resultExistsFlags.emplace_back(terrainExists);
- };
- AzFramework::Terrain::TerrainQueryRegion queryRegion =
- AzFramework::Terrain::TerrainQueryRegion::CreateFromAabbAndStepSize(inputQueryRegion, inputQueryStepSize);
- AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
- &AzFramework::Terrain::TerrainDataRequests::QueryRegion, queryRegion,
- AzFramework::Terrain::TerrainDataRequests::TerrainDataMask::Heights, perPositionCallback, sampler);
- EXPECT_EQ(queryPositions.size(), resultPositions.size());
- }
- // Compare two sets of output data and verify that they match.
- void ComparePositionData(const AZStd::vector<AZ::Vector3>& baselineValues, const AZStd::vector<bool>& baselineExistsFlags,
- const AZStd::vector<AZ::Vector3>& comparisonValues, const AZStd::vector<bool>& comparisonExistsFlags)
- {
- // Verify that we have the same quantity of results in both sets.
- ASSERT_EQ(baselineValues.size(), comparisonValues.size());
- // Verify that every value is found exactly once in each set. The two sets might not have the values in the same order though,
- // so we need to search for each value, verify it's found, and verify that it hadn't previously been found.
- AZStd::vector<bool> matchFound(baselineValues.size(), false);
- for (size_t comparisonIndex = 0; comparisonIndex < comparisonValues.size(); comparisonIndex++)
- {
- auto foundValue = AZStd::find(baselineValues.begin(), baselineValues.end(), comparisonValues[comparisonIndex]);
- EXPECT_NE(foundValue, baselineValues.end());
- if (foundValue != baselineValues.end())
- {
- size_t foundIndex = foundValue - baselineValues.begin();
- EXPECT_FALSE(matchFound[foundIndex]);
- EXPECT_EQ(baselineExistsFlags[foundIndex], comparisonExistsFlags[comparisonIndex]);
- matchFound[foundIndex] = true;
- }
- }
- }
- // Use the ProcessNormalsFromRegion API as our baseline that we'll compare the other query APIs against.
- void GenerateBaselineNormalData(
- const AZ::Aabb& inputQueryRegion,
- const AZ::Vector2& inputQueryStepSize,
- AzFramework::Terrain::TerrainDataRequests::Sampler sampler,
- AZStd::vector<AZ::Vector3>& queryPositions,
- AZStd::vector<AZ::Vector3>& resultNormals,
- AZStd::vector<bool>& resultExistsFlags)
- {
- queryPositions.clear();
- resultNormals.clear();
- resultExistsFlags.clear();
- auto perPositionCallback = [&queryPositions, &resultNormals, &resultExistsFlags](
- [[maybe_unused]] size_t xIndex, [[maybe_unused]] size_t yIndex,
- const AzFramework::SurfaceData::SurfacePoint& surfacePoint, bool terrainExists)
- {
- queryPositions.emplace_back(surfacePoint.m_position.GetX(), surfacePoint.m_position.GetY(), 0.0f);
- resultNormals.emplace_back(surfacePoint.m_normal);
- resultExistsFlags.emplace_back(terrainExists);
- };
- AzFramework::Terrain::TerrainQueryRegion queryRegion =
- AzFramework::Terrain::TerrainQueryRegion::CreateFromAabbAndStepSize(inputQueryRegion, inputQueryStepSize);
- AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
- &AzFramework::Terrain::TerrainDataRequests::QueryRegion, queryRegion,
- AzFramework::Terrain::TerrainDataRequests::TerrainDataMask::Normals, perPositionCallback, sampler);
- EXPECT_EQ(queryPositions.size(), resultNormals.size());
- }
- // Compare two sets of output data and verify that they match.
- void CompareNormalData(
- const AZStd::vector<AZ::Vector3>& baselineQueryPositions,
- const AZStd::vector<AZ::Vector3>& baselineValues,
- const AZStd::vector<bool>& baselineExistsFlags,
- const AZStd::vector<AZ::Vector3>& comparisonQueryPositions,
- const AZStd::vector<AZ::Vector3>& comparisonValues,
- const AZStd::vector<bool>& comparisonExistsFlags)
- {
- // Verify that we have the same quantity of results in both sets.
- ASSERT_EQ(baselineValues.size(), comparisonValues.size());
- // Verify that every value is found exactly once in each set. The two sets might not have the values in the same order though,
- // so we need to search for each value, verify it's found, and verify that it hadn't previously been found.
- // Also, since normals are easy to duplicate, we'll search by query positions to find the normals to compare.
- AZStd::vector<bool> matchFound(baselineValues.size(), false);
- for (size_t comparisonIndex = 0; comparisonIndex < comparisonQueryPositions.size(); comparisonIndex++)
- {
- auto& comparisonPosition = comparisonQueryPositions[comparisonIndex];
- auto foundPosition = AZStd::find(baselineQueryPositions.begin(), baselineQueryPositions.end(), comparisonPosition);
- EXPECT_NE(foundPosition, baselineQueryPositions.end());
- if (foundPosition != baselineQueryPositions.end())
- {
- size_t foundIndex = foundPosition - baselineQueryPositions.begin();
- EXPECT_FALSE(matchFound[foundIndex]);
- EXPECT_EQ(baselineValues[foundIndex], comparisonValues[comparisonIndex]);
- EXPECT_EQ(baselineExistsFlags[foundIndex], comparisonExistsFlags[comparisonIndex]);
- matchFound[foundIndex] = true;
- }
- }
- }
- // Use the ProcessSurfaceWeightsFromRegion API as our baseline that we'll compare the other query APIs against.
- void GenerateBaselineSurfaceWeightData(
- const AZ::Aabb& inputQueryRegion,
- const AZ::Vector2& inputQueryStepSize,
- AzFramework::Terrain::TerrainDataRequests::Sampler sampler,
- AZStd::vector<AZ::Vector3>& queryPositions,
- AZStd::vector<AzFramework::SurfaceData::SurfaceTagWeightList>& resultWeights)
- {
- queryPositions.clear();
- resultWeights.clear();
- auto perPositionCallback = [&queryPositions, &resultWeights](
- [[maybe_unused]] size_t xIndex, [[maybe_unused]] size_t yIndex,
- const AzFramework::SurfaceData::SurfacePoint& surfacePoint, bool terrainExists)
- {
- queryPositions.emplace_back(surfacePoint.m_position.GetX(), surfacePoint.m_position.GetY(), 0.0f);
- resultWeights.emplace_back(surfacePoint.m_surfaceTags);
- // For these unit tests, we expect every point queried to have valid terrain data.
- EXPECT_TRUE(terrainExists);
- };
- AzFramework::Terrain::TerrainQueryRegion queryRegion =
- AzFramework::Terrain::TerrainQueryRegion::CreateFromAabbAndStepSize(inputQueryRegion, inputQueryStepSize);
- AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
- &AzFramework::Terrain::TerrainDataRequests::QueryRegion, queryRegion,
- AzFramework::Terrain::TerrainDataRequests::TerrainDataMask::SurfaceData, perPositionCallback, sampler);
- EXPECT_EQ(queryPositions.size(), resultWeights.size());
- }
- // Compare two sets of output data and verify that they match.
- void CompareSurfaceWeightData(
- const AZStd::vector<AZ::Vector3>& baselineQueryPositions,
- const AZStd::vector<AzFramework::SurfaceData::SurfaceTagWeightList>& baselineValues,
- const AZStd::vector<AZ::Vector3>& comparisonQueryPositions,
- const AZStd::vector<AzFramework::SurfaceData::SurfaceTagWeightList>& comparisonValues)
- {
- // Verify that we have the same quantity of results in both sets.
- ASSERT_EQ(baselineValues.size(), comparisonValues.size());
- // Verify that every value is found exactly once in each set. The two sets might not have the values in the same order though,
- // so we need to search for each value, verify it's found, and verify that it hadn't previously been found.
- // Also, since surface weight lists are easy to duplicate, we'll search by query positions to find the weight lists to compare.
- AZStd::vector<bool> matchFound(baselineValues.size(), false);
- for (size_t comparisonIndex = 0; comparisonIndex < comparisonQueryPositions.size(); comparisonIndex++)
- {
- auto& comparisonPosition = comparisonQueryPositions[comparisonIndex];
- auto foundPosition = AZStd::find(baselineQueryPositions.begin(), baselineQueryPositions.end(), comparisonPosition);
- EXPECT_NE(foundPosition, baselineQueryPositions.end());
- if (foundPosition != baselineQueryPositions.end())
- {
- size_t foundIndex = foundPosition - baselineQueryPositions.begin();
- EXPECT_FALSE(matchFound[foundIndex]);
- EXPECT_EQ(baselineValues[foundIndex], comparisonValues[comparisonIndex]);
- matchFound[foundIndex] = true;
- }
- }
- }
- // Use the ProcessSurfacePointsFromRegion API as our baseline that we'll compare the other query APIs against.
- void GenerateBaselineSurfacePointData(
- const AZ::Aabb& inputQueryRegion,
- const AZ::Vector2& inputQueryStepSize,
- AzFramework::Terrain::TerrainDataRequests::Sampler sampler,
- AZStd::vector<AZ::Vector3>& queryPositions,
- AZStd::vector<AzFramework::SurfaceData::SurfacePoint>& resultPoints,
- AZStd::vector<bool>& resultExistsFlags)
- {
- queryPositions.clear();
- resultPoints.clear();
- resultExistsFlags.clear();
- auto perPositionCallback = [&queryPositions, &resultPoints, &resultExistsFlags](
- [[maybe_unused]] size_t xIndex, [[maybe_unused]] size_t yIndex,
- const AzFramework::SurfaceData::SurfacePoint& surfacePoint, bool terrainExists)
- {
- queryPositions.emplace_back(surfacePoint.m_position.GetX(), surfacePoint.m_position.GetY(), 0.0f);
- resultPoints.emplace_back(surfacePoint);
- resultExistsFlags.emplace_back(terrainExists);
- };
- AzFramework::Terrain::TerrainQueryRegion queryRegion =
- AzFramework::Terrain::TerrainQueryRegion::CreateFromAabbAndStepSize(inputQueryRegion, inputQueryStepSize);
- AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
- &AzFramework::Terrain::TerrainDataRequests::QueryRegion, queryRegion,
- AzFramework::Terrain::TerrainDataRequests::TerrainDataMask::All, perPositionCallback, sampler);
- EXPECT_EQ(queryPositions.size(), resultPoints.size());
- }
- // Compare two sets of output data and verify that they match.
- void CompareSurfacePointData(
- const AZStd::vector<AzFramework::SurfaceData::SurfacePoint>& baselineValues,
- const AZStd::vector<bool>& baselineExistsFlags,
- const AZStd::vector<AzFramework::SurfaceData::SurfacePoint>& comparisonValues,
- const AZStd::vector<bool>& comparisonExistsFlags)
- {
- // Verify that we have the same quantity of results in both sets.
- ASSERT_EQ(baselineValues.size(), comparisonValues.size());
- // Verify that every value is found exactly once in each set. The two sets might not have the values in the same order though,
- // so we need to search for each value, verify it's found, and verify that it hadn't previously been found.
- AZStd::vector<bool> matchFound(baselineValues.size(), false);
- for (size_t comparisonIndex = 0; comparisonIndex < comparisonValues.size(); comparisonIndex++)
- {
- const auto& comparisonValue = comparisonValues[comparisonIndex];
- auto foundValue = AZStd::find_if(
- baselineValues.begin(), baselineValues.end(),
- [&comparisonValue](const AzFramework::SurfaceData::SurfacePoint& baselineValue) -> bool
- {
- return (baselineValue.m_position == comparisonValue.m_position)
- && (baselineValue.m_normal == comparisonValue.m_normal)
- && (baselineValue.m_surfaceTags == comparisonValue.m_surfaceTags);
- });
- EXPECT_NE(foundValue, baselineValues.end());
- if (foundValue != baselineValues.end())
- {
- size_t foundIndex = foundValue - baselineValues.begin();
- EXPECT_FALSE(matchFound[foundIndex]);
- EXPECT_EQ(baselineExistsFlags[foundIndex], comparisonExistsFlags[comparisonIndex]);
- matchFound[foundIndex] = true;
- if (baselineExistsFlags[foundIndex] != comparisonExistsFlags[comparisonIndex])
- {
- matchFound[foundIndex] = true;
- }
- }
- }
- }
- AZStd::shared_ptr<AzFramework::Terrain::QueryAsyncParams> CreateTestAsyncParams()
- {
- auto params = AZStd::make_shared<AzFramework::Terrain::QueryAsyncParams>();
- // Set the number of jobs > 1 so that we have parallel queries that execute.
- params->m_desiredNumberOfJobs = 4;
- params->m_completionCallback =
- [this]([[maybe_unused]] AZStd::shared_ptr<AzFramework::Terrain::TerrainJobContext> context)
- {
- // Notify the main test thread that the query has completed.
- m_queryCompletionEvent.release();
- };
- return params;
- }
- // Set up the arbitrary terrain world parameters that we'll use for verifying our queries match.
- const static inline float TerrainSize = 32.0f;
- const static inline float TerrainQueryResolution = 1.0f;
- const static inline uint32_t TerrainNumSurfaces = 3;
- const static inline AZ::Aabb TerrainWorldBounds =
- AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TerrainSize / 2.0f), AZ::Vector3(TerrainSize / 2.0f));
- // Set up the query parameters that we'll use for all our queries
- const static inline AZ::Aabb QueryBounds = TerrainWorldBounds;
- const static inline float QueryStepSizeX = TerrainQueryResolution / 2.0f;
- const static inline float QueryStepSizeY = TerrainQueryResolution / 2.0f;
- const static inline uint32_t ExpectedResultCount =
- aznumeric_cast<uint32_t>((TerrainSize / QueryStepSizeX) * (TerrainSize / QueryStepSizeY));
- AZ::Vector2 QueryStepSize = AZ::Vector2(QueryStepSizeX, QueryStepSizeY);
- // Semaphore for use in async tests.
- AZStd::binary_semaphore m_queryCompletionEvent;
- };
- // -----------------------------------------------------------------------------
- // Compare Height Query APIs
- TEST_F(TerrainBulkQueryTest, ProcessHeightsFromRegionAndProcessHeightsFromListProduceSameResults)
- {
- CreateTestTerrainSystem(TerrainWorldBounds, TerrainQueryResolution, TerrainNumSurfaces);
- for (auto sampler : {
- AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR,
- AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP,
- AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT
- })
- {
- // Gather all our initial results from calling Process*FromRegion
- AZStd::vector<AZ::Vector3> queryPositions;
- AZStd::vector<AZ::Vector3> baselineResultPositions;
- AZStd::vector<bool> baselineExistsFlags;
- GenerateBaselineHeightData(QueryBounds, QueryStepSize, sampler, queryPositions, baselineResultPositions, baselineExistsFlags);
- ASSERT_EQ(queryPositions.size(), ExpectedResultCount);
- // Gather results from Process*FromList
- AZStd::vector<AZ::Vector3> comparisonResultPositions;
- AZStd::vector<bool> comparisonExistsFlags;
- auto listPositionCallback = [&comparisonResultPositions, &comparisonExistsFlags]
- (const AzFramework::SurfaceData::SurfacePoint& surfacePoint, bool terrainExists)
- {
- comparisonResultPositions.emplace_back(surfacePoint.m_position);
- comparisonExistsFlags.emplace_back(terrainExists);
- };
- AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
- &AzFramework::Terrain::TerrainDataRequests::QueryList,
- queryPositions, AzFramework::Terrain::TerrainDataRequests::TerrainDataMask::Heights, listPositionCallback, sampler);
- // Compare the results
- ComparePositionData(baselineResultPositions, baselineExistsFlags, comparisonResultPositions, comparisonExistsFlags);
- }
- DestroyTestTerrainSystem();
- }
- TEST_F(TerrainBulkQueryTest, ProcessHeightsFromRegionAndGetHeightProduceSameResults)
- {
- CreateTestTerrainSystem(TerrainWorldBounds, TerrainQueryResolution, TerrainNumSurfaces);
- for (auto sampler :
- { AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR, AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP,
- AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT })
- {
- // Gather all our initial results from calling Process*FromRegion
- AZStd::vector<AZ::Vector3> queryPositions;
- AZStd::vector<AZ::Vector3> baselineResultPositions;
- AZStd::vector<bool> baselineExistsFlags;
- GenerateBaselineHeightData(QueryBounds, QueryStepSize, sampler, queryPositions, baselineResultPositions, baselineExistsFlags);
- ASSERT_EQ(queryPositions.size(), ExpectedResultCount);
- // Gather results from Get*
- AZStd::vector<AZ::Vector3> comparisonResultPositions;
- AZStd::vector<bool> comparisonExistsFlags;
- float worldMinZ = TerrainWorldBounds.GetMin().GetZ();
- for (auto& position : queryPositions)
- {
- float terrainHeight = worldMinZ;
- bool terrainExists = false;
- AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult(
- terrainHeight, &AzFramework::Terrain::TerrainDataRequests::GetHeight, position, sampler, &terrainExists);
- comparisonResultPositions.emplace_back(position.GetX(), position.GetY(), terrainHeight);
- comparisonExistsFlags.emplace_back(terrainExists);
- }
- // Compare the results
- ComparePositionData(baselineResultPositions, baselineExistsFlags, comparisonResultPositions, comparisonExistsFlags);
- }
- DestroyTestTerrainSystem();
- }
- TEST_F(TerrainBulkQueryTest, ProcessHeightsFromRegionAndProcessHeightsFromRegionAsyncProduceSameResults)
- {
- CreateTestTerrainSystem(TerrainWorldBounds, TerrainQueryResolution, TerrainNumSurfaces);
- for (auto sampler :
- { AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR, AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP,
- AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT })
- {
- // Gather all our initial results from calling Process*FromRegion
- AZStd::vector<AZ::Vector3> queryPositions;
- AZStd::vector<AZ::Vector3> baselineResultPositions;
- AZStd::vector<bool> baselineExistsFlags;
- GenerateBaselineHeightData(QueryBounds, QueryStepSize, sampler, queryPositions, baselineResultPositions, baselineExistsFlags);
- ASSERT_EQ(queryPositions.size(), ExpectedResultCount);
- // Gather results from Process*FromRegionAsync
- AZStd::vector<AZ::Vector3> comparisonResultPositions;
- AZStd::vector<bool> comparisonExistsFlags;
- AZStd::mutex outputMutex;
- auto regionPositionCallback = [&comparisonResultPositions, &comparisonExistsFlags, &outputMutex](
- [[maybe_unused]] size_t xIndex, [[maybe_unused]] size_t yIndex,
- const AzFramework::SurfaceData::SurfacePoint& surfacePoint, bool terrainExists)
- {
- // Make sure only one thread can add its result at a time.
- AZStd::scoped_lock lock(outputMutex);
- comparisonResultPositions.emplace_back(surfacePoint.m_position);
- comparisonExistsFlags.emplace_back(terrainExists);
- };
- auto params = CreateTestAsyncParams();
- AZStd::shared_ptr<AzFramework::Terrain::TerrainJobContext> jobContext;
- AzFramework::Terrain::TerrainQueryRegion queryRegion =
- AzFramework::Terrain::TerrainQueryRegion::CreateFromAabbAndStepSize(QueryBounds, QueryStepSize);
- AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult(
- jobContext, &AzFramework::Terrain::TerrainDataRequests::QueryRegionAsync, queryRegion,
- AzFramework::Terrain::TerrainDataRequests::TerrainDataMask::Heights, regionPositionCallback, sampler, params);
- // Wait for the async query to complete
- m_queryCompletionEvent.acquire();
- // Compare the results
- ComparePositionData(baselineResultPositions, baselineExistsFlags, comparisonResultPositions, comparisonExistsFlags);
- }
- DestroyTestTerrainSystem();
- }
- TEST_F(TerrainBulkQueryTest, ProcessHeightsFromRegionAndProcessHeightsFromListAsyncProduceSameResults)
- {
- CreateTestTerrainSystem(TerrainWorldBounds, TerrainQueryResolution, TerrainNumSurfaces);
- for (auto sampler :
- { AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR, AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP,
- AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT })
- {
- // Gather all our initial results from calling Process*FromRegion
- AZStd::vector<AZ::Vector3> queryPositions;
- AZStd::vector<AZ::Vector3> baselineResultPositions;
- AZStd::vector<bool> baselineExistsFlags;
- GenerateBaselineHeightData(QueryBounds, QueryStepSize, sampler, queryPositions, baselineResultPositions, baselineExistsFlags);
- ASSERT_EQ(queryPositions.size(), ExpectedResultCount);
- // Gather results from Process*FromListAsync
- AZStd::vector<AZ::Vector3> comparisonResultPositions;
- AZStd::vector<bool> comparisonExistsFlags;
- AZStd::mutex outputMutex;
- auto listPositionCallback = [&comparisonResultPositions, &comparisonExistsFlags, &outputMutex](
- const AzFramework::SurfaceData::SurfacePoint& surfacePoint, bool terrainExists)
- {
- // Make sure only one thread can add its result at a time.
- AZStd::scoped_lock lock(outputMutex);
- comparisonResultPositions.emplace_back(surfacePoint.m_position);
- comparisonExistsFlags.emplace_back(terrainExists);
- };
- auto params = CreateTestAsyncParams();
- AZStd::shared_ptr<AzFramework::Terrain::TerrainJobContext> jobContext;
- AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult(
- jobContext, &AzFramework::Terrain::TerrainDataRequests::QueryListAsync, queryPositions,
- AzFramework::Terrain::TerrainDataRequests::TerrainDataMask::Heights,
- listPositionCallback, sampler, params);
- // Wait for the async query to complete
- m_queryCompletionEvent.acquire();
- // Compare the results
- ComparePositionData(baselineResultPositions, baselineExistsFlags, comparisonResultPositions, comparisonExistsFlags);
- }
- DestroyTestTerrainSystem();
- }
- // -----------------------------------------------------------------------------
- // Compare Normal Query APIs
- TEST_F(TerrainBulkQueryTest, ProcessNormalsFromRegionAndProcessNormalsFromListProduceSameResults)
- {
- CreateTestTerrainSystem(TerrainWorldBounds, TerrainQueryResolution, TerrainNumSurfaces);
- for (auto sampler :
- { AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR, AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP,
- AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT })
- {
- // Gather all our initial results from calling Process*FromRegion
- AZStd::vector<AZ::Vector3> queryPositions;
- AZStd::vector<AZ::Vector3> baselineResultNormals;
- AZStd::vector<bool> baselineExistsFlags;
- GenerateBaselineNormalData(QueryBounds, QueryStepSize, sampler, queryPositions, baselineResultNormals, baselineExistsFlags);
- ASSERT_EQ(queryPositions.size(), ExpectedResultCount);
- // Gather results from Process*FromList
- AZStd::vector<AZ::Vector3> comparisonResultPositions;
- AZStd::vector<AZ::Vector3> comparisonResultNormals;
- AZStd::vector<bool> comparisonExistsFlags;
- auto listNormalCallback = [&comparisonResultPositions, &comparisonResultNormals, &comparisonExistsFlags](
- const AzFramework::SurfaceData::SurfacePoint& surfacePoint, bool terrainExists)
- {
- comparisonResultPositions.emplace_back(surfacePoint.m_position);
- comparisonResultNormals.emplace_back(surfacePoint.m_normal);
- comparisonExistsFlags.emplace_back(terrainExists);
- };
- AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
- &AzFramework::Terrain::TerrainDataRequests::QueryList, queryPositions,
- AzFramework::Terrain::TerrainDataRequests::TerrainDataMask::Normals, listNormalCallback, sampler);
- // Compare the results
- CompareNormalData(queryPositions, baselineResultNormals, baselineExistsFlags,
- comparisonResultPositions, comparisonResultNormals, comparisonExistsFlags);
- }
- DestroyTestTerrainSystem();
- }
- TEST_F(TerrainBulkQueryTest, ProcessNormalsFromRegionAndGetNormalProduceSameResults)
- {
- CreateTestTerrainSystem(TerrainWorldBounds, TerrainQueryResolution, TerrainNumSurfaces);
- for (auto sampler :
- { AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR, AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP,
- AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT })
- {
- // Gather all our initial results from calling Process*FromRegion
- AZStd::vector<AZ::Vector3> queryPositions;
- AZStd::vector<AZ::Vector3> baselineResultNormals;
- AZStd::vector<bool> baselineExistsFlags;
- GenerateBaselineNormalData(QueryBounds, QueryStepSize, sampler, queryPositions, baselineResultNormals, baselineExistsFlags);
- ASSERT_EQ(queryPositions.size(), ExpectedResultCount);
- // Gather results from Get*
- AZStd::vector<AZ::Vector3> comparisonResultNormals;
- AZStd::vector<bool> comparisonExistsFlags;
- for (auto& position : queryPositions)
- {
- AZ::Vector3 terrainNormal = AZ::Vector3::CreateZero();
- bool terrainExists = false;
- AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult(
- terrainNormal, &AzFramework::Terrain::TerrainDataRequests::GetNormal, position, sampler, &terrainExists);
- comparisonResultNormals.emplace_back(terrainNormal);
- comparisonExistsFlags.emplace_back(terrainExists);
- }
- // Compare the results
- CompareNormalData(queryPositions, baselineResultNormals, baselineExistsFlags,
- queryPositions, comparisonResultNormals, comparisonExistsFlags);
- }
- DestroyTestTerrainSystem();
- }
- TEST_F(TerrainBulkQueryTest, ProcessNormalsFromRegionAndProcessNormalsFromRegionAsyncProduceSameResults)
- {
- CreateTestTerrainSystem(TerrainWorldBounds, TerrainQueryResolution, TerrainNumSurfaces);
- for (auto sampler :
- { AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR, AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP,
- AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT })
- {
- // Gather all our initial results from calling Process*FromRegion
- AZStd::vector<AZ::Vector3> queryPositions;
- AZStd::vector<AZ::Vector3> baselineResultNormals;
- AZStd::vector<bool> baselineExistsFlags;
- GenerateBaselineNormalData(QueryBounds, QueryStepSize, sampler, queryPositions, baselineResultNormals, baselineExistsFlags);
- ASSERT_EQ(queryPositions.size(), ExpectedResultCount);
- // Gather results from Process*FromRegionAsync
- AZStd::vector<AZ::Vector3> comparisonResultPositions;
- AZStd::vector<AZ::Vector3> comparisonResultNormals;
- AZStd::vector<bool> comparisonExistsFlags;
- AZStd::mutex outputMutex;
- auto regionPositionCallback = [&comparisonResultPositions, &comparisonResultNormals, &comparisonExistsFlags, &outputMutex](
- [[maybe_unused]] size_t xIndex, [[maybe_unused]] size_t yIndex,
- const AzFramework::SurfaceData::SurfacePoint& surfacePoint, bool terrainExists)
- {
- // Make sure only one thread can add its result at a time.
- AZStd::scoped_lock lock(outputMutex);
- comparisonResultPositions.emplace_back(surfacePoint.m_position);
- comparisonResultNormals.emplace_back(surfacePoint.m_normal);
- comparisonExistsFlags.emplace_back(terrainExists);
- };
- auto params = CreateTestAsyncParams();
- AZStd::shared_ptr<AzFramework::Terrain::TerrainJobContext> jobContext;
- AzFramework::Terrain::TerrainQueryRegion queryRegion =
- AzFramework::Terrain::TerrainQueryRegion::CreateFromAabbAndStepSize(QueryBounds, QueryStepSize);
- AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult(
- jobContext, &AzFramework::Terrain::TerrainDataRequests::QueryRegionAsync, queryRegion,
- AzFramework::Terrain::TerrainDataRequests::TerrainDataMask::Normals, regionPositionCallback, sampler, params);
- // Wait for the async query to complete
- m_queryCompletionEvent.acquire();
- // Compare the results
- CompareNormalData(queryPositions, baselineResultNormals, baselineExistsFlags,
- comparisonResultPositions, comparisonResultNormals, comparisonExistsFlags);
- }
- DestroyTestTerrainSystem();
- }
- TEST_F(TerrainBulkQueryTest, ProcessNormalsFromRegionAndProcessNormalsFromListAsyncProduceSameResults)
- {
- CreateTestTerrainSystem(TerrainWorldBounds, TerrainQueryResolution, TerrainNumSurfaces);
- for (auto sampler :
- { AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR, AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP,
- AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT })
- {
- // Gather all our initial results from calling Process*FromRegion
- AZStd::vector<AZ::Vector3> queryPositions;
- AZStd::vector<AZ::Vector3> baselineResultNormals;
- AZStd::vector<bool> baselineExistsFlags;
- GenerateBaselineNormalData(QueryBounds, QueryStepSize, sampler, queryPositions, baselineResultNormals, baselineExistsFlags);
- ASSERT_EQ(queryPositions.size(), ExpectedResultCount);
- // Gather results from Process*FromListAsync
- AZStd::vector<AZ::Vector3> comparisonResultPositions;
- AZStd::vector<AZ::Vector3> comparisonResultNormals;
- AZStd::vector<bool> comparisonExistsFlags;
- AZStd::mutex outputMutex;
- auto listPositionCallback = [&comparisonResultPositions, &comparisonResultNormals, &comparisonExistsFlags, &outputMutex](
- const AzFramework::SurfaceData::SurfacePoint& surfacePoint, bool terrainExists)
- {
- // Make sure only one thread can add its result at a time.
- AZStd::scoped_lock lock(outputMutex);
- comparisonResultPositions.emplace_back(surfacePoint.m_position);
- comparisonResultNormals.emplace_back(surfacePoint.m_normal);
- comparisonExistsFlags.emplace_back(terrainExists);
- };
- auto params = CreateTestAsyncParams();
- AZStd::shared_ptr<AzFramework::Terrain::TerrainJobContext> jobContext;
- AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult(
- jobContext, &AzFramework::Terrain::TerrainDataRequests::QueryListAsync, queryPositions,
- AzFramework::Terrain::TerrainDataRequests::TerrainDataMask::Normals, listPositionCallback,
- sampler, params);
- // Wait for the async query to complete
- m_queryCompletionEvent.acquire();
- // Compare the results
- CompareNormalData(queryPositions, baselineResultNormals, baselineExistsFlags,
- comparisonResultPositions, comparisonResultNormals, comparisonExistsFlags);
- }
- DestroyTestTerrainSystem();
- }
- // -----------------------------------------------------------------------------
- // Compare Surface Weight Query APIs
- TEST_F(TerrainBulkQueryTest, ProcessSurfaceWeightsFromRegionAndProcessSurfaceWeightsFromListProduceSameResults)
- {
- CreateTestTerrainSystem(TerrainWorldBounds, TerrainQueryResolution, TerrainNumSurfaces);
- for (auto sampler :
- { AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR, AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP,
- AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT })
- {
- // Gather all our initial results from calling Process*FromRegion
- AZStd::vector<AZ::Vector3> queryPositions;
- AZStd::vector<AzFramework::SurfaceData::SurfaceTagWeightList> baselineResultWeights;
- GenerateBaselineSurfaceWeightData(QueryBounds, QueryStepSize, sampler, queryPositions, baselineResultWeights);
- ASSERT_EQ(queryPositions.size(), ExpectedResultCount);
- // Gather results from Process*FromList
- AZStd::vector<AZ::Vector3> comparisonResultPositions;
- AZStd::vector<AzFramework::SurfaceData::SurfaceTagWeightList> comparisonResultWeights;
- auto listWeightsCallback = [&comparisonResultPositions, &comparisonResultWeights](
- const AzFramework::SurfaceData::SurfacePoint& surfacePoint, bool terrainExists)
- {
- comparisonResultPositions.emplace_back(surfacePoint.m_position);
- comparisonResultWeights.emplace_back(surfacePoint.m_surfaceTags);
- EXPECT_TRUE(terrainExists);
- };
- AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
- &AzFramework::Terrain::TerrainDataRequests::QueryList, queryPositions,
- AzFramework::Terrain::TerrainDataRequests::TerrainDataMask::SurfaceData, listWeightsCallback, sampler);
- // Compare the results
- CompareSurfaceWeightData(queryPositions, baselineResultWeights, comparisonResultPositions, comparisonResultWeights);
- }
- DestroyTestTerrainSystem();
- }
- TEST_F(TerrainBulkQueryTest, ProcessSurfaceWeightsFromRegionAndGetSurfaceWeightsProduceSameResults)
- {
- CreateTestTerrainSystem(TerrainWorldBounds, TerrainQueryResolution, TerrainNumSurfaces);
- for (auto sampler :
- { AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR, AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP,
- AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT })
- {
- // Gather all our initial results from calling Process*FromRegion
- AZStd::vector<AZ::Vector3> queryPositions;
- AZStd::vector<AzFramework::SurfaceData::SurfaceTagWeightList> baselineResultWeights;
- GenerateBaselineSurfaceWeightData(QueryBounds, QueryStepSize, sampler, queryPositions, baselineResultWeights);
- ASSERT_EQ(queryPositions.size(), ExpectedResultCount);
- // Gather results from Get*
- AZStd::vector<AzFramework::SurfaceData::SurfaceTagWeightList> comparisonResultWeights;
- AzFramework::SurfaceData::SurfaceTagWeightList terrainWeights;
- for (auto& position : queryPositions)
- {
- bool terrainExists = false;
- AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
- &AzFramework::Terrain::TerrainDataRequests::GetSurfaceWeights, position, terrainWeights, sampler, &terrainExists);
- comparisonResultWeights.emplace_back(terrainWeights);
- EXPECT_TRUE(terrainExists);
- }
- // Compare the results
- CompareSurfaceWeightData(queryPositions, baselineResultWeights, queryPositions, comparisonResultWeights);
- }
- DestroyTestTerrainSystem();
- }
- TEST_F(TerrainBulkQueryTest, ProcessSurfaceWeightsFromRegionAndProcessSurfaceWeightsFromRegionAsyncProduceSameResults)
- {
- CreateTestTerrainSystem(TerrainWorldBounds, TerrainQueryResolution, TerrainNumSurfaces);
- for (auto sampler :
- { AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR, AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP,
- AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT })
- {
- // Gather all our initial results from calling Process*FromRegion
- AZStd::vector<AZ::Vector3> queryPositions;
- AZStd::vector<AzFramework::SurfaceData::SurfaceTagWeightList> baselineResultWeights;
- GenerateBaselineSurfaceWeightData(QueryBounds, QueryStepSize, sampler, queryPositions, baselineResultWeights);
- ASSERT_EQ(queryPositions.size(), ExpectedResultCount);
- // Gather results from Process*FromRegionAsync
- AZStd::vector<AZ::Vector3> comparisonResultPositions;
- AZStd::vector<AzFramework::SurfaceData::SurfaceTagWeightList> comparisonResultWeights;
- AZStd::mutex outputMutex;
- auto perPositionCallback = [&comparisonResultPositions, &comparisonResultWeights, &outputMutex](
- [[maybe_unused]] size_t xIndex, [[maybe_unused]] size_t yIndex,
- const AzFramework::SurfaceData::SurfacePoint& surfacePoint, bool terrainExists)
- {
- // Make sure only one thread can add its result at a time.
- AZStd::scoped_lock lock(outputMutex);
- comparisonResultPositions.emplace_back(surfacePoint.m_position);
- comparisonResultWeights.emplace_back(surfacePoint.m_surfaceTags);
- EXPECT_TRUE(terrainExists);
- };
- auto params = CreateTestAsyncParams();
- AZStd::shared_ptr<AzFramework::Terrain::TerrainJobContext> jobContext;
- AzFramework::Terrain::TerrainQueryRegion queryRegion =
- AzFramework::Terrain::TerrainQueryRegion::CreateFromAabbAndStepSize(QueryBounds, QueryStepSize);
- AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult(
- jobContext, &AzFramework::Terrain::TerrainDataRequests::QueryRegionAsync, queryRegion,
- AzFramework::Terrain::TerrainDataRequests::TerrainDataMask::SurfaceData, perPositionCallback, sampler, params);
- // Wait for the async query to complete
- m_queryCompletionEvent.acquire();
- // Compare the results
- CompareSurfaceWeightData(queryPositions, baselineResultWeights, comparisonResultPositions, comparisonResultWeights);
- }
- DestroyTestTerrainSystem();
- }
- TEST_F(TerrainBulkQueryTest, ProcessSurfaceWeightsFromRegionAndProcessSurfaceWeightsFromListAsyncProduceSameResults)
- {
- CreateTestTerrainSystem(TerrainWorldBounds, TerrainQueryResolution, TerrainNumSurfaces);
- for (auto sampler :
- { AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR, AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP,
- AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT })
- {
- // Gather all our initial results from calling Process*FromRegion
- AZStd::vector<AZ::Vector3> queryPositions;
- AZStd::vector<AzFramework::SurfaceData::SurfaceTagWeightList> baselineResultWeights;
- GenerateBaselineSurfaceWeightData(QueryBounds, QueryStepSize, sampler, queryPositions, baselineResultWeights);
- ASSERT_EQ(queryPositions.size(), ExpectedResultCount);
- // Gather results from Process*FromListAsync
- AZStd::vector<AZ::Vector3> comparisonResultPositions;
- AZStd::vector<AzFramework::SurfaceData::SurfaceTagWeightList> comparisonResultWeights;
- AZStd::mutex outputMutex;
- auto listPositionCallback = [&comparisonResultPositions, &comparisonResultWeights, &outputMutex](
- const AzFramework::SurfaceData::SurfacePoint& surfacePoint, bool terrainExists)
- {
- // Make sure only one thread can add its result at a time.
- AZStd::scoped_lock lock(outputMutex);
- comparisonResultPositions.emplace_back(surfacePoint.m_position);
- comparisonResultWeights.emplace_back(surfacePoint.m_surfaceTags);
- EXPECT_TRUE(terrainExists);
- };
- auto params = CreateTestAsyncParams();
- AZStd::shared_ptr<AzFramework::Terrain::TerrainJobContext> jobContext;
- AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult(
- jobContext, &AzFramework::Terrain::TerrainDataRequests::QueryListAsync, queryPositions,
- AzFramework::Terrain::TerrainDataRequests::TerrainDataMask::SurfaceData, listPositionCallback, sampler, params);
- // Wait for the async query to complete
- m_queryCompletionEvent.acquire();
- // Compare the results
- CompareSurfaceWeightData(queryPositions, baselineResultWeights, comparisonResultPositions, comparisonResultWeights);
- }
- DestroyTestTerrainSystem();
- }
- // -----------------------------------------------------------------------------
- // Compare Surface Point Query APIs
- TEST_F(TerrainBulkQueryTest, ProcessSurfacePointsFromRegionAndProcessSurfacePointsFromListProduceSameResults)
- {
- CreateTestTerrainSystem(TerrainWorldBounds, TerrainQueryResolution, TerrainNumSurfaces);
- for (auto sampler :
- { AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR, AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP,
- AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT })
- {
- // Gather all our initial results from calling Process*FromRegion
- AZStd::vector<AZ::Vector3> queryPositions;
- AZStd::vector<AzFramework::SurfaceData::SurfacePoint> baselineResultPoints;
- AZStd::vector<bool> baselineExistsFlags;
- GenerateBaselineSurfacePointData(
- QueryBounds, QueryStepSize, sampler, queryPositions, baselineResultPoints, baselineExistsFlags);
- ASSERT_EQ(queryPositions.size(), ExpectedResultCount);
- // Gather results from Process*FromList
- AZStd::vector<AzFramework::SurfaceData::SurfacePoint> comparisonResultPoints;
- AZStd::vector<bool> comparisonExistsFlags;
- auto listPositionCallback = [&comparisonResultPoints, &comparisonExistsFlags](
- const AzFramework::SurfaceData::SurfacePoint& surfacePoint, bool terrainExists)
- {
- comparisonResultPoints.emplace_back(surfacePoint);
- comparisonExistsFlags.emplace_back(terrainExists);
- };
- AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
- &AzFramework::Terrain::TerrainDataRequests::QueryList, queryPositions,
- AzFramework::Terrain::TerrainDataRequests::TerrainDataMask::All, listPositionCallback, sampler);
- // Compare the results
- CompareSurfacePointData(baselineResultPoints, baselineExistsFlags, comparisonResultPoints, comparisonExistsFlags);
- }
- DestroyTestTerrainSystem();
- }
- TEST_F(TerrainBulkQueryTest, ProcessSurfacePointsFromRegionAndGetSurfacePointProduceSameResults)
- {
- CreateTestTerrainSystem(TerrainWorldBounds, TerrainQueryResolution, TerrainNumSurfaces);
- for (auto sampler :
- { AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR, AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP,
- AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT })
- {
- // Gather all our initial results from calling Process*FromRegion
- AZStd::vector<AZ::Vector3> queryPositions;
- AZStd::vector<AzFramework::SurfaceData::SurfacePoint> baselineResultPoints;
- AZStd::vector<bool> baselineExistsFlags;
- GenerateBaselineSurfacePointData(
- QueryBounds, QueryStepSize, sampler, queryPositions, baselineResultPoints, baselineExistsFlags);
- ASSERT_EQ(queryPositions.size(), ExpectedResultCount);
- // Gather results from Get*
- AZStd::vector<AzFramework::SurfaceData::SurfacePoint> comparisonResultPoints;
- AZStd::vector<bool> comparisonExistsFlags;
- AzFramework::SurfaceData::SurfacePoint surfacePoint;
- for (auto& position : queryPositions)
- {
- bool terrainExists = false;
- AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
- &AzFramework::Terrain::TerrainDataRequests::GetSurfacePoint, position, surfacePoint, sampler, &terrainExists);
- comparisonResultPoints.emplace_back(surfacePoint);
- comparisonExistsFlags.emplace_back(terrainExists);
- }
- // Compare the results
- CompareSurfacePointData(baselineResultPoints, baselineExistsFlags, comparisonResultPoints, comparisonExistsFlags);
- }
- DestroyTestTerrainSystem();
- }
- TEST_F(TerrainBulkQueryTest, ProcessSurfacePointsFromRegionAndProcessSurfacePointsFromRegionAsyncProduceSameResults)
- {
- CreateTestTerrainSystem(TerrainWorldBounds, TerrainQueryResolution, TerrainNumSurfaces);
- for (auto sampler :
- { AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR, AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP,
- AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT })
- {
- // Gather all our initial results from calling Process*FromRegion
- AZStd::vector<AZ::Vector3> queryPositions;
- AZStd::vector<AzFramework::SurfaceData::SurfacePoint> baselineResultPoints;
- AZStd::vector<bool> baselineExistsFlags;
- GenerateBaselineSurfacePointData(
- QueryBounds, QueryStepSize, sampler, queryPositions, baselineResultPoints, baselineExistsFlags);
- ASSERT_EQ(queryPositions.size(), ExpectedResultCount);
- // Gather results from Process*FromRegionAsync
- AZStd::vector<AzFramework::SurfaceData::SurfacePoint> comparisonResultPoints;
- AZStd::vector<bool> comparisonExistsFlags;
- AZStd::mutex outputMutex;
- auto regionPositionCallback = [&comparisonResultPoints, &comparisonExistsFlags, &outputMutex](
- [[maybe_unused]] size_t xIndex, [[maybe_unused]] size_t yIndex,
- const AzFramework::SurfaceData::SurfacePoint& surfacePoint, bool terrainExists)
- {
- // Make sure only one thread can add its result at a time.
- AZStd::scoped_lock lock(outputMutex);
- comparisonResultPoints.emplace_back(surfacePoint);
- comparisonExistsFlags.emplace_back(terrainExists);
- };
- auto params = CreateTestAsyncParams();
- AZStd::shared_ptr<AzFramework::Terrain::TerrainJobContext> jobContext;
- AzFramework::Terrain::TerrainQueryRegion queryRegion =
- AzFramework::Terrain::TerrainQueryRegion::CreateFromAabbAndStepSize(QueryBounds, QueryStepSize);
- AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult(
- jobContext, &AzFramework::Terrain::TerrainDataRequests::QueryRegionAsync, queryRegion,
- AzFramework::Terrain::TerrainDataRequests::TerrainDataMask::All, regionPositionCallback, sampler, params);
- // Wait for the async query to complete
- m_queryCompletionEvent.acquire();
- // Compare the results
- CompareSurfacePointData(baselineResultPoints, baselineExistsFlags, comparisonResultPoints, comparisonExistsFlags);
- }
- DestroyTestTerrainSystem();
- }
- TEST_F(TerrainBulkQueryTest, ProcessSurfacePointsFromRegionAndProcessSurfacePointsFromListAsyncProduceSameResults)
- {
- CreateTestTerrainSystem(TerrainWorldBounds, TerrainQueryResolution, TerrainNumSurfaces);
- for (auto sampler :
- { AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR, AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP,
- AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT })
- {
- // Gather all our initial results from calling Process*FromRegion
- AZStd::vector<AZ::Vector3> queryPositions;
- AZStd::vector<AzFramework::SurfaceData::SurfacePoint> baselineResultPoints;
- AZStd::vector<bool> baselineExistsFlags;
- GenerateBaselineSurfacePointData(
- QueryBounds, QueryStepSize, sampler, queryPositions, baselineResultPoints, baselineExistsFlags);
- ASSERT_EQ(queryPositions.size(), ExpectedResultCount);
- // Gather results from Process*FromListAsync
- AZStd::vector<AzFramework::SurfaceData::SurfacePoint> comparisonResultPoints;
- AZStd::vector<bool> comparisonExistsFlags;
- AZStd::mutex outputMutex;
- auto listPositionCallback = [&comparisonResultPoints, &comparisonExistsFlags, &outputMutex](
- const AzFramework::SurfaceData::SurfacePoint& surfacePoint, bool terrainExists)
- {
- // Make sure only one thread can add its result at a time.
- AZStd::scoped_lock lock(outputMutex);
- comparisonResultPoints.emplace_back(surfacePoint);
- comparisonExistsFlags.emplace_back(terrainExists);
- };
- auto params = CreateTestAsyncParams();
- AZStd::shared_ptr<AzFramework::Terrain::TerrainJobContext> jobContext;
- AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult(
- jobContext, &AzFramework::Terrain::TerrainDataRequests::QueryListAsync, queryPositions,
- AzFramework::Terrain::TerrainDataRequests::TerrainDataMask::All, listPositionCallback, sampler, params);
- // Wait for the async query to complete
- m_queryCompletionEvent.acquire();
- // Compare the results
- CompareSurfacePointData(baselineResultPoints, baselineExistsFlags, comparisonResultPoints, comparisonExistsFlags);
- }
- DestroyTestTerrainSystem();
- }
- } // namespace UnitTest
|