Non-terrain-gem changes in support of upcoming terrain work. (#3345)

In preparation for a prototype Terrain Gem to get submitted, there are a few changes that are needed outside of the Terrain Gem as well:

The TerrainDataNotificationBus lives in AzFramework/Terrain, and needed to be extended to contain an optional OnTerrainDataChanged event to notify other systems when a terrain region has changed.
The HeightmapUpdateNotificationBus was removed, as this was a legacy file from the old already-removed terrain system.
The EditorWrappedComponentBase<> wrapper received a small optimization to ensure that ConfigurationChanged() is only called when the value of visibility actually changes. With prefabs, it appears that sometimes OnEntityVisibilityChanged could be called multiple times in a row with the same visibility value.
The TerrainSurfaceDataSystemComponent was updated to use the correct busses, and is ready to be moved to the Terrain Gem in a subsequent PR.

Signed-off-by: Mike Balfour 82224783+mbalfour-amzn@users.noreply.github.com
This commit is contained in:
Mike Balfour
2021-08-20 11:31:19 -05:00
committed by GitHub
parent cef82f0313
commit bf42e3f02a
8 changed files with 75 additions and 110 deletions
@@ -6,20 +6,16 @@
*
*/
#include "TerrainSurfaceDataSystemComponent.h"
#include <TerrainSurfaceDataSystemComponent.h>
#include <AzCore/Debug/Profiler.h>
#include <AzCore/Math/MathUtils.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzFramework/Terrain/TerrainDataRequestBus.h>
#include <MathConversion.h>
#include <SurfaceData/SurfaceDataSystemRequestBus.h>
#include <SurfaceData/SurfaceTag.h>
#include <SurfaceData/Utility/SurfaceDataUtility.h>
#include <ISystem.h>
namespace SurfaceData
namespace Terrain
{
//////////////////////////////////////////////////////////////////////////
// TerrainSurfaceDataSystemConfig
@@ -98,26 +94,23 @@ namespace SurfaceData
void TerrainSurfaceDataSystemComponent::Activate()
{
m_providerHandle = InvalidSurfaceDataRegistryHandle;
m_system = GetISystem();
CrySystemEventBus::Handler::BusConnect();
AZ::HeightmapUpdateNotificationBus::Handler::BusConnect();
m_providerHandle = SurfaceData::InvalidSurfaceDataRegistryHandle;
AzFramework::Terrain::TerrainDataNotificationBus::Handler::BusConnect();
UpdateTerrainData(AZ::Aabb::CreateNull());
}
void TerrainSurfaceDataSystemComponent::Deactivate()
{
if (m_providerHandle != InvalidSurfaceDataRegistryHandle)
if (m_providerHandle != SurfaceData::InvalidSurfaceDataRegistryHandle)
{
SurfaceDataSystemRequestBus::Broadcast(&SurfaceDataSystemRequestBus::Events::UnregisterSurfaceDataProvider, m_providerHandle);
m_providerHandle = InvalidSurfaceDataRegistryHandle;
SurfaceData::SurfaceDataSystemRequestBus::Broadcast(
&SurfaceData::SurfaceDataSystemRequestBus::Events::UnregisterSurfaceDataProvider, m_providerHandle);
m_providerHandle = SurfaceData::InvalidSurfaceDataRegistryHandle;
}
SurfaceDataProviderRequestBus::Handler::BusDisconnect();
AZ::HeightmapUpdateNotificationBus::Handler::BusDisconnect();
CrySystemEventBus::Handler::BusDisconnect();
m_system = nullptr;
SurfaceData::SurfaceDataProviderRequestBus::Handler::BusDisconnect();
AzFramework::Terrain::TerrainDataNotificationBus::Handler::BusDisconnect();
// Clear the cached terrain bounds data
{
@@ -146,17 +139,8 @@ namespace SurfaceData
return false;
}
void TerrainSurfaceDataSystemComponent::OnCrySystemInitialized(ISystem& system, [[maybe_unused]] const SSystemInitParams& systemInitParams)
{
m_system = &system;
}
void TerrainSurfaceDataSystemComponent::OnCrySystemShutdown([[maybe_unused]] ISystem& system)
{
m_system = nullptr;
}
void TerrainSurfaceDataSystemComponent::GetSurfacePoints(const AZ::Vector3& inPosition, SurfacePointList& surfacePointList) const
void TerrainSurfaceDataSystemComponent::GetSurfacePoints(
const AZ::Vector3& inPosition, SurfaceData::SurfacePointList& surfacePointList) const
{
if (m_terrainBoundsIsValid)
{
@@ -168,12 +152,13 @@ namespace SurfaceData
const float terrainHeight = terrain->GetHeight(inPosition, AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR, &isTerrainValidAtPoint);
const bool isHole = !isTerrainValidAtPoint;
SurfacePoint point;
SurfaceData::SurfacePoint point;
point.m_entityId = GetEntityId();
point.m_position = AZ::Vector3(inPosition.GetX(), inPosition.GetY(), terrainHeight);
point.m_normal = terrain->GetNormal(inPosition);
const AZ::Crc32 terrainTag = isHole ? Constants::s_terrainHoleTagCrc : Constants::s_terrainTagCrc;
AddMaxValueForMasks(point.m_masks, terrainTag, 1.0f);
const AZ::Crc32 terrainTag =
isHole ? SurfaceData::Constants::s_terrainHoleTagCrc : SurfaceData::Constants::s_terrainTagCrc;
SurfaceData::AddMaxValueForMasks(point.m_masks, terrainTag, 1.0f);
surfacePointList.push_back(point);
}
// Only one handler should exist.
@@ -189,11 +174,11 @@ namespace SurfaceData
return terrain ? terrain->GetTerrainAabb() : AZ::Aabb::CreateNull();
}
SurfaceTagVector TerrainSurfaceDataSystemComponent::GetSurfaceTags() const
SurfaceData::SurfaceTagVector TerrainSurfaceDataSystemComponent::GetSurfaceTags() const
{
SurfaceTagVector tags;
tags.push_back(Constants::s_terrainHoleTagCrc);
tags.push_back(Constants::s_terrainTagCrc);
SurfaceData::SurfaceTagVector tags;
tags.push_back(SurfaceData::Constants::s_terrainHoleTagCrc);
tags.push_back(SurfaceData::Constants::s_terrainTagCrc);
return tags;
}
@@ -203,7 +188,7 @@ namespace SurfaceData
bool terrainValidAfterUpdate = false;
AZ::Aabb terrainBoundsBeforeUpdate = m_terrainBounds;
SurfaceDataRegistryEntry registryEntry;
SurfaceData::SurfaceDataRegistryEntry registryEntry;
registryEntry.m_entityId = GetEntityId();
registryEntry.m_bounds = GetSurfaceAabb();
registryEntry.m_tags = GetSurfaceTags();
@@ -215,38 +200,44 @@ namespace SurfaceData
if (terrainValidBeforeUpdate && terrainValidAfterUpdate)
{
AZ_Assert((m_providerHandle != InvalidSurfaceDataRegistryHandle), "Invalid surface data handle");
AZ_Assert((m_providerHandle != SurfaceData::InvalidSurfaceDataRegistryHandle), "Invalid surface data handle");
// Our terrain was valid before and after, it just changed in some way. If we have a valid dirty region passed in
// then it's possible that the heightmap has been modified in the Editor. Otherwise, just notify that the entire
// terrain has changed in some way.
if (dirtyRegion.IsValid())
{
SurfaceDataSystemRequestBus::Broadcast(&SurfaceDataSystemRequestBus::Events::RefreshSurfaceData, dirtyRegion);
SurfaceData::SurfaceDataSystemRequestBus::Broadcast(
&SurfaceData::SurfaceDataSystemRequestBus::Events::RefreshSurfaceData, dirtyRegion);
}
else
{
SurfaceDataSystemRequestBus::Broadcast(&SurfaceDataSystemRequestBus::Events::UpdateSurfaceDataProvider, m_providerHandle, registryEntry);
SurfaceData::SurfaceDataSystemRequestBus::Broadcast(
&SurfaceData::SurfaceDataSystemRequestBus::Events::UpdateSurfaceDataProvider, m_providerHandle, registryEntry);
}
}
else if (!terrainValidBeforeUpdate && terrainValidAfterUpdate)
{
// Our terrain has become valid, so register as a provider and save off the registry handles
AZ_Assert((m_providerHandle == InvalidSurfaceDataRegistryHandle), "Surface Provider data handle is initialized before our terrain became valid");
SurfaceDataSystemRequestBus::BroadcastResult(m_providerHandle, &SurfaceDataSystemRequestBus::Events::RegisterSurfaceDataProvider, registryEntry);
AZ_Assert(
(m_providerHandle == SurfaceData::InvalidSurfaceDataRegistryHandle),
"Surface Provider data handle is initialized before our terrain became valid");
SurfaceData::SurfaceDataSystemRequestBus::BroadcastResult(
m_providerHandle, &SurfaceData::SurfaceDataSystemRequestBus::Events::RegisterSurfaceDataProvider, registryEntry);
// Start listening for surface data events
AZ_Assert((m_providerHandle != InvalidSurfaceDataRegistryHandle), "Invalid surface data handle");
SurfaceDataProviderRequestBus::Handler::BusConnect(m_providerHandle);
AZ_Assert((m_providerHandle != SurfaceData::InvalidSurfaceDataRegistryHandle), "Invalid surface data handle");
SurfaceData::SurfaceDataProviderRequestBus::Handler::BusConnect(m_providerHandle);
}
else if (terrainValidBeforeUpdate && !terrainValidAfterUpdate)
{
// Our terrain has stopped being valid, so unregister and stop listening for surface data events
AZ_Assert((m_providerHandle != InvalidSurfaceDataRegistryHandle), "Invalid surface data handle");
SurfaceDataSystemRequestBus::Broadcast(&SurfaceDataSystemRequestBus::Events::UnregisterSurfaceDataProvider, m_providerHandle);
m_providerHandle = InvalidSurfaceDataRegistryHandle;
AZ_Assert((m_providerHandle != SurfaceData::InvalidSurfaceDataRegistryHandle), "Invalid surface data handle");
SurfaceData::SurfaceDataSystemRequestBus::Broadcast(
&SurfaceData::SurfaceDataSystemRequestBus::Events::UnregisterSurfaceDataProvider, m_providerHandle);
m_providerHandle = SurfaceData::InvalidSurfaceDataRegistryHandle;
SurfaceDataProviderRequestBus::Handler::BusDisconnect();
SurfaceData::SurfaceDataProviderRequestBus::Handler::BusDisconnect();
}
else
{
@@ -255,8 +246,9 @@ namespace SurfaceData
}
void TerrainSurfaceDataSystemComponent::HeightmapModified(const AZ::Aabb& bounds)
void TerrainSurfaceDataSystemComponent::OnTerrainDataChanged(
const AZ::Aabb& dirtyRegion, [[maybe_unused]] TerrainDataChangedMask dataChangedMask)
{
UpdateTerrainData(bounds);
UpdateTerrainData(dirtyRegion);
}
}