Terrain/mbalfour/terrain macro material component (#4500)

* Initial TerrainMacroMaterial Component.
The APIs will likely need to be adjusted once it gets hooked up to the renderer.
It also would benefit from better UX to prevent users from selecting the wrong material types, but there are separate tickets for the Editor to add features to allow for that.

Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com>

* Addressed PR feedback.

Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com>

* More PR feedback - add create/destroy notifications.

Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com>
monroegm-disable-blank-issue-2
Mike Balfour 4 years ago committed by GitHub
parent 38ccc6a8a6
commit f68d2676a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,8 @@
{
"description": "",
"materialType": "TerrainMacroMaterial.materialtype",
"parentMaterial": "",
"propertyLayoutVersion": 1,
"properties": {
}
}

@ -0,0 +1,46 @@
{
"description": "A material for providing terrain with low-fidelity color and normals. This material will get blended with surface detail materials.",
"propertyLayout": {
"version": 1,
"groups": [
{
"id": "settings",
"displayName": "Settings"
}
],
"properties": {
"macroColor": [
{
"id": "useTexture",
"displayName": "Use Texture",
"description": "Whether to use the texture.",
"type": "Bool",
"defaultValue": true
}
],
"macroNormal": [
{
"id": "useTexture",
"displayName": "Use Texture",
"description": "Whether to use the texture.",
"type": "Bool",
"defaultValue": true
}
]
}
},
"shaders": [
{
"file": "../../Shaders/Terrain/TerrainPBR_ForwardPass.shader"
},
{
"file": "../../Shaders/Terrain/Terrain_Shadowmap.shader"
},
{
"file": "../../Shaders/Terrain/Terrain_DepthPass.shader"
}
],
"functors": [
]
}

@ -14,6 +14,7 @@
#include <EditorComponents/EditorTerrainWorldComponent.h>
#include <EditorComponents/EditorTerrainWorldDebuggerComponent.h>
#include <EditorComponents/EditorTerrainWorldRendererComponent.h>
#include <TerrainRenderer/EditorComponents/EditorTerrainMacroMaterialComponent.h>
namespace Terrain
{
@ -24,6 +25,7 @@ namespace Terrain
{
Terrain::EditorTerrainHeightGradientListComponent::CreateDescriptor(),
Terrain::EditorTerrainLayerSpawnerComponent::CreateDescriptor(),
Terrain::EditorTerrainMacroMaterialComponent::CreateDescriptor(),
Terrain::EditorTerrainSurfaceGradientListComponent::CreateDescriptor(),
Terrain::EditorTerrainSystemComponent::CreateDescriptor(),
Terrain::EditorTerrainWorldComponent::CreateDescriptor(),

@ -18,6 +18,7 @@
#include <Components/TerrainLayerSpawnerComponent.h>
#include <Components/TerrainSurfaceGradientListComponent.h>
#include <Components/TerrainSurfaceDataSystemComponent.h>
#include <TerrainRenderer/Components/TerrainMacroMaterialComponent.h>
namespace Terrain
{
@ -31,6 +32,7 @@ namespace Terrain
TerrainWorldRendererComponent::CreateDescriptor(),
TerrainHeightGradientListComponent::CreateDescriptor(),
TerrainLayerSpawnerComponent::CreateDescriptor(),
TerrainMacroMaterialComponent::CreateDescriptor(),
TerrainSurfaceGradientListComponent::CreateDescriptor(),
TerrainSurfaceDataSystemComponent::CreateDescriptor(),
});

@ -0,0 +1,287 @@
/*
* 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 <TerrainRenderer/Components/TerrainMacroMaterialComponent.h>
#include <AzCore/Asset/AssetSerializer.h>
#include <AzCore/Asset/AssetManager.h>
#include <AzCore/Asset/AssetManagerBus.h>
#include <AzCore/Component/Entity.h>
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/SerializeContext.h>
namespace Terrain
{
AZ::Data::AssetId TerrainMacroMaterialConfig::s_macroMaterialTypeAssetId{};
void TerrainMacroMaterialConfig::Reflect(AZ::ReflectContext* context)
{
AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context);
if (serialize)
{
serialize->Class<TerrainMacroMaterialConfig, AZ::ComponentConfig>()
->Version(1)
->Field("MacroMaterial", &TerrainMacroMaterialConfig::m_materialAsset)
;
// The edit context for this appears in EditorTerrainMacroMaterialComponent.cpp.
}
}
AZ::Data::AssetId TerrainMacroMaterialConfig::GetTerrainMacroMaterialTypeAssetId()
{
// Get the Asset ID for the TerrainMacroMaterial material type and store it in a class static so that we don't have to look it
// up again.
if (!s_macroMaterialTypeAssetId.IsValid())
{
AZ::Data::AssetCatalogRequestBus::BroadcastResult(
s_macroMaterialTypeAssetId, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetIdByPath, TerrainMacroMaterialTypeAsset,
azrtti_typeid<AZ::RPI::MaterialTypeAsset>(), false);
AZ_Assert(s_macroMaterialTypeAssetId.IsValid(), "The asset '%s' couldn't be found.", TerrainMacroMaterialTypeAsset);
}
return s_macroMaterialTypeAssetId;
}
bool TerrainMacroMaterialConfig::IsMaterialTypeCorrect(const AZ::Data::AssetId& assetId)
{
// We'll verify that whatever material we try to load has this material type as a dependency, as a way to implicitly detect
// that we're only trying to use terrain macro materials even before we load the asset.
auto macroMaterialTypeAssetId = GetTerrainMacroMaterialTypeAssetId();
// Get the dependencies for the requested asset.
AZ::Outcome<AZStd::vector<AZ::Data::ProductDependency>, AZStd::string> result;
AZ::Data::AssetCatalogRequestBus::BroadcastResult(
result, &AZ::Data::AssetCatalogRequestBus::Events::GetDirectProductDependencies, assetId);
// If any of the dependencies match the TerrainMacroMaterial materialtype asset, then this should be the correct type of material.
if (result)
{
for (auto& dependency : result.GetValue())
{
if (dependency.m_assetId == macroMaterialTypeAssetId)
{
return true;
}
}
}
// Didn't have the expected dependency, so it must not be the right material type.
return false;
}
AZ::Outcome<void, AZStd::string> TerrainMacroMaterialConfig::ValidateMaterialAsset(void* newValue, const AZ::Uuid& valueType)
{
if (azrtti_typeid<AZ::Data::Asset<AZ::RPI::MaterialAsset>>() != valueType)
{
AZ_Assert(false, "Unexpected value type");
return AZ::Failure(AZStd::string("Unexpectedly received something other than a material asset for the MacroMaterial!"));
}
auto newMaterialAsset = *static_cast<AZ::Data::Asset<AZ::RPI::MaterialAsset>*>(newValue);
if (!IsMaterialTypeCorrect(newMaterialAsset.GetId()))
{
return AZ::Failure(AZStd::string::format(
"The selected MacroMaterial ('%s') needs to use the TerrainMacroMaterial material type.",
newMaterialAsset.GetHint().c_str()));
}
return AZ::Success();
}
void TerrainMacroMaterialComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services)
{
services.push_back(AZ_CRC_CE("TerrainMacroMaterialProviderService"));
}
void TerrainMacroMaterialComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services)
{
services.push_back(AZ_CRC_CE("TerrainMacroMaterialProviderService"));
}
void TerrainMacroMaterialComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& services)
{
services.push_back(AZ_CRC_CE("AxisAlignedBoxShapeService"));
}
void TerrainMacroMaterialComponent::Reflect(AZ::ReflectContext* context)
{
TerrainMacroMaterialConfig::Reflect(context);
AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context);
if (serialize)
{
serialize->Class<TerrainMacroMaterialComponent, AZ::Component>()
->Version(0)
->Field("Configuration", &TerrainMacroMaterialComponent::m_configuration)
;
}
}
TerrainMacroMaterialComponent::TerrainMacroMaterialComponent(const TerrainMacroMaterialConfig& configuration)
: m_configuration(configuration)
{
}
void TerrainMacroMaterialComponent::Activate()
{
// Clear out our shape bounds and make sure the material is queued to load.
m_cachedShapeBounds = AZ::Aabb::CreateNull();
m_configuration.m_materialAsset.QueueLoad();
// Don't mark our material as active until it's finished loading and is valid.
m_macroMaterialActive = false;
// Listen for the material asset to complete loading.
AZ::Data::AssetBus::Handler::BusConnect(m_configuration.m_materialAsset.GetId());
}
void TerrainMacroMaterialComponent::Deactivate()
{
TerrainMacroMaterialRequestBus::Handler::BusDisconnect();
AZ::Data::AssetBus::Handler::BusDisconnect();
m_configuration.m_materialAsset.Release();
m_macroMaterialInstance.reset();
// Send out any notifications as appropriate based on the macro material destruction.
HandleMaterialStateChange();
}
bool TerrainMacroMaterialComponent::ReadInConfig(const AZ::ComponentConfig* baseConfig)
{
if (auto config = azrtti_cast<const TerrainMacroMaterialConfig*>(baseConfig))
{
m_configuration = *config;
return true;
}
return false;
}
bool TerrainMacroMaterialComponent::WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const
{
if (auto config = azrtti_cast<TerrainMacroMaterialConfig*>(outBaseConfig))
{
*config = m_configuration;
return true;
}
return false;
}
void TerrainMacroMaterialComponent::OnShapeChanged([[maybe_unused]] ShapeComponentNotifications::ShapeChangeReasons reasons)
{
// This should only get called while the macro material is active. If it gets called while the macro material isn't active,
// we've got a bug where we haven't managed the bus connections properly.
AZ_Assert(m_macroMaterialActive, "The ShapeComponentNotificationBus connection is out of sync with the material load.");
AZ::Aabb oldShapeBounds = m_cachedShapeBounds;
LmbrCentral::ShapeComponentRequestsBus::EventResult(
m_cachedShapeBounds, GetEntityId(), &LmbrCentral::ShapeComponentRequestsBus::Events::GetEncompassingAabb);
TerrainMacroMaterialNotificationBus::Broadcast(
&TerrainMacroMaterialNotificationBus::Events::OnTerrainMacroMaterialRegionChanged,
GetEntityId(), oldShapeBounds, m_cachedShapeBounds);
}
void TerrainMacroMaterialComponent::HandleMaterialStateChange()
{
// We only want our component to appear active during the time that the macro material is loaded and valid. The logic below
// will handle all transition possibilities to notify if we've become active, inactive, or just changed. We'll also only
// keep a valid up-to-date copy of the shape bounds while the material is valid, since we don't need it any other time.
bool wasPreviouslyActive = m_macroMaterialActive;
bool isNowActive = (m_macroMaterialInstance != nullptr);
// Set our state to active or inactive, based on whether or not the macro material instance is now valid.
m_macroMaterialActive = isNowActive;
// Handle the different inactive/active transition possibilities.
if (!wasPreviouslyActive && !isNowActive)
{
// Do nothing, we haven't yet successfully loaded a valid material.
}
else if (!wasPreviouslyActive && isNowActive)
{
// We've transitioned from inactive to active, so send out a message saying that we've been created and start tracking the
// overall shape bounds.
// Get the current shape bounds.
LmbrCentral::ShapeComponentRequestsBus::EventResult(
m_cachedShapeBounds, GetEntityId(), &LmbrCentral::ShapeComponentRequestsBus::Events::GetEncompassingAabb);
// Start listening for terrain macro material requests.
TerrainMacroMaterialRequestBus::Handler::BusConnect(GetEntityId());
// Start listening for shape changes.
LmbrCentral::ShapeComponentNotificationsBus::Handler::BusConnect(GetEntityId());
TerrainMacroMaterialNotificationBus::Broadcast(
&TerrainMacroMaterialNotificationBus::Events::OnTerrainMacroMaterialCreated, GetEntityId(), m_macroMaterialInstance,
m_cachedShapeBounds);
}
else if (wasPreviouslyActive && !isNowActive)
{
// Stop listening to macro material requests or shape changes, and send out a notification that we no longer have a valid
// macro material.
TerrainMacroMaterialRequestBus::Handler::BusDisconnect();
LmbrCentral::ShapeComponentNotificationsBus::Handler::BusDisconnect();
m_cachedShapeBounds = AZ::Aabb::CreateNull();
TerrainMacroMaterialNotificationBus::Broadcast(
&TerrainMacroMaterialNotificationBus::Events::OnTerrainMacroMaterialDestroyed, GetEntityId());
}
else
{
// We were active both before and after, so just send out a material changed event.
TerrainMacroMaterialNotificationBus::Broadcast(
&TerrainMacroMaterialNotificationBus::Events::OnTerrainMacroMaterialChanged, GetEntityId(), m_macroMaterialInstance);
}
}
void TerrainMacroMaterialComponent::OnAssetReady(AZ::Data::Asset<AZ::Data::AssetData> asset)
{
m_configuration.m_materialAsset = asset;
if (m_configuration.m_materialAsset.Get()->GetMaterialTypeAsset().GetId() ==
TerrainMacroMaterialConfig::GetTerrainMacroMaterialTypeAssetId())
{
m_macroMaterialInstance = AZ::RPI::Material::FindOrCreate(m_configuration.m_materialAsset);
}
else
{
AZ_Error("Terrain", false, "Material '%s' has the wrong material type.", m_configuration.m_materialAsset.GetHint().c_str());
m_macroMaterialInstance.reset();
}
// Clear the material asset reference to make sure we don't prevent hot-reloading.
m_configuration.m_materialAsset.Release();
HandleMaterialStateChange();
}
void TerrainMacroMaterialComponent::OnAssetReloaded(AZ::Data::Asset<AZ::Data::AssetData> asset)
{
OnAssetReady(asset);
}
void TerrainMacroMaterialComponent::GetTerrainMacroMaterialData(
AZ::Data::Instance<AZ::RPI::Material>& macroMaterial, AZ::Aabb& macroMaterialRegion)
{
macroMaterial = m_macroMaterialInstance;
macroMaterialRegion = m_cachedShapeBounds;
}
}

@ -0,0 +1,92 @@
/*
* 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
*
*/
#pragma once
#include <AzCore/Asset/AssetCommon.h>
#include <AzCore/Component/Component.h>
#include <AzCore/Math/Aabb.h>
#include <Atom/RPI.Reflect/Material/MaterialAsset.h>
#include <LmbrCentral/Shape/ShapeComponentBus.h>
#include <TerrainRenderer/TerrainMacroMaterialBus.h>
namespace LmbrCentral
{
template<typename, typename>
class EditorWrappedComponentBase;
}
namespace Terrain
{
class TerrainMacroMaterialConfig
: public AZ::ComponentConfig
{
public:
AZ_CLASS_ALLOCATOR(TerrainMacroMaterialConfig, AZ::SystemAllocator, 0);
AZ_RTTI(TerrainMacroMaterialConfig, "{9DBAFFF0-FD20-4594-8884-E3266D8CCAC8}", AZ::ComponentConfig);
static void Reflect(AZ::ReflectContext* context);
AZ::Data::Asset<AZ::RPI::MaterialAsset> m_materialAsset = { AZ::Data::AssetLoadBehavior::QueueLoad };
static AZ::Data::AssetId GetTerrainMacroMaterialTypeAssetId();
static bool IsMaterialTypeCorrect(const AZ::Data::AssetId&);
AZ::Outcome<void, AZStd::string> ValidateMaterialAsset(void* newValue, const AZ::Uuid& valueType);
private:
static inline constexpr const char* TerrainMacroMaterialTypeAsset = "materials/terrain/terrainmacromaterial.azmaterialtype";
static AZ::Data::AssetId s_macroMaterialTypeAssetId;
};
class TerrainMacroMaterialComponent
: public AZ::Component
, public TerrainMacroMaterialRequestBus::Handler
, private LmbrCentral::ShapeComponentNotificationsBus::Handler
, private AZ::Data::AssetBus::Handler
{
public:
template<typename, typename>
friend class LmbrCentral::EditorWrappedComponentBase;
AZ_COMPONENT(TerrainMacroMaterialComponent, "{F82379FB-E2AE-4F75-A6F4-1AE5F5DA42E8}");
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services);
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services);
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& services);
static void Reflect(AZ::ReflectContext* context);
TerrainMacroMaterialComponent(const TerrainMacroMaterialConfig& configuration);
TerrainMacroMaterialComponent() = default;
~TerrainMacroMaterialComponent() = default;
//////////////////////////////////////////////////////////////////////////
// AZ::Component interface implementation
void Activate() override;
void Deactivate() override;
bool ReadInConfig(const AZ::ComponentConfig* baseConfig) override;
bool WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const override;
void GetTerrainMacroMaterialData(AZ::Data::Instance<AZ::RPI::Material>& macroMaterial, AZ::Aabb& macroMaterialRegion) override;
private:
////////////////////////////////////////////////////////////////////////
// ShapeComponentNotificationsBus
void OnShapeChanged(ShapeComponentNotifications::ShapeChangeReasons reasons) override;
//////////////////////////////////////////////////////////////////////////
// AZ::Data::AssetBus::Handler
void OnAssetReady(AZ::Data::Asset<AZ::Data::AssetData> asset) override;
void OnAssetReloaded(AZ::Data::Asset<AZ::Data::AssetData> asset) override;
void HandleMaterialStateChange();
TerrainMacroMaterialConfig m_configuration;
AZ::Aabb m_cachedShapeBounds;
AZ::Data::Instance<AZ::RPI::Material> m_macroMaterialInstance;
bool m_macroMaterialActive{ false };
};
}

@ -0,0 +1,52 @@
/*
* 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 <TerrainRenderer/EditorComponents/EditorTerrainMacroMaterialComponent.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzToolsFramework/AssetBrowser/Entries/AssetBrowserEntry.h>
namespace Terrain
{
void EditorTerrainMacroMaterialComponent::Reflect(AZ::ReflectContext* context)
{
BaseClassType::ReflectSubClass<EditorTerrainMacroMaterialComponent, BaseClassType>(
context, 1,
&LmbrCentral::EditorWrappedComponentBaseVersionConverter<typename BaseClassType::WrappedComponentType,
typename BaseClassType::WrappedConfigType, 1>
);
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
if (serializeContext)
{
AZ::EditContext* editContext = serializeContext->GetEditContext();
// The edit context for TerrainMacroMaterialConfig is specified here to make it easier to add custom filtering to the
// asset picker for the material asset so that we can eventually only display materials that inherit from the proper
// material type.
if (editContext)
{
editContext
->Class<TerrainMacroMaterialConfig>(
"Terrain Macro Material Component", "Provide a terrain macro material for a region of the world")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->DataElement(
AZ::Edit::UIHandlers::Default, &TerrainMacroMaterialConfig::m_materialAsset, "Macro Material",
"Terrain macro material for use by any terrain inside the bounding box on this entity.")
// This is disabled until ChangeValidate can support the Asset<T> type. :(
//->Attribute(AZ::Edit::Attributes::ChangeValidate, &TerrainMacroMaterialConfig::ValidateMaterialAsset)
;
}
}
}
}

@ -0,0 +1,32 @@
/*
* 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
*
*/
#pragma once
#include <TerrainRenderer/Components/TerrainMacroMaterialComponent.h>
#include <AzToolsFramework/ToolsComponents/EditorComponentBase.h>
#include <LmbrCentral/Component/EditorWrappedComponentBase.h>
namespace Terrain
{
class EditorTerrainMacroMaterialComponent
: public LmbrCentral::EditorWrappedComponentBase<TerrainMacroMaterialComponent, TerrainMacroMaterialConfig>
{
public:
using BaseClassType = LmbrCentral::EditorWrappedComponentBase<TerrainMacroMaterialComponent, TerrainMacroMaterialConfig>;
AZ_EDITOR_COMPONENT(EditorTerrainMacroMaterialComponent, "{24D87D5F-6845-4F1F-81DC-05B4CEBA3EF4}", BaseClassType);
static void Reflect(AZ::ReflectContext* context);
static constexpr const char* const s_categoryName = "Terrain";
static constexpr const char* const s_componentName = "Terrain Macro Material";
static constexpr const char* const s_componentDescription = "Provides a macro material for a region to the terrain renderer";
static constexpr const char* const s_icon = "Editor/Icons/Components/TerrainLayerRenderer.svg";
static constexpr const char* const s_viewportIcon = "Editor/Icons/Components/Viewport/TerrainLayerRenderer.svg";
static constexpr const char* const s_helpUrl = "";
};
}

@ -0,0 +1,78 @@
/*
* 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
*
*/
#pragma once
#include <AzCore/Component/ComponentBus.h>
#include <AzCore/EBus/EBus.h>
#include <AzCore/Math/Vector2.h>
#include <AzCore/Math/Aabb.h>
#include <Atom/RPI.Public/Material/Material.h>
namespace Terrain
{
/**
* Request terrain macro material data.
*/
class TerrainMacroMaterialRequests
: public AZ::ComponentBus
{
public:
////////////////////////////////////////////////////////////////////////
// EBusTraits
using MutexType = AZStd::recursive_mutex;
////////////////////////////////////////////////////////////////////////
virtual ~TerrainMacroMaterialRequests() = default;
// Get the terrain macro material and the region that it covers.
virtual void GetTerrainMacroMaterialData(AZ::Data::Instance<AZ::RPI::Material>& macroMaterial, AZ::Aabb& macroMaterialRegion) = 0;
};
using TerrainMacroMaterialRequestBus = AZ::EBus<TerrainMacroMaterialRequests>;
/**
* Notifications for when the terrain macro material data changes.
*/
class TerrainMacroMaterialNotifications : public AZ::EBusTraits
{
public:
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
//////////////////////////////////////////////////////////////////////////
virtual void OnTerrainMacroMaterialCreated(
[[maybe_unused]] AZ::EntityId macroMaterialEntity,
[[maybe_unused]] AZ::Data::Instance<AZ::RPI::Material> macroMaterial,
[[maybe_unused]] const AZ::Aabb& macroMaterialRegion)
{
}
virtual void OnTerrainMacroMaterialChanged(
[[maybe_unused]] AZ::EntityId macroMaterialEntity,
[[maybe_unused]] AZ::Data::Instance<AZ::RPI::Material> macroMaterial)
{
}
virtual void OnTerrainMacroMaterialRegionChanged(
[[maybe_unused]] AZ::EntityId macroMaterialEntity,
[[maybe_unused]] const AZ::Aabb& oldRegion,
[[maybe_unused]] const AZ::Aabb& newRegion)
{
}
virtual void OnTerrainMacroMaterialDestroyed([[maybe_unused]] AZ::EntityId macroMaterialEntity)
{
}
};
using TerrainMacroMaterialNotificationBus = AZ::EBus<TerrainMacroMaterialNotifications>;
}

@ -25,4 +25,6 @@ set(FILES
Source/EditorTerrainModule.h
Source/TerrainModule.cpp
Source/TerrainModule.h
Source/TerrainRenderer/EditorComponents/EditorTerrainMacroMaterialComponent.cpp
Source/TerrainRenderer/EditorComponents/EditorTerrainMacroMaterialComponent.h
)

@ -24,8 +24,11 @@ set(FILES
Source/Components/TerrainWorldDebuggerComponent.h
Source/Components/TerrainWorldRendererComponent.cpp
Source/Components/TerrainWorldRendererComponent.h
Source/TerrainRenderer/Components/TerrainMacroMaterialComponent.cpp
Source/TerrainRenderer/Components/TerrainMacroMaterialComponent.h
Source/TerrainRenderer/TerrainFeatureProcessor.cpp
Source/TerrainRenderer/TerrainFeatureProcessor.h
Source/TerrainRenderer/TerrainMacroMaterialBus.h
Source/TerrainSystem/TerrainSystem.cpp
Source/TerrainSystem/TerrainSystem.h
Source/TerrainSystem/TerrainSystemBus.h

Loading…
Cancel
Save