Files
o3de/Gems/Terrain/Code/Source/Components/TerrainWorldComponent.cpp
T
Mike Balfour 40f41689ee Initial Terrain System (#3401)
This represents the very beginnings of the Terrain System presented in Sig-Content RFC 4 ( https://github.com/o3de/sig-content/blob/main/rfcs/rfc-4-terrain-system.md ). There is some basic working functionality in this PR, but the system as a whole should not be considered working yet. The gem is disabled by default in all projects.

All of the code below is contained in the Terrain Gem, which is disabled by default. The following components exist and can be experimented with, but should not be expected to be functionally complete yet:

Terrain World - level component for enabling terrain
Terrain World Debugger - level component for enabling terrain debugging features
Terrain Layer Spawner - component for defining a region of terrain
Terrain Height Gradient List - component for defining a list of gradients to use as terrain heights

Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com>
2021-08-24 13:29:50 -05:00

124 lines
4.8 KiB
C++

/*
* 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 <Components/TerrainWorldComponent.h>
#include <AzCore/Asset/AssetManagerBus.h>
#include <AzCore/Component/Entity.h>
#include <AzCore/Asset/AssetManager.h>
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/SerializeContext.h>
namespace Terrain
{
void TerrainWorldConfig::Reflect(AZ::ReflectContext* context)
{
AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context);
if (serialize)
{
serialize->Class<TerrainWorldConfig, AZ::ComponentConfig>()
->Version(1)
->Field("WorldMin", &TerrainWorldConfig::m_worldMin)
->Field("WorldMax", &TerrainWorldConfig::m_worldMax)
->Field("HeightQueryResolution", &TerrainWorldConfig::m_heightQueryResolution)
;
AZ::EditContext* edit = serialize->GetEditContext();
if (edit)
{
edit->Class<TerrainWorldConfig>(
"Terrain World Component", "Data required for the terrain system to run")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZStd::vector<AZ::Crc32>({ AZ_CRC_CE("Level") }))
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->DataElement(AZ::Edit::UIHandlers::Default, &TerrainWorldConfig::m_worldMin, "World Bounds (Min)", "")
->DataElement(AZ::Edit::UIHandlers::Default, &TerrainWorldConfig::m_worldMax, "World Bounds (Max)", "")
->DataElement(AZ::Edit::UIHandlers::Default, &TerrainWorldConfig::m_heightQueryResolution, "Height Query Resolution (m)", "")
;
}
}
}
void TerrainWorldComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services)
{
services.push_back(AZ_CRC_CE("TerrainService"));
}
void TerrainWorldComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services)
{
services.push_back(AZ_CRC_CE("TerrainService"));
}
void TerrainWorldComponent::GetRequiredServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& services)
{
}
void TerrainWorldComponent::Reflect(AZ::ReflectContext* context)
{
TerrainWorldConfig::Reflect(context);
AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context);
if (serialize)
{
serialize->Class<TerrainWorldComponent, AZ::Component>()
->Version(0)
->Field("Configuration", &TerrainWorldComponent::m_configuration)
;
}
}
TerrainWorldComponent::TerrainWorldComponent(const TerrainWorldConfig& configuration)
: m_configuration(configuration)
{
}
TerrainWorldComponent::~TerrainWorldComponent()
{
}
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::SetHeightQueryResolution, m_configuration.m_heightQueryResolution);
// Currently, the Terrain System Component owns the Terrain System instance because the Terrain World component gets recreated
// every time an entity is added or removed to a level. If this ever changes, the Terrain System ownership could move into
// the level component.
TerrainSystemServiceRequestBus::Broadcast(&TerrainSystemServiceRequestBus::Events::Activate);
}
void TerrainWorldComponent::Deactivate()
{
TerrainSystemServiceRequestBus::Broadcast(&TerrainSystemServiceRequestBus::Events::Deactivate);
}
bool TerrainWorldComponent::ReadInConfig(const AZ::ComponentConfig* baseConfig)
{
if (auto config = azrtti_cast<const TerrainWorldConfig*>(baseConfig))
{
m_configuration = *config;
return true;
}
return false;
}
bool TerrainWorldComponent::WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const
{
if (auto config = azrtti_cast<TerrainWorldConfig*>(outBaseConfig))
{
*config = m_configuration;
return true;
}
return false;
}
}