diff --git a/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.cpp b/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.cpp index c51728a5c3..4a8b4680b3 100644 --- a/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.cpp +++ b/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.cpp @@ -284,21 +284,14 @@ namespace Terrain heights.clear(); heights.reserve(gridWidth * gridHeight); - for (int32_t row = 0; row < gridHeight; row++) + auto perPositionHeightCallback = [&heights, worldCenterZ] + ([[maybe_unused]] size_t xIndex, [[maybe_unused]] size_t yIndex, const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists) { - const float y = row * gridResolution.GetY() + worldSize.GetMin().GetY(); - for (int32_t col = 0; col < gridWidth; col++) - { - const float x = col * gridResolution.GetX() + worldSize.GetMin().GetX(); - float height = 0.0f; + heights.emplace_back(surfacePoint.m_position.GetZ() - worldCenterZ); + }; - AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult( - height, &AzFramework::Terrain::TerrainDataRequests::GetHeightFromFloats, x, y, - AzFramework::Terrain::TerrainDataRequests::Sampler::DEFAULT, nullptr); - - heights.emplace_back(height - worldCenterZ); - } - } + AzFramework::Terrain::TerrainDataRequestBus::Broadcast(&AzFramework::Terrain::TerrainDataRequests::ProcessHeightsFromRegion, + worldSize, gridResolution, perPositionHeightCallback, AzFramework::Terrain::TerrainDataRequests::Sampler::DEFAULT); } uint8_t TerrainPhysicsColliderComponent::GetMaterialIdIndex(const Physics::MaterialId& materialId, const AZStd::vector& materialList) const @@ -350,42 +343,37 @@ namespace Terrain AZStd::vector materialList = GetMaterialList(); - for (int32_t row = 0; row < gridHeight; row++) + auto perPositionCallback = [&heightMaterials, &materialList, this, worldCenterZ, worldHeightBoundsMin, worldHeightBoundsMax] + (size_t xIndex, size_t yIndex, const AzFramework::SurfaceData::SurfacePoint& surfacePoint, bool terrainExists) { - const float y = row * gridResolution.GetY() + worldSize.GetMin().GetY(); - for (int32_t col = 0; col < gridWidth; col++) + float height = surfacePoint.m_position.GetZ(); + + // Any heights that fall outside the range of our bounding box will get turned into holes. + if ((height < worldHeightBoundsMin) || (height > worldHeightBoundsMax)) { - const float x = col * gridResolution.GetX() + worldSize.GetMin().GetX(); - float height = 0.0f; - - bool terrainExists = true; - AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult( - height, &AzFramework::Terrain::TerrainDataRequests::GetHeightFromFloats, x, y, - AzFramework::Terrain::TerrainDataRequests::Sampler::DEFAULT, &terrainExists); - - // Any heights that fall outside the range of our bounding box will get turned into holes. - if ((height < worldHeightBoundsMin) || (height > worldHeightBoundsMax)) - { - height = worldHeightBoundsMin; - terrainExists = false; - } - - // Find the best surface tag at this point. - AzFramework::SurfaceData::SurfaceTagWeight surfaceWeight; - AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult( - surfaceWeight, &AzFramework::Terrain::TerrainDataRequests::GetMaxSurfaceWeightFromFloats, x, y, - AzFramework::Terrain::TerrainDataRequests::Sampler::DEFAULT, nullptr); - - Physics::HeightMaterialPoint point; - point.m_height = height - worldCenterZ; - point.m_quadMeshType = terrainExists ? Physics::QuadMeshType::SubdivideUpperLeftToBottomRight : Physics::QuadMeshType::Hole; - - Physics::MaterialId materialId = FindMaterialIdForSurfaceTag(surfaceWeight.m_surfaceType); - point.m_materialIndex = GetMaterialIdIndex(materialId, materialList); - - heightMaterials.emplace_back(point); + height = worldHeightBoundsMin; + terrainExists = false; } - } + + // Find the best surface tag at this point. + // We want the MaxSurfaceWeight. The ProcessSurfacePoints callback has surface weights sorted. + // So, we pick the value at the front of the list. + AzFramework::SurfaceData::SurfaceTagWeight surfaceWeight; + if (!surfacePoint.m_surfaceTags.empty()) + { + surfaceWeight = *surfacePoint.m_surfaceTags.begin(); + } + + Physics::HeightMaterialPoint point; + point.m_height = height - worldCenterZ; + point.m_quadMeshType = terrainExists ? Physics::QuadMeshType::SubdivideUpperLeftToBottomRight : Physics::QuadMeshType::Hole; + Physics::MaterialId materialId = FindMaterialIdForSurfaceTag(surfaceWeight.m_surfaceType); + point.m_materialIndex = GetMaterialIdIndex(materialId, materialList); + heightMaterials.emplace_back(point); + }; + + AzFramework::Terrain::TerrainDataRequestBus::Broadcast(&AzFramework::Terrain::TerrainDataRequests::ProcessSurfacePointsFromRegion, + worldSize, gridResolution, perPositionCallback, AzFramework::Terrain::TerrainDataRequests::Sampler::DEFAULT); } AZ::Vector2 TerrainPhysicsColliderComponent::GetHeightfieldGridSpacing() const diff --git a/Gems/Terrain/Code/Source/Components/TerrainWorldDebuggerComponent.cpp b/Gems/Terrain/Code/Source/Components/TerrainWorldDebuggerComponent.cpp index f3e0d59537..46be621307 100644 --- a/Gems/Terrain/Code/Source/Components/TerrainWorldDebuggerComponent.cpp +++ b/Gems/Terrain/Code/Source/Components/TerrainWorldDebuggerComponent.cpp @@ -354,44 +354,29 @@ namespace Terrain // For each terrain height value in the region, create the _| grid lines for that point and cache off the height value // for use with subsequent grid line calculations. auto ProcessHeightValue = [gridResolution, &previousHeight, &rowHeights, §or] - (uint32_t xIndex, uint32_t yIndex, const AZ::Vector3& position, [[maybe_unused]] bool terrainExists) + (uint32_t xIndex, uint32_t yIndex, const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists) { // Don't add any vertices for the first column or first row. These grid lines will be handled by an adjacent sector, if // there is one. if ((xIndex > 0) && (yIndex > 0)) { - float x = position.GetX() - gridResolution.GetX(); - float y = position.GetY() - gridResolution.GetY(); + float x = surfacePoint.m_position.GetX() - gridResolution.GetX(); + float y = surfacePoint.m_position.GetY() - gridResolution.GetY(); - sector.m_lineVertices.emplace_back(AZ::Vector3(x, position.GetY(), previousHeight)); - sector.m_lineVertices.emplace_back(position); + sector.m_lineVertices.emplace_back(AZ::Vector3(x, surfacePoint.m_position.GetY(), previousHeight)); + sector.m_lineVertices.emplace_back(surfacePoint.m_position); - sector.m_lineVertices.emplace_back(AZ::Vector3(position.GetX(), y, rowHeights[xIndex])); - sector.m_lineVertices.emplace_back(position); + sector.m_lineVertices.emplace_back(AZ::Vector3(surfacePoint.m_position.GetX(), y, rowHeights[xIndex])); + sector.m_lineVertices.emplace_back(surfacePoint.m_position); } // Save off the heights so that we can use them to draw subsequent columns and rows. - previousHeight = position.GetZ(); - rowHeights[xIndex] = position.GetZ(); + previousHeight = surfacePoint.m_position.GetZ(); + rowHeights[xIndex] = surfacePoint.m_position.GetZ(); }; - // This set of nested loops will get replaced with a call to ProcessHeightsFromRegion once the API exists. - for (size_t yIndex = 0; yIndex < numSamplesY; yIndex++) - { - float y = region.GetMin().GetY() + (gridResolution.GetY() * yIndex); - for (size_t xIndex = 0; xIndex < numSamplesX; xIndex++) - { - float x = region.GetMin().GetX() + (gridResolution.GetX() * xIndex); - - float height = worldMinZ; - bool terrainExists = false; - AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult( - height, &AzFramework::Terrain::TerrainDataRequests::GetHeightFromFloats, x, y, - AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT, &terrainExists); - ProcessHeightValue( - aznumeric_cast(xIndex), aznumeric_cast(yIndex), AZ::Vector3(x, y, height), terrainExists); - } - } + AzFramework::Terrain::TerrainDataRequestBus::Broadcast(&AzFramework::Terrain::TerrainDataRequests::ProcessHeightsFromRegion, + region, gridResolution, ProcessHeightValue, AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT); } void TerrainWorldDebuggerComponent::OnTerrainDataChanged(const AZ::Aabb& dirtyRegion, TerrainDataChangedMask dataChangedMask)