Terrain/sphrose/surface gradient list component (#4409)

* cherry-pick conflict fix

Signed-off-by: sphrose <82213493+sphrose@users.noreply.github.com>

* Missed include file

Signed-off-by: sphrose <82213493+sphrose@users.noreply.github.com>

* review changes.

Signed-off-by: sphrose <82213493+sphrose@users.noreply.github.com>

* cherry-pick merge fix

Signed-off-by: sphrose <82213493+sphrose@users.noreply.github.com>

* review changes.

Signed-off-by: sphrose <82213493+sphrose@users.noreply.github.com>

* bug fix

Signed-off-by: sphrose <82213493+sphrose@users.noreply.github.com>

* review changes.

Signed-off-by: sphrose <82213493+sphrose@users.noreply.github.com>

* compile fix

Signed-off-by: sphrose <82213493+sphrose@users.noreply.github.com>

* compile fix

Signed-off-by: sphrose <82213493+sphrose@users.noreply.github.com>
This commit is contained in:
sphrose
2021-10-05 17:53:05 +01:00
committed by GitHub
parent 36eac35bc3
commit 4a4c93f866
15 changed files with 567 additions and 26 deletions
@@ -8,6 +8,7 @@
#pragma once
#include <AzCore/EBus/EBus.h>
#include <AzCore/std/containers/set.h>
#include <AzCore/Math/Vector2.h>
#include <AzCore/Math/Vector3.h>
#include <AzCore/Math/Aabb.h>
@@ -17,16 +18,38 @@ namespace AzFramework
{
namespace SurfaceData
{
namespace Constants
{
static const char* s_unassignedTagName = "(unassigned)";
}
struct SurfaceTagWeight
{
AZ_TYPE_INFO(SurfaceTagWeight, "{EA14018E-E853-4BF5-8E13-D83BB99A54CC}");
AZ::Crc32 m_surfaceType;
float m_weight; //! A Value in the range [0.0f .. 1.0f]
AZ::Crc32 m_surfaceType = AZ::Crc32(Constants::s_unassignedTagName);
float m_weight = 0.0f; //! A Value in the range [0.0f .. 1.0f]
//! Don't call this directly. TerrainDataRequests::Reflect is doing it already.
static void Reflect(AZ::ReflectContext* context);
};
struct SurfaceTagWeightComparator
{
bool operator()(const SurfaceTagWeight& tagWeight1, const SurfaceTagWeight& tagWeight2) const
{
if (!AZ::IsClose(tagWeight1.m_weight, tagWeight2.m_weight))
{
return tagWeight1.m_weight > tagWeight2.m_weight;
}
else
{
return tagWeight1.m_surfaceType > tagWeight2.m_surfaceType;
}
}
};
using OrderedSurfaceTagWeightSet = AZStd::set<SurfaceTagWeight, SurfaceTagWeightComparator>;
} //namespace SurfaceData
namespace Terrain
@@ -75,8 +98,28 @@ namespace AzFramework
//! @terrainExists: Can be nullptr. If != nullptr then, if there's no terrain at location x,y or location x,y is inside a terrain HOLE then *terrainExistsPtr will be set to false,
//! otherwise *terrainExistsPtr will be set to true.
virtual SurfaceData::SurfaceTagWeight GetMaxSurfaceWeight(AZ::Vector3 position, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0;
virtual SurfaceData::SurfaceTagWeight GetMaxSurfaceWeightFromVector2(const AZ::Vector2& inPosition, Sampler sampleFilter = Sampler::DEFAULT, bool* terrainExistsPtr = nullptr) const = 0;
virtual SurfaceData::SurfaceTagWeight GetMaxSurfaceWeightFromFloats(float x, float y, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0;
//! Given an XY coordinate, return the set of surface types and weights. The Vector3 input position version is defined to ignore
//! the input Z value.
virtual void GetSurfaceWeights(
const AZ::Vector3& inPosition,
SurfaceData::OrderedSurfaceTagWeightSet& outSurfaceWeights,
Sampler sampleFilter = Sampler::DEFAULT,
bool* terrainExistsPtr = nullptr) const = 0;
virtual void GetSurfaceWeightsFromVector2(
const AZ::Vector2& inPosition,
SurfaceData::OrderedSurfaceTagWeightSet& outSurfaceWeights,
Sampler sampleFilter = Sampler::DEFAULT,
bool* terrainExistsPtr = nullptr) const = 0;
virtual void GetSurfaceWeightsFromFloats(
float x,
float y,
SurfaceData::OrderedSurfaceTagWeightSet& outSurfaceWeights,
Sampler sampleFilter = Sampler::DEFAULT,
bool* terrainExistsPtr = nullptr) const = 0;
//! Convenience function for low level systems that can't do a reverse lookup from Crc to string. Everyone else should use GetMaxSurfaceWeight or GetMaxSurfaceWeightFromFloats.
//! Not available in the behavior context.
//! Returns nullptr if the position is inside a hole or outside of the terrain boundaries.
+4
View File
@@ -115,7 +115,11 @@ namespace PhysX
}
float GetHeightFromFloats(float, float, Sampler, bool*) const override { return {}; }
AzFramework::SurfaceData::SurfaceTagWeight GetMaxSurfaceWeight(AZ::Vector3, Sampler, bool*) const override { return {}; }
AzFramework::SurfaceData::SurfaceTagWeight GetMaxSurfaceWeightFromVector2(const AZ::Vector2&, Sampler, bool*) const override { return {}; }
AzFramework::SurfaceData::SurfaceTagWeight GetMaxSurfaceWeightFromFloats(float, float, Sampler, bool*) const override { return {}; }
void GetSurfaceWeights(const AZ::Vector3&, AzFramework::SurfaceData::OrderedSurfaceTagWeightSet&, Sampler, bool*) const override {}
void GetSurfaceWeightsFromVector2(const AZ::Vector2&, AzFramework::SurfaceData::OrderedSurfaceTagWeightSet&, Sampler, bool*) const override{};
void GetSurfaceWeightsFromFloats(float, float, AzFramework::SurfaceData::OrderedSurfaceTagWeightSet&, Sampler, bool*) const override {}
const char* GetMaxSurfaceName(AZ::Vector3, Sampler, bool*) const override { return {}; }
bool GetIsHoleFromFloats(float, float, Sampler) const override { return {}; }
AZ::Vector3 GetNormal(AZ::Vector3, Sampler, bool*) const override { return {}; }
@@ -9,12 +9,13 @@
#pragma once
#include <AzCore/Math/Crc.h>
#include <AzFramework/Terrain/TerrainDataRequestBus.h>
namespace SurfaceData
{
namespace Constants
{
static const char* s_unassignedTagName = "(unassigned)";
static const char* s_unassignedTagName = AzFramework::SurfaceData::Constants::s_unassignedTagName;
static const char* s_terrainHoleTagName = "terrainHole";
static const char* s_terrainTagName = "terrain";
@@ -0,0 +1,35 @@
/*
* 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 <SurfaceData/SurfaceDataTypes.h>
namespace Terrain
{
//! This bus provides retrieval of information from Terrain Surfaces.
class TerrainAreaSurfaceRequests
: public AZ::ComponentBus
{
public:
////////////////////////////////////////////////////////////////////////
// EBusTraits
using MutexType = AZStd::recursive_mutex;
////////////////////////////////////////////////////////////////////////
virtual ~TerrainAreaSurfaceRequests() = default;
//! Get the surfaces and weights from a gradient at a given position sorted into descending order of weight.
virtual void GetSurfaceWeights(const AZ::Vector3& inPosition, AzFramework::SurfaceData::OrderedSurfaceTagWeightSet& outSurfaceWeights) const = 0;
};
using TerrainAreaSurfaceRequestBus = AZ::EBus<TerrainAreaSurfaceRequests>;
} // namespace Terrain
@@ -0,0 +1,34 @@
/*
* 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 <SurfaceData/SurfaceDataTypes.h>
namespace Terrain
{
//! This bus provides retrieval of information from Terrain Surfaces.
class TerrainAreaSurfaceRequests
: public AZ::ComponentBus
{
public:
////////////////////////////////////////////////////////////////////////
// EBusTraits
using MutexType = AZStd::recursive_mutex;
////////////////////////////////////////////////////////////////////////
virtual ~TerrainAreaSurfaceRequests() = default;
virtual void GetSurfaceWeights(const AZ::Vector3& inPosition, SurfaceData::SurfaceTagWeightMap& surfaceWeights) const = 0;
};
using TerrainAreaSurfaceRequestBus = AZ::EBus<TerrainAreaSurfaceRequests>;
} // namespace Terrain
@@ -0,0 +1,157 @@
/*
* 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/TerrainSurfaceGradientListComponent.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <GradientSignal/Ebuses/GradientRequestBus.h>
namespace Terrain
{
void TerrainSurfaceGradientMapping::Reflect(AZ::ReflectContext* context)
{
if (auto serialize = azrtti_cast<AZ::SerializeContext*>(context))
{
serialize->Class<TerrainSurfaceGradientMapping>()
->Version(1)
->Field("Gradient Entity", &TerrainSurfaceGradientMapping::m_gradientEntityId)
->Field("Surface Tag", &TerrainSurfaceGradientMapping::m_surfaceTag)
;
if (auto edit = serialize->GetEditContext())
{
edit->Class<TerrainSurfaceGradientMapping>("Terrain Surface Gradient Mapping", "Mapping between a gradient and a surface.")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::Show)
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->DataElement(
AZ::Edit::UIHandlers::Default, &TerrainSurfaceGradientMapping::m_gradientEntityId, "Gradient Entity", "ID of Entity providing a gradient.")
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::AttributesAndValues)
->UIElement("GradientPreviewer", "Previewer")
->Attribute(AZ::Edit::Attributes::NameLabelOverride, "")
->Attribute(AZ_CRC_CE("GradientEntity"), &TerrainSurfaceGradientMapping::m_gradientEntityId)
->DataElement(
AZ::Edit::UIHandlers::Default, &TerrainSurfaceGradientMapping::m_surfaceTag, "Surface Tag",
"Surface type to map to this gradient.")
;
}
}
}
void TerrainSurfaceGradientListConfig::Reflect(AZ::ReflectContext* context)
{
TerrainSurfaceGradientMapping::Reflect(context);
AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context);
if (serialize)
{
serialize->Class<TerrainSurfaceGradientListConfig, AZ::ComponentConfig>()
->Version(1)
->Field("Mappings", &TerrainSurfaceGradientListConfig::m_gradientSurfaceMappings)
;
AZ::EditContext* edit = serialize->GetEditContext();
if (edit)
{
edit->Class<TerrainSurfaceGradientListConfig>(
"Terrain Surface Gradient List Component", "Provide mapping between gradients and surfaces.")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::Show)
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->DataElement(
AZ::Edit::UIHandlers::Default, &TerrainSurfaceGradientListConfig::m_gradientSurfaceMappings, "Gradient to Surface Mappings", "Maps Gradient Entities to Surfaces.")
;
}
}
}
void TerrainSurfaceGradientListComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services)
{
services.push_back(AZ_CRC_CE("TerrainSurfaceProviderService"));
}
void TerrainSurfaceGradientListComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services)
{
services.push_back(AZ_CRC_CE("TerrainSurfaceProviderService"));
}
void TerrainSurfaceGradientListComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& services)
{
services.push_back(AZ_CRC("TerrainAreaService"));
}
void TerrainSurfaceGradientListComponent::Reflect(AZ::ReflectContext* context)
{
TerrainSurfaceGradientListConfig::Reflect(context);
AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context);
if (serialize)
{
serialize->Class<TerrainSurfaceGradientListComponent, AZ::Component>()
->Version(0)->Field("Configuration", &TerrainSurfaceGradientListComponent::m_configuration)
;
}
}
TerrainSurfaceGradientListComponent::TerrainSurfaceGradientListComponent(const TerrainSurfaceGradientListConfig& configuration)
: m_configuration(configuration)
{
}
void TerrainSurfaceGradientListComponent::Activate()
{
Terrain::TerrainAreaSurfaceRequestBus::Handler::BusConnect(GetEntityId());
}
void TerrainSurfaceGradientListComponent::Deactivate()
{
Terrain::TerrainAreaSurfaceRequestBus::Handler::BusDisconnect();
}
bool TerrainSurfaceGradientListComponent::ReadInConfig(const AZ::ComponentConfig* baseConfig)
{
if (auto config = azrtti_cast<const TerrainSurfaceGradientListConfig*>(baseConfig))
{
m_configuration = *config;
return true;
}
return false;
}
bool TerrainSurfaceGradientListComponent::WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const
{
if (auto config = azrtti_cast<TerrainSurfaceGradientListConfig*>(outBaseConfig))
{
*config = m_configuration;
return true;
}
return false;
}
void TerrainSurfaceGradientListComponent::GetSurfaceWeights(const AZ::Vector3& inPosition, AzFramework::SurfaceData::OrderedSurfaceTagWeightSet& outSurfaceWeights) const
{
outSurfaceWeights.clear();
const GradientSignal::GradientSampleParams params(AZ::Vector3(inPosition.GetX(), inPosition.GetY(), 0.0f));
for (const auto& mapping : m_configuration.m_gradientSurfaceMappings)
{
float weight = 0.0f;
GradientSignal::GradientRequestBus::EventResult(weight, mapping.m_gradientEntityId, &GradientSignal::GradientRequestBus::Events::GetValue, params);
AzFramework::SurfaceData::SurfaceTagWeight tagWeight;
tagWeight.m_surfaceType = mapping.m_surfaceTag;
tagWeight.m_weight = weight;
outSurfaceWeights.emplace(tagWeight);
}
}
} // namespace Terrain
@@ -0,0 +1,77 @@
/*
* 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 <AzFramework/Terrain/TerrainDataRequestBus.h>
#include <SurfaceData/SurfaceDataTypes.h>
#include <Terrain/Ebuses/TerrainAreaSurfaceRequestBus.h>
namespace LmbrCentral
{
template<typename, typename>
class EditorWrappedComponentBase;
}
namespace Terrain
{
class TerrainSurfaceGradientMapping final
{
public:
AZ_CLASS_ALLOCATOR(TerrainSurfaceGradientMapping, AZ::SystemAllocator, 0);
AZ_RTTI(TerrainSurfaceGradientMapping, "{473AD2CE-F22A-45A9-803F-2192F3D9F2BF}");
static void Reflect(AZ::ReflectContext* context);
AZ::EntityId m_gradientEntityId;
SurfaceData::SurfaceTag m_surfaceTag;
};
class TerrainSurfaceGradientListConfig : public AZ::ComponentConfig
{
public:
AZ_CLASS_ALLOCATOR(TerrainSurfaceGradientListConfig, AZ::SystemAllocator, 0);
AZ_RTTI(TerrainSurfaceGradientListConfig, "{E9B083AD-8D30-47DA-8F8E-AA089BFA35E9}", AZ::ComponentConfig);
static void Reflect(AZ::ReflectContext* context);
AZStd::vector<Terrain::TerrainSurfaceGradientMapping> m_gradientSurfaceMappings;
};
class TerrainSurfaceGradientListComponent
: public AZ::Component
, public Terrain::TerrainAreaSurfaceRequestBus::Handler
{
public:
template<typename, typename>
friend class LmbrCentral::EditorWrappedComponentBase;
AZ_COMPONENT(TerrainSurfaceGradientListComponent, "{51F97C95-6B8A-4B06-B394-BD25BFCC8B7E}");
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);
TerrainSurfaceGradientListComponent(const TerrainSurfaceGradientListConfig& configuration);
TerrainSurfaceGradientListComponent() = default;
~TerrainSurfaceGradientListComponent() = 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;
// TerrainAreaSurfaceRequestBus
void GetSurfaceWeights(const AZ::Vector3& inPosition, AzFramework::SurfaceData::OrderedSurfaceTagWeightSet& outSurfaceWeights) const override;
private:
TerrainSurfaceGradientListConfig m_configuration;
};
} // namespace Terrain
@@ -0,0 +1,22 @@
/*
* 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 <EditorComponents/EditorTerrainSurfaceGradientListComponent.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/EditContext.h>
namespace Terrain
{
void EditorTerrainSurfaceGradientListComponent::Reflect(AZ::ReflectContext* context)
{
BaseClassType::ReflectSubClass<EditorTerrainSurfaceGradientListComponent, BaseClassType>(context, 1,
&LmbrCentral::EditorWrappedComponentBaseVersionConverter<typename BaseClassType::WrappedComponentType,
typename BaseClassType::WrappedConfigType, 1>
);
}
}
@@ -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 <Components/TerrainSurfaceGradientListComponent.h>
#include <AzToolsFramework/ToolsComponents/EditorComponentBase.h>
#include <LmbrCentral/Component/EditorWrappedComponentBase.h>
namespace Terrain
{
class EditorTerrainSurfaceGradientListComponent
: public LmbrCentral::EditorWrappedComponentBase<TerrainSurfaceGradientListComponent, TerrainSurfaceGradientListConfig>
{
public:
using BaseClassType = LmbrCentral::EditorWrappedComponentBase<TerrainSurfaceGradientListComponent, TerrainSurfaceGradientListConfig>;
AZ_EDITOR_COMPONENT(EditorTerrainSurfaceGradientListComponent, "{49831E91-A11F-4EFF-A824-6D85C284B934}", BaseClassType);
static void Reflect(AZ::ReflectContext* context);
static constexpr const char* const s_categoryName = "Terrain";
static constexpr const char* const s_componentName = "Terrain Surface Gradient List";
static constexpr const char* const s_componentDescription = "Provides a mapping between gradients and surface tags for use by the terrain system.";
static constexpr const char* const s_icon = "Editor/Icons/Components/TerrainLayerSpawner.svg";
static constexpr const char* const s_viewportIcon = "Editor/Icons/Components/Viewport/TerrainLayerSpawner.svg";
static constexpr const char* const s_helpUrl = "";
};
}
@@ -9,6 +9,7 @@
#include <EditorTerrainModule.h>
#include <EditorComponents/EditorTerrainHeightGradientListComponent.h>
#include <EditorComponents/EditorTerrainLayerSpawnerComponent.h>
#include <EditorComponents/EditorTerrainSurfaceGradientListComponent.h>
#include <EditorComponents/EditorTerrainSystemComponent.h>
#include <EditorComponents/EditorTerrainWorldComponent.h>
#include <EditorComponents/EditorTerrainWorldDebuggerComponent.h>
@@ -23,6 +24,7 @@ namespace Terrain
{
Terrain::EditorTerrainHeightGradientListComponent::CreateDescriptor(),
Terrain::EditorTerrainLayerSpawnerComponent::CreateDescriptor(),
Terrain::EditorTerrainSurfaceGradientListComponent::CreateDescriptor(),
Terrain::EditorTerrainSystemComponent::CreateDescriptor(),
Terrain::EditorTerrainWorldComponent::CreateDescriptor(),
Terrain::EditorTerrainWorldDebuggerComponent::CreateDescriptor(),
@@ -16,6 +16,7 @@
#include <Components/TerrainWorldRendererComponent.h>
#include <Components/TerrainHeightGradientListComponent.h>
#include <Components/TerrainLayerSpawnerComponent.h>
#include <Components/TerrainSurfaceGradientListComponent.h>
#include <Components/TerrainSurfaceDataSystemComponent.h>
namespace Terrain
@@ -30,6 +31,7 @@ namespace Terrain
TerrainWorldRendererComponent::CreateDescriptor(),
TerrainHeightGradientListComponent::CreateDescriptor(),
TerrainLayerSpawnerComponent::CreateDescriptor(),
TerrainSurfaceGradientListComponent::CreateDescriptor(),
TerrainSurfaceDataSystemComponent::CreateDescriptor(),
});
}
@@ -8,10 +8,17 @@
#include <TerrainSystem/TerrainSystem.h>
#include <AzCore/std/parallel/shared_mutex.h>
#include <AzCore/std/sort.h>
#include <SurfaceData/SurfaceDataTypes.h>
#include <SurfaceData/SurfaceDataSystemRequestBus.h>
#include <LmbrCentral/Shape/ShapeComponentBus.h>
#include <Atom/RPI.Public/Scene.h>
#include <Atom/RPI.Public/FeatureProcessorFactory.h>
#include <TerrainRenderer/TerrainFeatureProcessor.h>
#include <Terrain/Ebuses/TerrainAreaSurfaceRequestBus.h>
using namespace Terrain;
bool TerrainLayerPriorityComparator::operator()(const AZ::EntityId& layer1id, const AZ::EntityId& layer2id) const
@@ -201,6 +208,7 @@ float TerrainSystem::GetHeightSynchronous(float x, float y, Sampler sampler, boo
break;
}
// For now, always set terrainExists to true, as we don't have a way to author data for terrain holes yet.
if (terrainExistsPtr)
{
*terrainExistsPtr = terrainExists;
@@ -291,33 +299,134 @@ AZ::Vector3 TerrainSystem::GetNormalFromFloats(float x, float y, Sampler sampler
AzFramework::SurfaceData::SurfaceTagWeight TerrainSystem::GetMaxSurfaceWeight(
[[maybe_unused]] AZ::Vector3 position, [[maybe_unused]] Sampler sampleFilter, [[maybe_unused]] bool* terrainExistsPtr) const
const AZ::Vector3 position, Sampler sampleFilter, bool* terrainExistsPtr) const
{
if (terrainExistsPtr)
{
*terrainExistsPtr = true;
}
return GetMaxSurfaceWeightFromFloats(position.GetX(), position.GetY(), sampleFilter, terrainExistsPtr);
}
return AzFramework::SurfaceData::SurfaceTagWeight();
AzFramework::SurfaceData::SurfaceTagWeight TerrainSystem::GetMaxSurfaceWeightFromVector2(const AZ::Vector2& inPosition, Sampler sampleFilter, bool* terrainExistsPtr) const
{
return GetMaxSurfaceWeightFromFloats(inPosition.GetX(), inPosition.GetY(), sampleFilter, terrainExistsPtr);
}
AzFramework::SurfaceData::SurfaceTagWeight TerrainSystem::GetMaxSurfaceWeightFromFloats(
[[maybe_unused]] float x,
[[maybe_unused]] float y,
[[maybe_unused]] Sampler sampleFilter,
[[maybe_unused]] bool* terrainExistsPtr) const
const float x, const float y, Sampler sampleFilter, bool* terrainExistsPtr) const
{
if (terrainExistsPtr)
{
*terrainExistsPtr = true;
}
return AzFramework::SurfaceData::SurfaceTagWeight();
AzFramework::SurfaceData::OrderedSurfaceTagWeightSet weightSet;
GetOrderedSurfaceWeights(x, y, sampleFilter, weightSet, terrainExistsPtr);
if (weightSet.empty())
{
return {};
}
return *weightSet.begin();
}
const char* TerrainSystem::GetMaxSurfaceName(
[[maybe_unused]] AZ::Vector3 position, [[maybe_unused]] Sampler sampleFilter, [[maybe_unused]] bool* terrainExistsPtr) const
AZ::EntityId TerrainSystem::FindBestAreaEntityAtPosition(float x, float y, AZ::Aabb& bounds) const
{
AZ::Vector3 inPosition = AZ::Vector3(x, y, 0);
// Find the highest priority layer that encompasses this position
AZStd::shared_lock<AZStd::shared_mutex> lock(m_areaMutex);
// The areas are sorted into priority order: the first area that contains inPosition is the most suitable.
for (const auto& [areaId, areaBounds] : m_registeredAreas)
{
inPosition.SetZ(areaBounds.GetMin().GetZ());
if (areaBounds.Contains(inPosition))
{
bounds = areaBounds;
return areaId;
}
}
return AZ::EntityId();
}
void TerrainSystem::GetOrderedSurfaceWeights(
const float x,
const float y,
[[maybe_unused]] Sampler sampler,
AzFramework::SurfaceData::OrderedSurfaceTagWeightSet& outSurfaceWeights,
bool* terrainExistsPtr) const
{
AZ::Aabb bounds;
AZ::EntityId bestAreaId = FindBestAreaEntityAtPosition(x, y, bounds);
if (terrainExistsPtr)
{
GetHeightFromFloats(x, y, AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT, terrainExistsPtr);
}
outSurfaceWeights.clear();
if (!bestAreaId.IsValid())
{
return;
}
const AZ::Vector3 inPosition = AZ::Vector3(x, y, 0.0f);
// Get all the surfaces with weights at the given point.
Terrain::TerrainAreaSurfaceRequestBus::Event(
bestAreaId, &Terrain::TerrainAreaSurfaceRequestBus::Events::GetSurfaceWeights, inPosition, outSurfaceWeights);
}
void TerrainSystem::GetSurfaceWeights(
const AZ::Vector3& inPosition,
AzFramework::SurfaceData::OrderedSurfaceTagWeightSet& outSurfaceWeights,
Sampler sampleFilter,
bool* terrainExistsPtr) const
{
if (terrainExistsPtr)
{
*terrainExistsPtr = true;
}
GetOrderedSurfaceWeights(inPosition.GetX(), inPosition.GetY(), sampleFilter, outSurfaceWeights, terrainExistsPtr);
}
void TerrainSystem::GetSurfaceWeightsFromVector2(
const AZ::Vector2& inPosition,
AzFramework::SurfaceData::OrderedSurfaceTagWeightSet& outSurfaceWeights,
Sampler sampleFilter,
bool* terrainExistsPtr) const
{
// For now, always set terrainExists to true, as we don't have a way to author data for terrain holes yet.
if (terrainExistsPtr)
{
*terrainExistsPtr = true;
}
GetOrderedSurfaceWeights(inPosition.GetX(), inPosition.GetY(), sampleFilter, outSurfaceWeights, terrainExistsPtr);
}
void TerrainSystem::GetSurfaceWeightsFromFloats(
float x,
float y,
AzFramework::SurfaceData::OrderedSurfaceTagWeightSet& outSurfaceWeights,
Sampler sampleFilter,
bool* terrainExistsPtr) const
{
// For now, always set terrainExists to true, as we don't have a way to author data for terrain holes yet.
if (terrainExistsPtr)
{
*terrainExistsPtr = true;
}
GetOrderedSurfaceWeights(x, y, sampleFilter, outSurfaceWeights, terrainExistsPtr);
}
const char* TerrainSystem::GetMaxSurfaceName([[maybe_unused]] AZ::Vector3 position, [[maybe_unused]] Sampler sampleFilter, [[maybe_unused]] bool* terrainExistsPtr) const
{
// For now, always set terrainExists to true, as we don't have a way to author data for terrain holes yet.
if (terrainExistsPtr)
{
*terrainExistsPtr = true;
@@ -327,14 +436,6 @@ const char* TerrainSystem::GetMaxSurfaceName(
}
/*
void TerrainSystem::GetSurfaceWeights(
[[maybe_unused]] const AZ::Vector3& inPosition,
[[maybe_unused]] Sampler sampleFilter,
[[maybe_unused]] SurfaceData::SurfaceTagWeightMap& outSurfaceWeights)
{
// TODO: implement
}
void TerrainSystem::GetSurfacePoint(
const AZ::Vector3& inPosition, [[maybe_unused]] Sampler sampleFilter, SurfaceData::SurfacePoint& outSurfacePoint)
{
@@ -70,9 +70,28 @@ namespace Terrain
//! HOLE then *terrainExistsPtr will be set to false,
//! otherwise *terrainExistsPtr will be set to true.
AzFramework::SurfaceData::SurfaceTagWeight GetMaxSurfaceWeight(
AZ::Vector3 position, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const override;
const AZ::Vector3 position, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const override;
AzFramework::SurfaceData::SurfaceTagWeight GetMaxSurfaceWeightFromVector2(
const AZ::Vector2& inPosition, Sampler sampleFilter = Sampler::DEFAULT, bool* terrainExistsPtr = nullptr) const override;
AzFramework::SurfaceData::SurfaceTagWeight GetMaxSurfaceWeightFromFloats(
float x, float y, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const override;
const float x, const float y, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const override;
void GetSurfaceWeights(
const AZ::Vector3& inPosition,
AzFramework::SurfaceData::OrderedSurfaceTagWeightSet& outSurfaceWeights,
Sampler sampleFilter = Sampler::DEFAULT,
bool* terrainExistsPtr = nullptr) const override;
void GetSurfaceWeightsFromVector2(
const AZ::Vector2& inPosition,
AzFramework::SurfaceData::OrderedSurfaceTagWeightSet& outSurfaceWeights,
Sampler sampleFilter = Sampler::DEFAULT,
bool* terrainExistsPtr = nullptr) const override;
void GetSurfaceWeightsFromFloats(
float x,
float y,
AzFramework::SurfaceData::OrderedSurfaceTagWeightSet& outSurfaceWeights,
Sampler sampleFilter = Sampler::DEFAULT,
bool* terrainExistsPtr = nullptr) const override;
//! Convenience function for low level systems that can't do a reverse lookup from Crc to string. Everyone else should use
//! GetMaxSurfaceWeight or GetMaxSurfaceWeightFromFloats. Not available in the behavior context. Returns nullptr if the position is
@@ -96,6 +115,13 @@ namespace Terrain
private:
void ClampPosition(float x, float y, AZ::Vector2& outPosition, AZ::Vector2& normalizedDelta) const;
AZ::EntityId FindBestAreaEntityAtPosition(float x, float y, AZ::Aabb& bounds) const;
void GetOrderedSurfaceWeights(
const float x,
const float y,
Sampler sampler,
AzFramework::SurfaceData::OrderedSurfaceTagWeightSet& outSurfaceWeights,
bool* terrainExistsPtr) const;
float GetHeightSynchronous(float x, float y, Sampler sampler, bool* terrainExistsPtr) const;
float GetTerrainAreaHeight(float x, float y, bool& terrainExists) const;
AZ::Vector3 GetNormalSynchronous(float x, float y, Sampler sampler, bool* terrainExistsPtr) const;
@@ -11,6 +11,8 @@ set(FILES
Source/EditorComponents/EditorTerrainHeightGradientListComponent.h
Source/EditorComponents/EditorTerrainLayerSpawnerComponent.cpp
Source/EditorComponents/EditorTerrainLayerSpawnerComponent.h
Source/EditorComponents/EditorTerrainSurfaceGradientListComponent.cpp
Source/EditorComponents/EditorTerrainSurfaceGradientListComponent.h
Source/EditorComponents/EditorTerrainWorldComponent.cpp
Source/EditorComponents/EditorTerrainWorldComponent.h
Source/EditorComponents/EditorTerrainWorldDebuggerComponent.cpp
+3
View File
@@ -7,12 +7,15 @@
#
set(FILES
Include/Terrain/Ebuses/TerrainAreaSurfaceRequestBus.h
Source/Components/TerrainHeightGradientListComponent.cpp
Source/Components/TerrainHeightGradientListComponent.h
Source/Components/TerrainLayerSpawnerComponent.cpp
Source/Components/TerrainLayerSpawnerComponent.h
Source/Components/TerrainSurfaceDataSystemComponent.cpp
Source/Components/TerrainSurfaceDataSystemComponent.h
Source/Components/TerrainSurfaceGradientListComponent.cpp
Source/Components/TerrainSurfaceGradientListComponent.h
Source/Components/TerrainSystemComponent.cpp
Source/Components/TerrainSystemComponent.h
Source/Components/TerrainWorldComponent.cpp