diff --git a/Code/Framework/AzFramework/AzFramework/Terrain/TerrainDataRequestBus.h b/Code/Framework/AzFramework/AzFramework/Terrain/TerrainDataRequestBus.h index 0d16bf3460..9379485646 100644 --- a/Code/Framework/AzFramework/AzFramework/Terrain/TerrainDataRequestBus.h +++ b/Code/Framework/AzFramework/AzFramework/Terrain/TerrainDataRequestBus.h @@ -161,6 +161,10 @@ namespace AzFramework SurfacePointListFillCallback perPositionCallback, Sampler sampleFilter = Sampler::DEFAULT) const = 0; + //! Returns the number of samples for a given region and step size. + virtual AZStd::pair GetNumSamplesFromRegion(const AZ::Aabb& inRegion, + const AZ::Vector2& stepSize) const = 0; + //! Given a region(aabb) and a step size, call the provided callback function with surface data corresponding to the //! coordinates in the region. virtual void ProcessHeightsFromRegion(const AZ::Aabb& inRegion, diff --git a/Code/Framework/AzFramework/Tests/Mocks/Terrain/MockTerrainDataRequestBus.h b/Code/Framework/AzFramework/Tests/Mocks/Terrain/MockTerrainDataRequestBus.h index f3a6cc07b3..52ac28ef63 100644 --- a/Code/Framework/AzFramework/Tests/Mocks/Terrain/MockTerrainDataRequestBus.h +++ b/Code/Framework/AzFramework/Tests/Mocks/Terrain/MockTerrainDataRequestBus.h @@ -92,6 +92,8 @@ namespace UnitTest ProcessSurfaceWeightsFromListOfVector2, void(const AZStd::span&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler)); MOCK_CONST_METHOD3( ProcessSurfacePointsFromListOfVector2, void(const AZStd::span&, AzFramework::Terrain::SurfacePointListFillCallback, Sampler)); + MOCK_CONST_METHOD2( + GetNumSamplesFromRegion, AZStd::pair(const AZ::Aabb&, const AZ::Vector2&)); MOCK_CONST_METHOD4( ProcessHeightsFromRegion, void(const AZ::Aabb&, const AZ::Vector2&, AzFramework::Terrain::SurfacePointRegionFillCallback, Sampler)); MOCK_CONST_METHOD4( diff --git a/Gems/Terrain/Code/Source/TerrainRenderer/TerrainFeatureProcessor.cpp b/Gems/Terrain/Code/Source/TerrainRenderer/TerrainFeatureProcessor.cpp index ebc8a16fcb..4232a37264 100644 --- a/Gems/Terrain/Code/Source/TerrainRenderer/TerrainFeatureProcessor.cpp +++ b/Gems/Terrain/Code/Source/TerrainRenderer/TerrainFeatureProcessor.cpp @@ -208,12 +208,21 @@ namespace Terrain } int32_t xStart = aznumeric_cast(AZStd::ceilf(m_dirtyRegion.GetMin().GetX() / m_sampleSpacing)); - int32_t xEnd = aznumeric_cast(AZStd::floorf(m_dirtyRegion.GetMax().GetX() / m_sampleSpacing)) + 1; int32_t yStart = aznumeric_cast(AZStd::ceilf(m_dirtyRegion.GetMin().GetY() / m_sampleSpacing)); - int32_t yEnd = aznumeric_cast(AZStd::floorf(m_dirtyRegion.GetMax().GetY() / m_sampleSpacing)) + 1; - uint32_t updateWidth = xEnd - xStart; - uint32_t updateHeight = yEnd - yStart; + AZ::Vector2 stepSize(m_sampleSpacing); + AZ::Vector3 maxBound( + m_dirtyRegion.GetMax().GetX() + m_sampleSpacing, m_dirtyRegion.GetMax().GetY() + m_sampleSpacing, 0.0f); + AZ::Aabb region; + region.Set(m_dirtyRegion.GetMin(), maxBound); + + AZStd::pair numSamples; + AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult( + numSamples, &AzFramework::Terrain::TerrainDataRequests::GetNumSamplesFromRegion, + region, stepSize); + + uint32_t updateWidth = numSamples.first; + uint32_t updateHeight = numSamples.second; AZStd::vector pixels; pixels.reserve(updateWidth * updateHeight); { @@ -238,14 +247,9 @@ namespace Terrain pixels.push_back(uint16Height); }; - AZ::Vector2 stepSize(m_sampleSpacing); - AZ::Vector3 maxBound( - m_dirtyRegion.GetMax().GetX() + m_sampleSpacing, m_dirtyRegion.GetMax().GetY() + m_sampleSpacing, 0.0f); - AZ::Aabb region; - region.Set(m_dirtyRegion.GetMin(), maxBound); AzFramework::Terrain::TerrainDataRequestBus::Broadcast( &AzFramework::Terrain::TerrainDataRequests::ProcessHeightsFromRegion, - region, stepSize, perPositionCallback,AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT); + region, stepSize, perPositionCallback, AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT); } if (m_heightmapImage) diff --git a/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.cpp b/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.cpp index 2ecd13b5ad..4dfa03ed53 100644 --- a/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.cpp +++ b/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.cpp @@ -690,6 +690,16 @@ void TerrainSystem::ProcessSurfacePointsFromListOfVector2( } } +AZStd::pair TerrainSystem::GetNumSamplesFromRegion( + const AZ::Aabb& inRegion, + const AZ::Vector2& stepSize) const +{ + const size_t numSamplesX = aznumeric_cast(ceil(inRegion.GetExtents().GetX() / stepSize.GetX())); + const size_t numSamplesY = aznumeric_cast(ceil(inRegion.GetExtents().GetY() / stepSize.GetY())); + + return AZStd::make_pair(numSamplesX, numSamplesY); +} + void TerrainSystem::ProcessHeightsFromRegion( const AZ::Aabb& inRegion, const AZ::Vector2& stepSize, diff --git a/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.h b/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.h index 7c6e0cd91e..2296d48843 100644 --- a/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.h +++ b/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.h @@ -163,6 +163,10 @@ namespace Terrain AzFramework::Terrain::SurfacePointListFillCallback perPositionCallback, Sampler sampleFilter = Sampler::DEFAULT) const override; + //! Returns the number of samples for a given region and step size. + virtual AZStd::pair GetNumSamplesFromRegion(const AZ::Aabb& inRegion, + const AZ::Vector2& stepSize) const override; + //! Given a region(aabb) and a step size, call the provided callback function with surface data corresponding to the //! coordinates in the region. virtual void ProcessHeightsFromRegion(const AZ::Aabb& inRegion,