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:
@@ -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.
|
||||
|
||||
@@ -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
|
||||
+22
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user