From 0c7dfce5a0d01684c508abe56db42c7eb3b6c8c8 Mon Sep 17 00:00:00 2001 From: Ken Pruiksma Date: Tue, 31 Aug 2021 19:05:03 -0500 Subject: [PATCH] First pass terrain cleanup (#3753) * First pass cleanup of some terrain components. Signed-off-by: Ken Pruiksma * Adding basic culling to terrain sectors Signed-off-by: Ken Pruiksma * Adding default value for m_transform Signed-off-by: Ken Pruiksma --- .../Components/TerrainWorldComponent.cpp | 6 +- .../TerrainWorldDebuggerComponent.cpp | 7 - .../TerrainFeatureProcessor.cpp | 204 ++++++++---------- .../TerrainRenderer/TerrainFeatureProcessor.h | 33 +-- .../Source/TerrainSystem/TerrainSystem.cpp | 32 +-- .../Code/Source/TerrainSystem/TerrainSystem.h | 7 +- .../Source/TerrainSystem/TerrainSystemBus.h | 6 +- 7 files changed, 122 insertions(+), 173 deletions(-) diff --git a/Gems/Terrain/Code/Source/Components/TerrainWorldComponent.cpp b/Gems/Terrain/Code/Source/Components/TerrainWorldComponent.cpp index e2af58e3eb..669a8f4b02 100644 --- a/Gems/Terrain/Code/Source/Components/TerrainWorldComponent.cpp +++ b/Gems/Terrain/Code/Source/Components/TerrainWorldComponent.cpp @@ -85,8 +85,10 @@ namespace Terrain void TerrainWorldComponent::Activate() { - TerrainSystemServiceRequestBus::Broadcast(&TerrainSystemServiceRequestBus::Events::SetWorldMin, m_configuration.m_worldMin); - TerrainSystemServiceRequestBus::Broadcast(&TerrainSystemServiceRequestBus::Events::SetWorldMax, m_configuration.m_worldMax); + TerrainSystemServiceRequestBus::Broadcast( + &TerrainSystemServiceRequestBus::Events::SetWorldBounds, + AZ::Aabb::CreateFromMinMax(m_configuration.m_worldMin, m_configuration.m_worldMax) + ); TerrainSystemServiceRequestBus::Broadcast( &TerrainSystemServiceRequestBus::Events::SetHeightQueryResolution, m_configuration.m_heightQueryResolution); diff --git a/Gems/Terrain/Code/Source/Components/TerrainWorldDebuggerComponent.cpp b/Gems/Terrain/Code/Source/Components/TerrainWorldDebuggerComponent.cpp index 1fea51ded4..d7504295c2 100644 --- a/Gems/Terrain/Code/Source/Components/TerrainWorldDebuggerComponent.cpp +++ b/Gems/Terrain/Code/Source/Components/TerrainWorldDebuggerComponent.cpp @@ -92,20 +92,13 @@ namespace Terrain { m_wireframeBounds = AZ::Aabb::CreateNull(); - TerrainSystemServiceRequestBus::Broadcast( - &TerrainSystemServiceRequestBus::Events::SetDebugWireframe, m_configuration.m_drawWireframe); - AzFramework::EntityDebugDisplayEventBus::Handler::BusConnect(GetEntityId()); AzFramework::BoundsRequestBus::Handler::BusConnect(GetEntityId()); AzFramework::Terrain::TerrainDataNotificationBus::Handler::BusConnect(); - } void TerrainWorldDebuggerComponent::Deactivate() { - TerrainSystemServiceRequestBus::Broadcast( - &TerrainSystemServiceRequestBus::Events::SetDebugWireframe, false); - AzFramework::Terrain::TerrainDataNotificationBus::Handler::BusDisconnect(); AzFramework::BoundsRequestBus::Handler::BusDisconnect(); AzFramework::EntityDebugDisplayEventBus::Handler::BusDisconnect(); diff --git a/Gems/Terrain/Code/Source/TerrainRenderer/TerrainFeatureProcessor.cpp b/Gems/Terrain/Code/Source/TerrainRenderer/TerrainFeatureProcessor.cpp index 812ed3f0da..2178151e3d 100644 --- a/Gems/Terrain/Code/Source/TerrainRenderer/TerrainFeatureProcessor.cpp +++ b/Gems/Terrain/Code/Source/TerrainRenderer/TerrainFeatureProcessor.cpp @@ -10,12 +10,14 @@ #include #include +#include #include #include #include #include +#include #include #include #include @@ -34,6 +36,7 @@ namespace Terrain namespace { const uint32_t DEFAULT_UploadBufferSize = 512 * 1024; // 512k + const char* TerrainFPName = "TerrainFeatureProcessor"; } namespace ShaderInputs @@ -59,7 +62,7 @@ namespace Terrain void TerrainFeatureProcessor::Activate() { - m_areaData.clear(); + m_areaData = {}; InitializeAtomStuff(); EnableSceneNotification(); @@ -69,43 +72,18 @@ namespace Terrain { m_rhiSystem = AZ::RHI::RHISystemInterface::Get(); - m_rhiSystem->GetDrawListTagRegistry()->AcquireTag(AZ::Name("Terrain")); - { // Load the shader - - const char* terrainShaderFilePath = "Shaders/Terrain/Terrain.azshader"; - - AZ::Data::AssetId shaderAssetId; - AZ::Data::AssetCatalogRequestBus::BroadcastResult( - shaderAssetId, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetIdByPath, - terrainShaderFilePath, azrtti_typeid(), false); - if (!shaderAssetId.IsValid()) - { - AZ_Error("Terrain", false, "Failed to get shader asset id with path %s", terrainShaderFilePath); - return; - } - - auto shaderAsset = AZ::Data::AssetManager::Instance().GetAsset(shaderAssetId, AZ::Data::AssetLoadBehavior::PreLoad); - shaderAsset.BlockUntilLoadComplete(); - - if (!shaderAsset.IsReady()) - { - AZ_Error("Terrain", false, "Failed to get shader asset with path %s", terrainShaderFilePath); - return; - } - - m_shader = AZ::RPI::Shader::FindOrCreate(shaderAsset); + constexpr const char* TerrainShaderFilePath = "Shaders/Terrain/Terrain.azshader"; + m_shader = AZ::RPI::LoadShader(TerrainShaderFilePath); if (!m_shader) { - AZ_Error("Terrain", false, "Failed to find or create a shader instance from shader asset '%s'", terrainShaderFilePath); + AZ_Error(TerrainFPName, false, "Failed to find or create a shader instance from shader asset '%s'", TerrainShaderFilePath); return; } // Create the data layout - m_pipelineStateDescriptor = AZ::RHI::PipelineStateDescriptorForDraw{}; - { AZ::RHI::InputStreamLayoutBuilder layoutBuilder; @@ -124,41 +102,41 @@ namespace Terrain m_perObjectSrgAsset = m_shader->FindShaderResourceGroupLayout(AZ::Name{"ObjectSrg"}); if (!m_perObjectSrgAsset) { - AZ_Error("Terrain", false, "Failed to get shader resource group asset"); + AZ_Error(TerrainFPName, false, "Failed to get shader resource group asset"); return; } else if (!m_perObjectSrgAsset->IsFinalized()) { - AZ_Error("Terrain", false, "Shader resource group asset is not loaded"); + AZ_Error(TerrainFPName, false, "Shader resource group asset is not loaded"); return; } const AZ::RHI::ShaderResourceGroupLayout* shaderResourceGroupLayout = &(*m_perObjectSrgAsset); m_heightmapImageIndex = shaderResourceGroupLayout->FindShaderInputImageIndex(AZ::Name(ShaderInputs::HeightmapImage)); - AZ_Error("Terrain", m_heightmapImageIndex.IsValid(), "Failed to find shader input image %s.", ShaderInputs::HeightmapImage); + AZ_Error(TerrainFPName, m_heightmapImageIndex.IsValid(), "Failed to find shader input image %s.", ShaderInputs::HeightmapImage); m_modelToWorldIndex = shaderResourceGroupLayout->FindShaderInputConstantIndex(AZ::Name(ShaderInputs::ModelToWorld)); - AZ_Error("Terrain", m_modelToWorldIndex.IsValid(), "Failed to find shader input constant %s.", ShaderInputs::ModelToWorld); + AZ_Error(TerrainFPName, m_modelToWorldIndex.IsValid(), "Failed to find shader input constant %s.", ShaderInputs::ModelToWorld); m_heightScaleIndex = shaderResourceGroupLayout->FindShaderInputConstantIndex(AZ::Name(ShaderInputs::HeightScale)); - AZ_Error("Terrain", m_heightScaleIndex.IsValid(), "Failed to find shader input constant %s.", ShaderInputs::HeightScale); + AZ_Error(TerrainFPName, m_heightScaleIndex.IsValid(), "Failed to find shader input constant %s.", ShaderInputs::HeightScale); m_uvMinIndex = shaderResourceGroupLayout->FindShaderInputConstantIndex(AZ::Name(ShaderInputs::UvMin)); - AZ_Error("Terrain", m_uvMinIndex.IsValid(), "Failed to find shader input constant %s.", ShaderInputs::UvMin); + AZ_Error(TerrainFPName, m_uvMinIndex.IsValid(), "Failed to find shader input constant %s.", ShaderInputs::UvMin); m_uvMaxIndex = shaderResourceGroupLayout->FindShaderInputConstantIndex(AZ::Name(ShaderInputs::UvMax)); - AZ_Error("Terrain", m_uvMaxIndex.IsValid(), "Failed to find shader input constant %s.", ShaderInputs::UvMax); + AZ_Error(TerrainFPName, m_uvMaxIndex.IsValid(), "Failed to find shader input constant %s.", ShaderInputs::UvMax); m_uvStepIndex = shaderResourceGroupLayout->FindShaderInputConstantIndex(AZ::Name(ShaderInputs::UvStep)); - AZ_Error("Terrain", m_uvStepIndex.IsValid(), "Failed to find shader input constant %s.", ShaderInputs::UvStep); + AZ_Error(TerrainFPName, m_uvStepIndex.IsValid(), "Failed to find shader input constant %s.", ShaderInputs::UvStep); // If this fails to run now, it's ok, we'll initialize it in OnRenderPipelineAdded later. bool success = GetParentScene()->ConfigurePipelineState(m_shader->GetDrawListTag(), m_pipelineStateDescriptor); if (success) { m_pipelineState = m_shader->AcquirePipelineState(m_pipelineStateDescriptor); - AZ_Assert(m_pipelineState, "Failed to acquire default pipeline state for shader '%s'", terrainShaderFilePath); + AZ_Assert(m_pipelineState, "Failed to acquire default pipeline state for shader '%s'", TerrainShaderFilePath); } } @@ -172,7 +150,7 @@ namespace Terrain if (resultCode != AZ::RHI::ResultCode::Success) { - AZ_Error("Terrain", false, "Failed to create host buffer pool from RPI"); + AZ_Error(TerrainFPName, false, "Failed to create host buffer pool from RPI"); return; } @@ -180,7 +158,7 @@ namespace Terrain if (!InitializeRenderBuffers()) { - AZ_Error("Terrain", false, "Failed to create Terrain render buffers!"); + AZ_Error(TerrainFPName, false, "Failed to create Terrain render buffers!"); return; } } @@ -210,7 +188,7 @@ namespace Terrain DisableSceneNotification(); DestroyRenderBuffers(); - m_areaData.clear(); + m_areaData = {}; if (m_hostPool) { @@ -226,7 +204,6 @@ namespace Terrain } void TerrainFeatureProcessor::UpdateTerrainData( - AZ::EntityId areaId, const AZ::Transform& transform, const AZ::Aabb& worldBounds, [[maybe_unused]] float sampleSpacing, @@ -234,37 +211,33 @@ namespace Terrain { if (!worldBounds.IsValid()) { - m_areaData.erase(areaId); return; } - TerrainAreaData areaData; - - areaData.m_transform = transform; - areaData.m_heightScale = worldBounds.GetZExtent(); - areaData.m_terrainBounds = worldBounds; - areaData.m_heightmapImageHeight = height; - areaData.m_heightmapImageWidth = width; + m_areaData.m_transform = transform; + m_areaData.m_heightScale = worldBounds.GetZExtent(); + m_areaData.m_terrainBounds = worldBounds; + m_areaData.m_heightmapImageHeight = height; + m_areaData.m_heightmapImageWidth = width; // Create heightmap image data { - areaData.m_propertiesDirty = true; + m_areaData.m_propertiesDirty = true; AZ::RHI::Size imageSize; imageSize.m_width = width; imageSize.m_height = height; AZ::Data::Instance streamingImagePool = AZ::RPI::ImageSystemInterface::Get()->GetSystemStreamingPool(); - areaData.m_heightmapImage = AZ::RPI::StreamingImage::CreateFromCpuData(*streamingImagePool, + m_areaData.m_heightmapImage = AZ::RPI::StreamingImage::CreateFromCpuData(*streamingImagePool, AZ::RHI::ImageDimension::Image2D, imageSize, AZ::RHI::Format::R32_FLOAT, (uint8_t*)heightData.data(), heightData.size() * sizeof(float)); - AZ_Error("Terrain", areaData.m_heightmapImage, "Failed to initialize the heightmap image!"); + AZ_Error(TerrainFPName, m_areaData.m_heightmapImage, "Failed to initialize the heightmap image!"); } - m_areaData.insert_or_assign(areaId, areaData); } void TerrainFeatureProcessor::ProcessSurfaces(const FeatureProcessor::RenderPacket& process) @@ -276,31 +249,30 @@ namespace Terrain return; } - if (m_areaData.empty()) + if (!m_areaData.m_terrainBounds.IsValid()) { return; } - - m_drawPackets.clear(); - m_processSrgs.clear(); - - AZ::RHI::DrawPacketBuilder drawPacketBuilder; - - uint32_t numIndices = static_cast(m_gridIndices.size()); - - AZ::RHI::DrawIndexed drawIndexed; - drawIndexed.m_indexCount = numIndices; - drawIndexed.m_indexOffset = 0; - drawIndexed.m_vertexOffset = 0; - - for (auto& [areaId, areaData] : m_areaData) + + if (m_areaData.m_propertiesDirty) { + m_sectorData.clear(); + + AZ::RHI::DrawPacketBuilder drawPacketBuilder; + + uint32_t numIndices = static_cast(m_gridIndices.size()); + + AZ::RHI::DrawIndexed drawIndexed; + drawIndexed.m_indexCount = numIndices; + drawIndexed.m_indexOffset = 0; + drawIndexed.m_vertexOffset = 0; + float xFirstPatchStart = - areaData.m_terrainBounds.GetMin().GetX() - fmod(areaData.m_terrainBounds.GetMin().GetX(), m_gridMeters); - float xLastPatchStart = areaData.m_terrainBounds.GetMax().GetX() - fmod(areaData.m_terrainBounds.GetMax().GetX(), m_gridMeters); + m_areaData.m_terrainBounds.GetMin().GetX() - fmod(m_areaData.m_terrainBounds.GetMin().GetX(), m_gridMeters); + float xLastPatchStart = m_areaData.m_terrainBounds.GetMax().GetX() - fmod(m_areaData.m_terrainBounds.GetMax().GetX(), m_gridMeters); float yFirstPatchStart = - areaData.m_terrainBounds.GetMin().GetY() - fmod(areaData.m_terrainBounds.GetMin().GetY(), m_gridMeters); - float yLastPatchStart = areaData.m_terrainBounds.GetMax().GetY() - fmod(areaData.m_terrainBounds.GetMax().GetY(), m_gridMeters); + m_areaData.m_terrainBounds.GetMin().GetY() - fmod(m_areaData.m_terrainBounds.GetMin().GetY(), m_gridMeters); + float yLastPatchStart = m_areaData.m_terrainBounds.GetMax().GetY() - fmod(m_areaData.m_terrainBounds.GetMax().GetY(), m_gridMeters); for (float yPatch = yFirstPatchStart; yPatch <= yLastPatchStart; yPatch += m_gridMeters) { @@ -310,62 +282,70 @@ namespace Terrain drawPacketBuilder.SetDrawArguments(drawIndexed); drawPacketBuilder.SetIndexBufferView(m_indexBufferView); - auto m_resourceGroup = AZ::RPI::ShaderResourceGroup::Create(m_shader->GetAsset(), m_shader->GetSupervariantIndex(), AZ::Name("ObjectSrg")); + auto resourceGroup = AZ::RPI::ShaderResourceGroup::Create(m_shader->GetAsset(), m_shader->GetSupervariantIndex(), AZ::Name("ObjectSrg")); //auto m_resourceGroup = AZ::RPI::ShaderResourceGroup::Create(m_shader->GetAsset(), AZ::Name("ObjectSrg")); - if (!m_resourceGroup) + if (!resourceGroup) { - AZ_Error("Terrain", false, "Failed to create shader resource group"); + AZ_Error(TerrainFPName, false, "Failed to create shader resource group"); return; } float uvMin[2] = { 0.0f, 0.0f }; float uvMax[2] = { 1.0f, 1.0f }; - uvMin[0] = (float)((xPatch - areaData.m_terrainBounds.GetMin().GetX()) / areaData.m_terrainBounds.GetXExtent()); - uvMin[1] = (float)((yPatch - areaData.m_terrainBounds.GetMin().GetY()) / areaData.m_terrainBounds.GetYExtent()); + uvMin[0] = (float)((xPatch - m_areaData.m_terrainBounds.GetMin().GetX()) / m_areaData.m_terrainBounds.GetXExtent()); + uvMin[1] = (float)((yPatch - m_areaData.m_terrainBounds.GetMin().GetY()) / m_areaData.m_terrainBounds.GetYExtent()); uvMax[0] = - (float)(((xPatch + m_gridMeters) - areaData.m_terrainBounds.GetMin().GetX()) / areaData.m_terrainBounds.GetXExtent()); + (float)(((xPatch + m_gridMeters) - m_areaData.m_terrainBounds.GetMin().GetX()) / m_areaData.m_terrainBounds.GetXExtent()); uvMax[1] = - (float)(((yPatch + m_gridMeters) - areaData.m_terrainBounds.GetMin().GetY()) / areaData.m_terrainBounds.GetYExtent()); + (float)(((yPatch + m_gridMeters) - m_areaData.m_terrainBounds.GetMin().GetY()) / m_areaData.m_terrainBounds.GetYExtent()); float uvStep[2] = { - 1.0f / areaData.m_heightmapImageWidth, 1.0f / areaData.m_heightmapImageHeight, + 1.0f / m_areaData.m_heightmapImageWidth, 1.0f / m_areaData.m_heightmapImageHeight, }; - AZ::Transform transform = areaData.m_transform; - transform.SetTranslation(xPatch, yPatch, areaData.m_transform.GetTranslation().GetZ()); + AZ::Transform transform = m_areaData.m_transform; + transform.SetTranslation(xPatch, yPatch, m_areaData.m_transform.GetTranslation().GetZ()); AZ::Matrix3x4 matrix3x4 = AZ::Matrix3x4::CreateFromTransform(transform); - m_resourceGroup->SetImage(m_heightmapImageIndex, areaData.m_heightmapImage); - m_resourceGroup->SetConstant(m_modelToWorldIndex, matrix3x4); - m_resourceGroup->SetConstant(m_heightScaleIndex, areaData.m_heightScale); - m_resourceGroup->SetConstant(m_uvMinIndex, uvMin); - m_resourceGroup->SetConstant(m_uvMaxIndex, uvMax); - m_resourceGroup->SetConstant(m_uvStepIndex, uvStep); - m_resourceGroup->Compile(); - m_processSrgs.push_back(m_resourceGroup); - - if (m_resourceGroup != nullptr) - { - drawPacketBuilder.AddShaderResourceGroup(m_resourceGroup->GetRHIShaderResourceGroup()); - } + resourceGroup->SetImage(m_heightmapImageIndex, m_areaData.m_heightmapImage); + resourceGroup->SetConstant(m_modelToWorldIndex, matrix3x4); + resourceGroup->SetConstant(m_heightScaleIndex, m_areaData.m_heightScale); + resourceGroup->SetConstant(m_uvMinIndex, uvMin); + resourceGroup->SetConstant(m_uvMaxIndex, uvMax); + resourceGroup->SetConstant(m_uvStepIndex, uvStep); + resourceGroup->Compile(); + drawPacketBuilder.AddShaderResourceGroup(resourceGroup->GetRHIShaderResourceGroup()); AZ::RHI::DrawPacketBuilder::DrawRequest drawRequest; drawRequest.m_listTag = m_drawListTag; drawRequest.m_pipelineState = m_pipelineState.get(); - drawRequest.m_streamBufferViews = m_vertexBufferViews; + drawRequest.m_streamBufferViews = AZStd::array_view(&m_vertexBufferView, 1); drawPacketBuilder.AddDrawItem(drawRequest); - - const AZ::RHI::DrawPacket* drawPacket = drawPacketBuilder.End(); - m_drawPackets.emplace_back(drawPacket); - - for (auto& view : process.m_views) - { - view->AddDrawPacket(drawPacket); - } + + m_sectorData.emplace_back( + drawPacketBuilder.End(), + AZ::Aabb::CreateFromMinMax( + AZ::Vector3(xPatch, yPatch, m_areaData.m_terrainBounds.GetMin().GetZ()), + AZ::Vector3(xPatch + m_gridMeters, yPatch + m_gridMeters, m_areaData.m_terrainBounds.GetMax().GetZ()) + ), + resourceGroup + ); + } + } + } + + for (auto& view : process.m_views) + { + AZ::Frustum viewFrustum = AZ::Frustum::CreateFromMatrixColumnMajor(view->GetWorldToClipMatrix()); + for (auto& sectorData : m_sectorData) + { + if (viewFrustum.IntersectAabb(sectorData.m_aabb) != AZ::IntersectResult::Exterior) + { + view->AddDrawPacket(sectorData.m_drawPacket.get()); } } } @@ -413,9 +393,6 @@ namespace Terrain m_indexBuffer->SetName(AZ::Name("TerrainIndexBuffer")); m_vertexBuffer->SetName(AZ::Name("TerrainVertexBuffer")); - // We only need one vertex buffer view. - m_vertexBufferViews.resize(1); - AZStd::vector> buffers = { m_indexBuffer , m_vertexBuffer }; // Fill our buffers with the vertex/index data @@ -433,7 +410,7 @@ namespace Terrain if (result != AZ::RHI::ResultCode::Success) { - AZ_Error("Terrain", false, "Failed to create GPU buffers for Terrain"); + AZ_Error(TerrainFPName, false, "Failed to create GPU buffers for Terrain"); return false; } @@ -462,10 +439,10 @@ namespace Terrain const uint64_t elementSize = m_gridVertices.size() * sizeof(Vertex); memcpy(mappedData, m_gridVertices.data(), elementSize); - m_vertexBufferViews[bufferIndex - 1] = AZ::RHI::StreamBufferView( + m_vertexBufferView = AZ::RHI::StreamBufferView( *buffer, 0, static_cast(elementSize), static_cast(sizeof(Vertex))); - AZ::RHI::ValidateStreamBufferViews(m_pipelineStateDescriptor.m_inputStreamLayout, m_vertexBufferViews); + AZ::RHI::ValidateStreamBufferViews(m_pipelineStateDescriptor.m_inputStreamLayout, { { m_vertexBufferView } }); } m_hostPool->UnmapBuffer(*buffer); @@ -479,9 +456,8 @@ namespace Terrain m_indexBuffer.reset(); m_vertexBuffer.reset(); - m_vertexBufferViews.clear(); - - m_processSrgs.clear(); + m_indexBufferView = {}; + m_vertexBufferView = {}; m_pipelineStateDescriptor = AZ::RHI::PipelineStateDescriptorForDraw{}; m_pipelineState = nullptr; diff --git a/Gems/Terrain/Code/Source/TerrainRenderer/TerrainFeatureProcessor.h b/Gems/Terrain/Code/Source/TerrainRenderer/TerrainFeatureProcessor.h index 2a1d5b7514..7a7b63b634 100644 --- a/Gems/Terrain/Code/Source/TerrainRenderer/TerrainFeatureProcessor.h +++ b/Gems/Terrain/Code/Source/TerrainRenderer/TerrainFeatureProcessor.h @@ -47,16 +47,12 @@ namespace Terrain void Deactivate() override; void Render(const AZ::RPI::FeatureProcessor::RenderPacket& packet) override; - void UpdateTerrainData(AZ::EntityId areaId, const AZ::Transform& transform, const AZ::Aabb& worldBounds, float sampleSpacing, + void UpdateTerrainData(const AZ::Transform& transform, const AZ::Aabb& worldBounds, float sampleSpacing, uint32_t width, uint32_t height, const AZStd::vector& heightData); - void RemoveTerrainData(AZ::EntityId areaId) - { - m_areaData.erase(areaId); - } void RemoveTerrainData() { - m_areaData.clear(); + m_areaData = {}; } private: @@ -122,13 +118,13 @@ namespace Terrain AZ::RHI::Ptr m_indexBuffer; AZ::RHI::Ptr m_vertexBuffer; AZ::RHI::IndexBufferView m_indexBufferView; - AZStd::fixed_vector m_vertexBufferViews; + AZ::RHI::StreamBufferView m_vertexBufferView; // Per-area data struct TerrainAreaData { - AZ::Transform m_transform; - AZ::Aabb m_terrainBounds; + AZ::Transform m_transform{ AZ::Transform::CreateIdentity() }; + AZ::Aabb m_terrainBounds{ AZ::Aabb::CreateNull() }; float m_heightScale; AZ::Data::Instance m_heightmapImage; uint32_t m_heightmapImageWidth; @@ -136,10 +132,21 @@ namespace Terrain bool m_propertiesDirty{ true }; }; - AZStd::unordered_map m_areaData; + TerrainAreaData m_areaData; - // These could either be per-area or system-level - AZStd::vector> m_drawPackets; - AZStd::vector> m_processSrgs; + struct SectorData + { + AZ::Data::Instance m_srg; + AZ::Aabb m_aabb; + AZStd::unique_ptr m_drawPacket; + + SectorData(const AZ::RHI::DrawPacket* drawPacket, AZ::Aabb aabb, AZ::Data::Instance srg) + : m_srg(srg) + , m_aabb(aabb) + , m_drawPacket(drawPacket) + {} + }; + + AZStd::vector m_sectorData; }; } diff --git a/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.cpp b/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.cpp index 872b37a02e..90b74f08ba 100644 --- a/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.cpp +++ b/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.cpp @@ -49,15 +49,9 @@ void TerrainSystem::Deactivate() m_terrainSettingsDirty = true; } -void TerrainSystem::SetWorldMin(AZ::Vector3 worldOrigin) -{ - m_requestedSettings.m_worldBounds.SetMin(worldOrigin); - m_terrainSettingsDirty = true; -} - -void TerrainSystem::SetWorldMax(AZ::Vector3 worldBounds) -{ - m_requestedSettings.m_worldBounds.SetMax(worldBounds); +void TerrainSystem::SetWorldBounds(const AZ::Aabb& worldBounds) +{ + m_requestedSettings.m_worldBounds = worldBounds; m_terrainSettingsDirty = true; } @@ -67,13 +61,6 @@ void TerrainSystem::SetHeightQueryResolution(AZ::Vector2 queryResolution) m_terrainSettingsDirty = true; } -void TerrainSystem::SetDebugWireframe(bool wireframeEnabled) -{ - m_requestedSettings.m_debugWireframeEnabled = wireframeEnabled; - m_terrainSettingsDirty = true; -} - - AZ::Aabb TerrainSystem::GetTerrainAabb() const { return m_currentSettings.m_worldBounds; @@ -378,13 +365,6 @@ void TerrainSystem::OnTick(float /*deltaTime*/, AZ::ScriptTimePoint /*time*/) terrainSettingsChanged = true; } - if (m_requestedSettings.m_debugWireframeEnabled != m_currentSettings.m_debugWireframeEnabled) - { - m_dirtyRegion = AZ::Aabb::CreateNull(); - m_terrainHeightDirty = true; - terrainSettingsChanged = true; - } - if (m_requestedSettings.m_heightQueryResolution != m_currentSettings.m_heightQueryResolution) { m_dirtyRegion = AZ::Aabb::CreateNull(); @@ -409,7 +389,6 @@ void TerrainSystem::OnTick(float /*deltaTime*/, AZ::ScriptTimePoint /*time*/) { AZStd::shared_lock lock(m_areaMutex); - AZ::EntityId entityId(0); AZ::Transform transform = AZ::Transform::CreateTranslation(m_currentSettings.m_worldBounds.GetCenter()); uint32_t width = aznumeric_cast( @@ -417,7 +396,7 @@ void TerrainSystem::OnTick(float /*deltaTime*/, AZ::ScriptTimePoint /*time*/) uint32_t height = aznumeric_cast( (float)m_currentSettings.m_worldBounds.GetYExtent() / m_currentSettings.m_heightQueryResolution.GetY()); AZStd::vector pixels; - pixels.resize(width * height); + pixels.resize_no_construct(width * height); const uint32_t pixelDataSize = width * height * sizeof(float); memset(pixels.data(), 0, pixelDataSize); @@ -454,8 +433,7 @@ void TerrainSystem::OnTick(float /*deltaTime*/, AZ::ScriptTimePoint /*time*/) if (terrainFeatureProcessor) { terrainFeatureProcessor->UpdateTerrainData( - entityId, transform, m_currentSettings.m_worldBounds, m_currentSettings.m_heightQueryResolution.GetX(), width, height, - pixels); + transform, m_currentSettings.m_worldBounds, m_currentSettings.m_heightQueryResolution.GetX(), width, height, pixels); } } diff --git a/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.h b/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.h index 56ed182047..2d2286a0c3 100644 --- a/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.h +++ b/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.h @@ -36,11 +36,9 @@ namespace Terrain /////////////////////////////////////////// // TerrainSystemServiceRequestBus::Handler Impl - - void SetWorldMin(AZ::Vector3 worldOrigin) override; - void SetWorldMax(AZ::Vector3 worldBounds) override; + + void SetWorldBounds(const AZ::Aabb& worldBounds) override; void SetHeightQueryResolution(AZ::Vector2 queryResolution) override; - void SetDebugWireframe(bool wireframeEnabled) override; void Activate() override; void Deactivate() override; @@ -103,7 +101,6 @@ namespace Terrain { AZ::Aabb m_worldBounds; AZ::Vector2 m_heightQueryResolution{ 1.0f }; - bool m_debugWireframeEnabled{ false }; bool m_systemActive{ false }; }; diff --git a/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystemBus.h b/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystemBus.h index 08521fd780..e999cbf8be 100644 --- a/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystemBus.h +++ b/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystemBus.h @@ -39,10 +39,8 @@ namespace Terrain virtual void Activate() = 0; virtual void Deactivate() = 0; - virtual void SetWorldMin(AZ::Vector3 worldOrigin) = 0; - virtual void SetWorldMax(AZ::Vector3 worldBounds) = 0; + virtual void SetWorldBounds(const AZ::Aabb& worldBounds) = 0; virtual void SetHeightQueryResolution(AZ::Vector2 queryResolution) = 0; - virtual void SetDebugWireframe(bool wireframeEnabled) = 0; // register an area to override terrain virtual void RegisterArea(AZ::EntityId areaId) = 0; @@ -111,8 +109,6 @@ namespace Terrain virtual void GetHeight(const AZ::Vector3& inPosition, AZ::Vector3& outPosition, Sampler sampleFilter = Sampler::DEFAULT) = 0; virtual void GetNormal(const AZ::Vector3& inPosition, AZ::Vector3& outNormal, Sampler sampleFilter = Sampler::DEFAULT) = 0; - //virtual void GetSurfaceWeights(const AZ::Vector3& inPosition, SurfaceTagWeightMap& outSurfaceWeights, Sampler sampleFilter = DEFAULT) = 0; - //virtual void GetSurfacePoint(const AZ::Vector3& inPosition, SurfacePoint& outSurfacePoint, SurfacePointDataMask dataMask = DEFAULT, Sampler sampleFilter = DEFAULT) = 0; }; using TerrainAreaHeightRequestBus = AZ::EBus;