Terrain API cleanups (#4914)
* Terrain API fixups Moved SurfaceData definitions in AzFramework out of terrain into separate files. Added some missing API calls: Get*FromVector2, GetSurfacePoint* Changed OrderedSurfaceTagWeightSet to SurfaceTagWeightList Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * PR feedback - remove IsClose check. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Fixed PhysX test compile failures by redcoding a bunch of "dummy terrain" implementation that's unused. It was originally added for the PhysX Terrain component, but that component is long gone and has been superceded by the more generic PhysX Heightfield Collider. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> * Fixed up failing terrain unit tests. Added API changes, and changed the assumption on where the surface weight sort is taking place. The component is no longer expected to provide the sorted list, it only needs to be sorted at the end coming out of the terrain system, so the unit tests have been modified to reflect that. Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com>
This commit is contained in:
@@ -58,6 +58,7 @@
|
||||
#include <AzFramework/Script/ScriptComponent.h>
|
||||
#include <AzFramework/Spawnable/SpawnableSystemComponent.h>
|
||||
#include <AzFramework/StreamingInstall/StreamingInstall.h>
|
||||
#include <AzFramework/SurfaceData/SurfaceData.h>
|
||||
#include <AzFramework/TargetManagement/TargetManagementComponent.h>
|
||||
#include <AzFramework/Viewport/CameraState.h>
|
||||
#include <AzFramework/Metrics/MetricsPlainTextNameRegistration.h>
|
||||
@@ -278,6 +279,8 @@ namespace AzFramework
|
||||
AzFramework::RemoteStorageDriveConfig::Reflect(context);
|
||||
|
||||
Physics::ReflectionUtils::ReflectPhysicsApi(context);
|
||||
AzFramework::SurfaceData::SurfaceTagWeight::Reflect(context);
|
||||
AzFramework::SurfaceData::SurfacePoint::Reflect(context);
|
||||
AzFramework::Terrain::TerrainDataRequests::Reflect(context);
|
||||
|
||||
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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 <AzFramework/SurfaceData/SurfaceData.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
|
||||
namespace AzFramework::SurfaceData
|
||||
{
|
||||
void SurfaceTagWeight::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<SurfaceTagWeight>()
|
||||
->Field("m_surfaceType", &SurfaceTagWeight::m_surfaceType)
|
||||
->Field("m_weight", &SurfaceTagWeight::m_weight)
|
||||
;
|
||||
}
|
||||
|
||||
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->Class<SurfaceTagWeight>()
|
||||
->Attribute(AZ::Script::Attributes::Category, "SurfaceData")
|
||||
->Constructor()
|
||||
->Property("surfaceType", BehaviorValueProperty(&SurfaceTagWeight::m_surfaceType))
|
||||
->Property("weight", BehaviorValueProperty(&SurfaceTagWeight::m_weight))
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
void SurfacePoint::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<SurfacePoint>()
|
||||
->Field("m_position", &SurfacePoint::m_position)
|
||||
->Field("m_normal", &SurfacePoint::m_normal)
|
||||
->Field("m_surfaceTags", &SurfacePoint::m_surfaceTags)
|
||||
;
|
||||
}
|
||||
|
||||
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->Class<SurfacePoint>("AzFramework::SurfaceData::SurfacePoint")
|
||||
->Attribute(AZ::Script::Attributes::Category, "SurfaceData")
|
||||
->Constructor()
|
||||
->Property("position", BehaviorValueProperty(&SurfacePoint::m_position))
|
||||
->Property("normal", BehaviorValueProperty(&SurfacePoint::m_normal))
|
||||
->Property("surfaceTags", BehaviorValueProperty(&SurfacePoint::m_surfaceTags))
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace AzFramework::SurfaceData
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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/Math/Crc.h>
|
||||
#include <AzCore/Math/Vector2.h>
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
|
||||
namespace AzFramework::SurfaceData
|
||||
{
|
||||
namespace Constants
|
||||
{
|
||||
static constexpr const char* s_unassignedTagName = "(unassigned)";
|
||||
}
|
||||
|
||||
struct SurfaceTagWeight
|
||||
{
|
||||
AZ_TYPE_INFO(SurfaceTagWeight, "{EA14018E-E853-4BF5-8E13-D83BB99A54CC}");
|
||||
SurfaceTagWeight() = default;
|
||||
SurfaceTagWeight(AZ::Crc32 surfaceType, float weight)
|
||||
: m_surfaceType(surfaceType)
|
||||
, m_weight(weight)
|
||||
{
|
||||
}
|
||||
|
||||
AZ::Crc32 m_surfaceType = AZ::Crc32(Constants::s_unassignedTagName);
|
||||
float m_weight = 0.0f; //! A Value in the range [0.0f .. 1.0f]
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
};
|
||||
|
||||
struct SurfaceTagWeightComparator
|
||||
{
|
||||
bool operator()(const SurfaceTagWeight& tagWeight1, const SurfaceTagWeight& tagWeight2) const
|
||||
{
|
||||
// Return a deterministic sort order for surface tags from highest to lowest weight, with the surface types sorted
|
||||
// in a predictable order when the weights are equal. The surface type sort order is meaningless since it is sorting CRC
|
||||
// values, it's really just important for it to be stable.
|
||||
// For the floating-point weight comparisons we use exact instead of IsClose value comparisons for a similar reason - we
|
||||
// care about being sorted highest to lowest, but there's no inherent meaning in sorting surface types with *similar* weights
|
||||
// together.
|
||||
|
||||
if (tagWeight1.m_weight != tagWeight2.m_weight)
|
||||
{
|
||||
return tagWeight1.m_weight > tagWeight2.m_weight;
|
||||
}
|
||||
else
|
||||
{
|
||||
return tagWeight1.m_surfaceType > tagWeight2.m_surfaceType;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
using SurfaceTagWeightList = AZStd::vector<SurfaceTagWeight>;
|
||||
|
||||
struct SurfacePoint final
|
||||
{
|
||||
AZ_TYPE_INFO(SurfacePoint, "{331A3D0E-BB1D-47BF-96A2-249FAA0D720D}");
|
||||
|
||||
AZ::Vector3 m_position;
|
||||
AZ::Vector3 m_normal;
|
||||
SurfaceTagWeightList m_surfaceTags;
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
};
|
||||
} // namespace AzFramework::SurfaceData
|
||||
@@ -8,56 +8,33 @@
|
||||
|
||||
#include "TerrainDataRequestBus.h"
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
|
||||
namespace AzFramework
|
||||
namespace AzFramework::Terrain
|
||||
{
|
||||
namespace SurfaceData
|
||||
void TerrainDataRequests::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
void SurfaceTagWeight::Reflect(AZ::ReflectContext* context)
|
||||
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
{
|
||||
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<SurfaceTagWeight>()
|
||||
->Field("m_surfaceType", &SurfaceTagWeight::m_surfaceType)
|
||||
->Field("m_weight", &SurfaceTagWeight::m_weight)
|
||||
;
|
||||
}
|
||||
|
||||
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->Class<SurfaceTagWeight>("SurfaceTagWeight")
|
||||
->Property("m_surfaceType", BehaviorValueProperty(&SurfaceTagWeight::m_surfaceType))
|
||||
->Property("m_weight", BehaviorValueProperty(&SurfaceTagWeight::m_weight))
|
||||
;
|
||||
}
|
||||
}
|
||||
} //namespace SurfaceData
|
||||
|
||||
namespace Terrain
|
||||
{
|
||||
void TerrainDataRequests::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
AzFramework::SurfaceData::SurfaceTagWeight::Reflect(context);
|
||||
|
||||
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->EBus<AzFramework::Terrain::TerrainDataRequestBus>("TerrainDataRequestBus")
|
||||
->Attribute(AZ::Script::Attributes::Category, "Terrain")
|
||||
->Event("GetHeight", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetHeight)
|
||||
->Event("GetHeightFromFloats", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetHeightFromFloats)
|
||||
->Event("GetMaxSurfaceWeight", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetMaxSurfaceWeight)
|
||||
->Event("GetMaxSurfaceWeightFromFloats", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetMaxSurfaceWeightFromFloats)
|
||||
->Event("GetIsHoleFromFloats", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetIsHoleFromFloats)
|
||||
->Event("GetNormal", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetNormal)
|
||||
->Event("GetNormalFromFloats", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetNormalFromFloats)
|
||||
->Event("GetTerrainAabb", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetTerrainAabb)
|
||||
->Event("GetTerrainHeightQueryResolution",
|
||||
&AzFramework::Terrain::TerrainDataRequestBus::Events::GetTerrainHeightQueryResolution)
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
behaviorContext->EBus<AzFramework::Terrain::TerrainDataRequestBus>("TerrainDataRequestBus")
|
||||
->Attribute(AZ::Script::Attributes::Category, "Terrain")
|
||||
->Event("GetHeight", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetHeight)
|
||||
->Event("GetNormal", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetNormal)
|
||||
->Event("GetMaxSurfaceWeight", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetMaxSurfaceWeight)
|
||||
->Event("GetMaxSurfaceWeightFromVector2",
|
||||
&AzFramework::Terrain::TerrainDataRequestBus::Events::GetMaxSurfaceWeightFromVector2)
|
||||
->Event("GetSurfaceWeights", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetSurfaceWeights)
|
||||
->Event("GetSurfaceWeightsFromVector2",
|
||||
&AzFramework::Terrain::TerrainDataRequestBus::Events::GetSurfaceWeightsFromVector2)
|
||||
->Event("GetIsHoleFromFloats", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetIsHoleFromFloats)
|
||||
->Event("GetSurfacePoint", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetSurfacePoint)
|
||||
->Event("GetSurfacePointFromVector2",
|
||||
&AzFramework::Terrain::TerrainDataRequestBus::Events::GetSurfacePointFromVector2)
|
||||
->Event("GetTerrainAabb", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetTerrainAabb)
|
||||
->Event("GetTerrainHeightQueryResolution",
|
||||
&AzFramework::Terrain::TerrainDataRequestBus::Events::GetTerrainHeightQueryResolution)
|
||||
;
|
||||
}
|
||||
|
||||
} //namespace Terrain
|
||||
} // namespace AzFramework
|
||||
}
|
||||
} // namespace AzFramework::Terrain
|
||||
|
||||
@@ -8,50 +8,13 @@
|
||||
#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>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzFramework/SurfaceData/SurfaceData.h>
|
||||
|
||||
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 = 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
|
||||
{
|
||||
|
||||
@@ -91,49 +54,82 @@ namespace AzFramework
|
||||
//! Returns terrains height in meters at location x,y.
|
||||
//! @terrainExistsPtr: 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 become false,
|
||||
//! otherwise *terrainExistsPtr will become true.
|
||||
virtual float GetHeight(AZ::Vector3 position, Sampler sampler = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0;
|
||||
virtual float GetHeightFromFloats(float x, float y, Sampler sampler = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0;
|
||||
virtual float GetHeight(const AZ::Vector3& position, Sampler sampler = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0;
|
||||
virtual float GetHeightFromVector2(
|
||||
const AZ::Vector2& position, Sampler sampler = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0;
|
||||
virtual float GetHeightFromFloats(
|
||||
float x, float y, Sampler sampler = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0;
|
||||
|
||||
//! Returns true if there's a hole at location x,y.
|
||||
//! Also returns true if there's no terrain data at location x,y.
|
||||
virtual bool GetIsHole(const AZ::Vector3& position, Sampler sampleFilter = Sampler::BILINEAR) const = 0;
|
||||
virtual bool GetIsHoleFromVector2(const AZ::Vector2& position, Sampler sampleFilter = Sampler::BILINEAR) const = 0;
|
||||
virtual bool GetIsHoleFromFloats(float x, float y, Sampler sampleFilter = Sampler::BILINEAR) const = 0;
|
||||
|
||||
// Given an XY coordinate, return the surface normal.
|
||||
//! @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 AZ::Vector3 GetNormal(
|
||||
const AZ::Vector3& position, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0;
|
||||
virtual AZ::Vector3 GetNormalFromVector2(
|
||||
const AZ::Vector2& position, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0;
|
||||
virtual AZ::Vector3 GetNormalFromFloats(
|
||||
float x, float y, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0;
|
||||
|
||||
//! Given an XY coordinate, return the max surface type and weight.
|
||||
//! @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;
|
||||
virtual SurfaceData::SurfaceTagWeight GetMaxSurfaceWeight(
|
||||
const 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,
|
||||
SurfaceData::SurfaceTagWeightList& outSurfaceWeights,
|
||||
Sampler sampleFilter = Sampler::DEFAULT,
|
||||
bool* terrainExistsPtr = nullptr) const = 0;
|
||||
virtual void GetSurfaceWeightsFromVector2(
|
||||
const AZ::Vector2& inPosition,
|
||||
SurfaceData::OrderedSurfaceTagWeightSet& outSurfaceWeights,
|
||||
SurfaceData::SurfaceTagWeightList& outSurfaceWeights,
|
||||
Sampler sampleFilter = Sampler::DEFAULT,
|
||||
bool* terrainExistsPtr = nullptr) const = 0;
|
||||
virtual void GetSurfaceWeightsFromFloats(
|
||||
float x,
|
||||
float y,
|
||||
SurfaceData::OrderedSurfaceTagWeightSet& outSurfaceWeights,
|
||||
SurfaceData::SurfaceTagWeightList& 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.
|
||||
virtual const char * GetMaxSurfaceName(AZ::Vector3 position, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0;
|
||||
virtual const char* GetMaxSurfaceName(
|
||||
const AZ::Vector3& position, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0;
|
||||
|
||||
//! Returns true if there's a hole at location x,y.
|
||||
//! Also returns true if there's no terrain data at location x,y.
|
||||
virtual bool GetIsHoleFromFloats(float x, float y, Sampler sampleFilter = Sampler::BILINEAR) const = 0;
|
||||
|
||||
// Given an XY coordinate, return the surface normal.
|
||||
//! @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 AZ::Vector3 GetNormal(AZ::Vector3 position, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0;
|
||||
virtual AZ::Vector3 GetNormalFromFloats(float x, float y, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0;
|
||||
//! Given an XY coordinate, return all terrain information at that location. The Vector3 input position version is defined
|
||||
//! to ignore the input Z value.
|
||||
virtual void GetSurfacePoint(
|
||||
const AZ::Vector3& inPosition,
|
||||
SurfaceData::SurfacePoint& outSurfacePoint,
|
||||
Sampler sampleFilter = Sampler::DEFAULT,
|
||||
bool* terrainExistsPtr = nullptr) const = 0;
|
||||
virtual void GetSurfacePointFromVector2(
|
||||
const AZ::Vector2& inPosition,
|
||||
SurfaceData::SurfacePoint& outSurfacePoint,
|
||||
Sampler sampleFilter = Sampler::DEFAULT,
|
||||
bool* terrainExistsPtr = nullptr) const = 0;
|
||||
virtual void GetSurfacePointFromFloats(
|
||||
float x,
|
||||
float y,
|
||||
SurfaceData::SurfacePoint& outSurfacePoint,
|
||||
Sampler sampleFilter = Sampler::DEFAULT,
|
||||
bool* terrainExistsPtr = nullptr) const = 0;
|
||||
};
|
||||
using TerrainDataRequestBus = AZ::EBus<TerrainDataRequests>;
|
||||
|
||||
@@ -169,6 +165,10 @@ namespace AzFramework
|
||||
}
|
||||
};
|
||||
using TerrainDataNotificationBus = AZ::EBus<TerrainDataNotifications>;
|
||||
|
||||
} //namespace Terrain
|
||||
} // namespace Terrain
|
||||
} // namespace AzFramework
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
AZ_TYPE_INFO_SPECIALIZE(AzFramework::Terrain::TerrainDataRequests::Sampler, "{D29BB6D7-3006-4114-858D-355EAA256B86}");
|
||||
} // namespace AZ
|
||||
|
||||
@@ -301,6 +301,8 @@ set(FILES
|
||||
Spawnable/SpawnableMonitor.cpp
|
||||
Spawnable/SpawnableSystemComponent.h
|
||||
Spawnable/SpawnableSystemComponent.cpp
|
||||
SurfaceData/SurfaceData.h
|
||||
SurfaceData/SurfaceData.cpp
|
||||
Terrain/TerrainDataRequestBus.h
|
||||
Terrain/TerrainDataRequestBus.cpp
|
||||
Thermal/ThermalInfo.h
|
||||
|
||||
@@ -61,7 +61,6 @@ namespace PhysX::Benchmarks
|
||||
m_defaultScene = physicsSystem->GetScene(m_testSceneHandle);
|
||||
}
|
||||
|
||||
m_dummyTerrainComponentDescriptor = DummyTestTerrainComponent::CreateDescriptor();
|
||||
Physics::DefaultWorldBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
@@ -80,9 +79,6 @@ namespace PhysX::Benchmarks
|
||||
m_testSceneHandle = AzPhysics::InvalidSceneHandle;
|
||||
|
||||
TestUtils::ResetPhysXSystem();
|
||||
|
||||
m_dummyTerrainComponentDescriptor->ReleaseDescriptor();
|
||||
m_dummyTerrainComponentDescriptor = nullptr;
|
||||
}
|
||||
|
||||
AzPhysics::SceneHandle PhysXBaseBenchmarkFixture::CreateDefaultTestScene()
|
||||
|
||||
@@ -61,7 +61,6 @@ namespace PhysX::Benchmarks
|
||||
|
||||
AzPhysics::Scene* m_defaultScene = nullptr;
|
||||
AzPhysics::SceneHandle m_testSceneHandle = AzPhysics::InvalidSceneHandle;
|
||||
AZ::ComponentDescriptor* m_dummyTerrainComponentDescriptor = nullptr;
|
||||
};
|
||||
} // namespace PhysX::Benchmarks
|
||||
#endif //HAVE_BENCHMARK
|
||||
|
||||
@@ -52,14 +52,10 @@ namespace PhysXEditorTests
|
||||
m_defaultScene = physicsSystem->GetScene(m_defaultSceneHandle);
|
||||
}
|
||||
Physics::DefaultWorldBus::Handler::BusConnect();
|
||||
m_dummyTerrainComponentDescriptor = PhysX::DummyTestTerrainComponent::CreateDescriptor();
|
||||
}
|
||||
|
||||
void PhysXEditorFixture::TearDown()
|
||||
{
|
||||
m_dummyTerrainComponentDescriptor->ReleaseDescriptor();
|
||||
m_dummyTerrainComponentDescriptor = nullptr;
|
||||
|
||||
Physics::DefaultWorldBus::Handler::BusDisconnect();
|
||||
|
||||
// prevents warnings from the undo cache on subsequent tests
|
||||
|
||||
@@ -51,7 +51,6 @@ namespace PhysXEditorTests
|
||||
// DefaultWorldBus
|
||||
AzPhysics::SceneHandle GetDefaultSceneHandle() const override;
|
||||
|
||||
AZ::ComponentDescriptor* m_dummyTerrainComponentDescriptor = nullptr;
|
||||
AzPhysics::SceneHandle m_defaultSceneHandle = AzPhysics::InvalidSceneHandle;
|
||||
AzPhysics::Scene* m_defaultScene = nullptr;
|
||||
|
||||
|
||||
@@ -41,16 +41,12 @@ namespace PhysX
|
||||
}
|
||||
|
||||
Physics::DefaultWorldBus::Handler::BusConnect();
|
||||
|
||||
m_dummyTerrainComponentDescriptor = DummyTestTerrainComponent::CreateDescriptor();
|
||||
}
|
||||
|
||||
void PhysXDefaultWorldTest::TearDown()
|
||||
{
|
||||
Physics::DefaultWorldBus::Handler::BusDisconnect();
|
||||
m_defaultScene = nullptr;
|
||||
m_dummyTerrainComponentDescriptor->ReleaseDescriptor();
|
||||
m_dummyTerrainComponentDescriptor = nullptr;
|
||||
|
||||
//Clean up the Test scene
|
||||
if (auto* physicsSystem = AZ::Interface<AzPhysics::SystemInterface>::Get())
|
||||
|
||||
@@ -33,7 +33,6 @@ namespace PhysX
|
||||
// DefaultWorldBus
|
||||
AzPhysics::SceneHandle GetDefaultSceneHandle() const override;
|
||||
|
||||
AZ::ComponentDescriptor* m_dummyTerrainComponentDescriptor = nullptr;
|
||||
AzPhysics::Scene* m_defaultScene = nullptr;
|
||||
AzPhysics::SceneHandle m_testSceneHandle = AzPhysics::InvalidSceneHandle;
|
||||
};
|
||||
|
||||
@@ -63,68 +63,4 @@ namespace PhysX
|
||||
AzPhysics::SimulatedBodyEvents::OnTriggerExit::Handler m_onTriggerExitHandler;
|
||||
};
|
||||
|
||||
|
||||
//! Dummy component emulating presence of terrain by connecting to TerrainDataRequestBus
|
||||
//! PhysX Terrain Component skips activation if there's no terrain present,
|
||||
//! so in order to test it we also add the DummyTestTerrainComponent.
|
||||
class DummyTestTerrainComponent
|
||||
: public AZ::Component
|
||||
, private AzFramework::Terrain::TerrainDataRequestBus::Handler
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(DummyTestTerrainComponent, "{EE4ECA23-9C27-4D5D-9C6F-271A19C0333E}");
|
||||
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
|
||||
{
|
||||
provided.push_back(AZ_CRC_CE("TerrainService"));
|
||||
}
|
||||
|
||||
private:
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// AZ::Component interface implementation
|
||||
void Activate() override
|
||||
{
|
||||
AzFramework::Terrain::TerrainDataRequestBus::Handler::BusConnect();
|
||||
}
|
||||
void Deactivate() override
|
||||
{
|
||||
AzFramework::Terrain::TerrainDataRequestBus::Handler::BusDisconnect();
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// TerrainDataRequestBus interface dummy implementation
|
||||
AZ::Vector2 GetTerrainHeightQueryResolution() const override
|
||||
{
|
||||
return {};
|
||||
}
|
||||
void SetTerrainHeightQueryResolution([[maybe_unused]] AZ::Vector2 queryResolution) override
|
||||
{
|
||||
}
|
||||
|
||||
AZ::Aabb GetTerrainAabb() const override
|
||||
{
|
||||
return {};
|
||||
}
|
||||
void SetTerrainAabb([[maybe_unused]] const AZ::Aabb& worldBounds) override
|
||||
{
|
||||
}
|
||||
|
||||
float GetHeight(AZ::Vector3, Sampler, bool*) const override
|
||||
{
|
||||
return {};
|
||||
}
|
||||
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 {}; }
|
||||
AZ::Vector3 GetNormalFromFloats(float, float, Sampler, bool*) const override { return {}; }
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
};
|
||||
|
||||
} // namespace PhysX
|
||||
|
||||
@@ -27,8 +27,8 @@ namespace Terrain
|
||||
|
||||
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;
|
||||
//! Get the surfaces and weights from a gradient at a given position.
|
||||
virtual void GetSurfaceWeights(const AZ::Vector3& inPosition, AzFramework::SurfaceData::SurfaceTagWeightList& outSurfaceWeights) const = 0;
|
||||
};
|
||||
|
||||
using TerrainAreaSurfaceRequestBus = AZ::EBus<TerrainAreaSurfaceRequests>;
|
||||
|
||||
@@ -107,17 +107,28 @@ namespace UnitTest
|
||||
MOCK_METHOD1(SetTerrainHeightQueryResolution, void(AZ::Vector2));
|
||||
MOCK_CONST_METHOD0(GetTerrainAabb, AZ::Aabb());
|
||||
MOCK_METHOD1(SetTerrainAabb, void(const AZ::Aabb&));
|
||||
MOCK_CONST_METHOD3(GetHeight, float(AZ::Vector3, Sampler, bool*));
|
||||
MOCK_CONST_METHOD3(GetHeight, float(const AZ::Vector3&, Sampler, bool*));
|
||||
MOCK_CONST_METHOD3(GetHeightFromVector2, float(const AZ::Vector2&, Sampler, bool*));
|
||||
MOCK_CONST_METHOD4(GetHeightFromFloats, float(float, float, Sampler, bool*));
|
||||
MOCK_CONST_METHOD3(GetMaxSurfaceWeight, AzFramework::SurfaceData::SurfaceTagWeight(AZ::Vector3, Sampler, bool*));
|
||||
MOCK_CONST_METHOD2(GetIsHole, bool(const AZ::Vector3&, Sampler));
|
||||
MOCK_CONST_METHOD2(GetIsHoleFromVector2, bool(const AZ::Vector2&, Sampler));
|
||||
MOCK_CONST_METHOD3(GetIsHoleFromFloats, bool(float, float, Sampler));
|
||||
MOCK_CONST_METHOD3(GetNormal, AZ::Vector3(const AZ::Vector3&, Sampler, bool*));
|
||||
MOCK_CONST_METHOD3(GetNormalFromVector2, AZ::Vector3(const AZ::Vector2&, Sampler, bool*));
|
||||
MOCK_CONST_METHOD4(GetNormalFromFloats, AZ::Vector3(float, float, Sampler, bool*));
|
||||
MOCK_CONST_METHOD3(GetMaxSurfaceWeight, AzFramework::SurfaceData::SurfaceTagWeight(const AZ::Vector3&, Sampler, bool*));
|
||||
MOCK_CONST_METHOD3(GetMaxSurfaceWeightFromVector2, AzFramework::SurfaceData::SurfaceTagWeight(const AZ::Vector2&, Sampler, bool*));
|
||||
MOCK_CONST_METHOD4(GetMaxSurfaceWeightFromFloats, AzFramework::SurfaceData::SurfaceTagWeight(float, float, Sampler, bool*));
|
||||
MOCK_CONST_METHOD4(GetSurfaceWeights, void(const AZ::Vector3&, AzFramework::SurfaceData::OrderedSurfaceTagWeightSet&, Sampler, bool*));
|
||||
MOCK_CONST_METHOD4(GetSurfaceWeightsFromVector2, void(const AZ::Vector2&, AzFramework::SurfaceData::OrderedSurfaceTagWeightSet&, Sampler, bool*));
|
||||
MOCK_CONST_METHOD5(GetSurfaceWeightsFromFloats, void(float, float, AzFramework::SurfaceData::OrderedSurfaceTagWeightSet&, Sampler, bool*));
|
||||
MOCK_CONST_METHOD3(GetMaxSurfaceName, const char*(AZ::Vector3, Sampler, bool*));
|
||||
MOCK_CONST_METHOD3(GetIsHoleFromFloats, bool(float, float, Sampler));
|
||||
MOCK_CONST_METHOD3(GetNormal, AZ::Vector3(AZ::Vector3, Sampler, bool*));
|
||||
MOCK_CONST_METHOD4(GetNormalFromFloats, AZ::Vector3(float, float, Sampler, bool*));
|
||||
MOCK_CONST_METHOD4(GetSurfaceWeights, void(const AZ::Vector3&, AzFramework::SurfaceData::SurfaceTagWeightList&, Sampler, bool*));
|
||||
MOCK_CONST_METHOD4(
|
||||
GetSurfaceWeightsFromVector2, void(const AZ::Vector2&, AzFramework::SurfaceData::SurfaceTagWeightList&, Sampler, bool*));
|
||||
MOCK_CONST_METHOD5(
|
||||
GetSurfaceWeightsFromFloats, void(float, float, AzFramework::SurfaceData::SurfaceTagWeightList&, Sampler, bool*));
|
||||
MOCK_CONST_METHOD3(GetMaxSurfaceName, const char*(const AZ::Vector3&, Sampler, bool*));
|
||||
MOCK_CONST_METHOD4(GetSurfacePoint, void(const AZ::Vector3&, AzFramework::SurfaceData::SurfacePoint&, Sampler, bool*));
|
||||
MOCK_CONST_METHOD4(
|
||||
GetSurfacePointFromVector2, void(const AZ::Vector2&, AzFramework::SurfaceData::SurfacePoint&, Sampler, bool*));
|
||||
MOCK_CONST_METHOD5(
|
||||
GetSurfacePointFromFloats, void(float, float, AzFramework::SurfaceData::SurfacePoint&, Sampler, bool*));
|
||||
};
|
||||
} // namespace UnitTest
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace UnitTest
|
||||
|
||||
MOCK_METHOD0(Activate, void());
|
||||
MOCK_METHOD0(Deactivate, void());
|
||||
MOCK_CONST_METHOD2(GetSurfaceWeights, void(const AZ::Vector3&, AzFramework::SurfaceData::OrderedSurfaceTagWeightSet&));
|
||||
MOCK_CONST_METHOD2(GetSurfaceWeights, void(const AZ::Vector3&, AzFramework::SurfaceData::SurfaceTagWeightList&));
|
||||
};
|
||||
|
||||
} // namespace UnitTest
|
||||
|
||||
@@ -149,13 +149,17 @@ namespace Terrain
|
||||
if (terrain->GetTerrainAabb().Contains(inPosition))
|
||||
{
|
||||
bool isTerrainValidAtPoint = false;
|
||||
const float terrainHeight = terrain->GetHeight(inPosition, AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR, &isTerrainValidAtPoint);
|
||||
AzFramework::SurfaceData::SurfacePoint terrainSurfacePoint;
|
||||
terrain->GetSurfacePoint(
|
||||
inPosition, terrainSurfacePoint, AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR,
|
||||
&isTerrainValidAtPoint);
|
||||
|
||||
const bool isHole = !isTerrainValidAtPoint;
|
||||
|
||||
SurfaceData::SurfacePoint point;
|
||||
point.m_entityId = GetEntityId();
|
||||
point.m_position = AZ::Vector3(inPosition.GetX(), inPosition.GetY(), terrainHeight);
|
||||
point.m_normal = terrain->GetNormal(inPosition);
|
||||
point.m_position = terrainSurfacePoint.m_position;
|
||||
point.m_normal = terrainSurfacePoint.m_normal;
|
||||
|
||||
// Always add a "terrain" or "terrainHole" tag.
|
||||
const AZ::Crc32 terrainTag =
|
||||
@@ -163,9 +167,7 @@ namespace Terrain
|
||||
SurfaceData::AddMaxValueForMasks(point.m_masks, terrainTag, 1.0f);
|
||||
|
||||
// Add all of the surface tags that the terrain has at this point.
|
||||
AzFramework::SurfaceData::OrderedSurfaceTagWeightSet surfaceWeights;
|
||||
terrain->GetSurfaceWeights(point.m_position, surfaceWeights);
|
||||
for (auto& tag : surfaceWeights)
|
||||
for (auto& tag : terrainSurfacePoint.m_surfaceTags)
|
||||
{
|
||||
SurfaceData::AddMaxValueForMasks(point.m_masks, tag.m_surfaceType, tag.m_weight);
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ namespace Terrain
|
||||
|
||||
void TerrainSurfaceGradientListComponent::GetSurfaceWeights(
|
||||
const AZ::Vector3& inPosition,
|
||||
AzFramework::SurfaceData::OrderedSurfaceTagWeightSet& outSurfaceWeights) const
|
||||
AzFramework::SurfaceData::SurfaceTagWeightList& outSurfaceWeights) const
|
||||
{
|
||||
outSurfaceWeights.clear();
|
||||
|
||||
@@ -178,10 +178,7 @@ namespace Terrain
|
||||
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);
|
||||
outSurfaceWeights.emplace_back(mapping.m_surfaceTag, weight);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace Terrain
|
||||
bool WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const override;
|
||||
|
||||
// TerrainAreaSurfaceRequestBus
|
||||
void GetSurfaceWeights(const AZ::Vector3& inPosition, AzFramework::SurfaceData::OrderedSurfaceTagWeightSet& outSurfaceWeights) const override;
|
||||
void GetSurfaceWeights(const AZ::Vector3& inPosition, AzFramework::SurfaceData::SurfaceTagWeightList& outSurfaceWeights) const override;
|
||||
|
||||
private:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -241,7 +241,12 @@ float TerrainSystem::GetTerrainAreaHeight(float x, float y, bool& terrainExists)
|
||||
return height;
|
||||
}
|
||||
|
||||
float TerrainSystem::GetHeight(AZ::Vector3 position, Sampler sampler, bool* terrainExistsPtr) const
|
||||
float TerrainSystem::GetHeight(const AZ::Vector3& position, Sampler sampler, bool* terrainExistsPtr) const
|
||||
{
|
||||
return GetHeightSynchronous(position.GetX(), position.GetY(), sampler, terrainExistsPtr);
|
||||
}
|
||||
|
||||
float TerrainSystem::GetHeightFromVector2(const AZ::Vector2& position, Sampler sampler, bool* terrainExistsPtr) const
|
||||
{
|
||||
return GetHeightSynchronous(position.GetX(), position.GetY(), sampler, terrainExistsPtr);
|
||||
}
|
||||
@@ -251,6 +256,20 @@ float TerrainSystem::GetHeightFromFloats(float x, float y, Sampler sampler, bool
|
||||
return GetHeightSynchronous(x, y, sampler, terrainExistsPtr);
|
||||
}
|
||||
|
||||
bool TerrainSystem::GetIsHole(const AZ::Vector3& position, Sampler sampler) const
|
||||
{
|
||||
bool terrainExists = false;
|
||||
GetHeightSynchronous(position.GetX(), position.GetY(), sampler, &terrainExists);
|
||||
return !terrainExists;
|
||||
}
|
||||
|
||||
bool TerrainSystem::GetIsHoleFromVector2(const AZ::Vector2& position, Sampler sampler) const
|
||||
{
|
||||
bool terrainExists = false;
|
||||
GetHeightSynchronous(position.GetX(), position.GetY(), sampler, &terrainExists);
|
||||
return !terrainExists;
|
||||
}
|
||||
|
||||
bool TerrainSystem::GetIsHoleFromFloats(float x, float y, Sampler sampler) const
|
||||
{
|
||||
bool terrainExists = false;
|
||||
@@ -287,7 +306,12 @@ AZ::Vector3 TerrainSystem::GetNormalSynchronous(float x, float y, Sampler sample
|
||||
return outNormal;
|
||||
}
|
||||
|
||||
AZ::Vector3 TerrainSystem::GetNormal(AZ::Vector3 position, Sampler sampler, bool* terrainExistsPtr) const
|
||||
AZ::Vector3 TerrainSystem::GetNormal(const AZ::Vector3& position, Sampler sampler, bool* terrainExistsPtr) const
|
||||
{
|
||||
return GetNormalSynchronous(position.GetX(), position.GetY(), sampler, terrainExistsPtr);
|
||||
}
|
||||
|
||||
AZ::Vector3 TerrainSystem::GetNormalFromVector2(const AZ::Vector2& position, Sampler sampler, bool* terrainExistsPtr) const
|
||||
{
|
||||
return GetNormalSynchronous(position.GetX(), position.GetY(), sampler, terrainExistsPtr);
|
||||
}
|
||||
@@ -299,7 +323,7 @@ AZ::Vector3 TerrainSystem::GetNormalFromFloats(float x, float y, Sampler sampler
|
||||
|
||||
|
||||
AzFramework::SurfaceData::SurfaceTagWeight TerrainSystem::GetMaxSurfaceWeight(
|
||||
const AZ::Vector3 position, Sampler sampleFilter, bool* terrainExistsPtr) const
|
||||
const AZ::Vector3& position, Sampler sampleFilter, bool* terrainExistsPtr) const
|
||||
{
|
||||
return GetMaxSurfaceWeightFromFloats(position.GetX(), position.GetY(), sampleFilter, terrainExistsPtr);
|
||||
}
|
||||
@@ -317,7 +341,7 @@ AzFramework::SurfaceData::SurfaceTagWeight TerrainSystem::GetMaxSurfaceWeightFro
|
||||
*terrainExistsPtr = true;
|
||||
}
|
||||
|
||||
AzFramework::SurfaceData::OrderedSurfaceTagWeightSet weightSet;
|
||||
AzFramework::SurfaceData::SurfaceTagWeightList weightSet;
|
||||
|
||||
GetOrderedSurfaceWeights(x, y, sampleFilter, weightSet, terrainExistsPtr);
|
||||
|
||||
@@ -329,6 +353,38 @@ AzFramework::SurfaceData::SurfaceTagWeight TerrainSystem::GetMaxSurfaceWeightFro
|
||||
return *weightSet.begin();
|
||||
}
|
||||
|
||||
void TerrainSystem::GetSurfacePoint(
|
||||
const AZ::Vector3& inPosition,
|
||||
AzFramework::SurfaceData::SurfacePoint& outSurfacePoint,
|
||||
Sampler sampleFilter,
|
||||
bool* terrainExistsPtr) const
|
||||
{
|
||||
outSurfacePoint.m_position = inPosition;
|
||||
outSurfacePoint.m_position.SetZ(GetHeightSynchronous(inPosition.GetX(), inPosition.GetY(), sampleFilter, terrainExistsPtr));
|
||||
outSurfacePoint.m_normal = GetNormalSynchronous(inPosition.GetX(), inPosition.GetY(), sampleFilter, nullptr);
|
||||
GetSurfaceWeights(inPosition, outSurfacePoint.m_surfaceTags, sampleFilter, nullptr);
|
||||
}
|
||||
|
||||
void TerrainSystem::GetSurfacePointFromVector2(
|
||||
const AZ::Vector2& inPosition,
|
||||
AzFramework::SurfaceData::SurfacePoint& outSurfacePoint,
|
||||
Sampler sampleFilter,
|
||||
bool* terrainExistsPtr) const
|
||||
{
|
||||
GetSurfacePoint(AZ::Vector3(inPosition.GetX(), inPosition.GetY(), 0.0f), outSurfacePoint, sampleFilter, terrainExistsPtr);
|
||||
}
|
||||
|
||||
void TerrainSystem::GetSurfacePointFromFloats(
|
||||
float x,
|
||||
float y,
|
||||
AzFramework::SurfaceData::SurfacePoint& outSurfacePoint,
|
||||
Sampler sampleFilter,
|
||||
bool* terrainExistsPtr) const
|
||||
{
|
||||
GetSurfacePoint(AZ::Vector3(x, y, 0.0f), outSurfacePoint, sampleFilter, terrainExistsPtr);
|
||||
}
|
||||
|
||||
|
||||
AZ::EntityId TerrainSystem::FindBestAreaEntityAtPosition(float x, float y, AZ::Aabb& bounds) const
|
||||
{
|
||||
AZ::Vector3 inPosition = AZ::Vector3(x, y, 0);
|
||||
@@ -354,7 +410,7 @@ void TerrainSystem::GetOrderedSurfaceWeights(
|
||||
const float x,
|
||||
const float y,
|
||||
[[maybe_unused]] Sampler sampler,
|
||||
AzFramework::SurfaceData::OrderedSurfaceTagWeightSet& outSurfaceWeights,
|
||||
AzFramework::SurfaceData::SurfaceTagWeightList& outSurfaceWeights,
|
||||
bool* terrainExistsPtr) const
|
||||
{
|
||||
AZ::Aabb bounds;
|
||||
@@ -377,54 +433,40 @@ void TerrainSystem::GetOrderedSurfaceWeights(
|
||||
// Get all the surfaces with weights at the given point.
|
||||
Terrain::TerrainAreaSurfaceRequestBus::Event(
|
||||
bestAreaId, &Terrain::TerrainAreaSurfaceRequestBus::Events::GetSurfaceWeights, inPosition, outSurfaceWeights);
|
||||
|
||||
AZStd::sort(outSurfaceWeights.begin(), outSurfaceWeights.end(), AzFramework::SurfaceData::SurfaceTagWeightComparator());
|
||||
}
|
||||
|
||||
void TerrainSystem::GetSurfaceWeights(
|
||||
const AZ::Vector3& inPosition,
|
||||
AzFramework::SurfaceData::OrderedSurfaceTagWeightSet& outSurfaceWeights,
|
||||
AzFramework::SurfaceData::SurfaceTagWeightList& 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,
|
||||
AzFramework::SurfaceData::SurfaceTagWeightList& 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,
|
||||
float x, float y,
|
||||
AzFramework::SurfaceData::SurfaceTagWeightList& 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
|
||||
const char* TerrainSystem::GetMaxSurfaceName(
|
||||
[[maybe_unused]] const 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)
|
||||
@@ -436,21 +478,6 @@ const char* TerrainSystem::GetMaxSurfaceName([[maybe_unused]] AZ::Vector3 positi
|
||||
}
|
||||
|
||||
/*
|
||||
void TerrainSystem::GetSurfacePoint(
|
||||
const AZ::Vector3& inPosition, [[maybe_unused]] Sampler sampleFilter, SurfaceData::SurfacePoint& outSurfacePoint)
|
||||
{
|
||||
// TODO: Handle sampleFilter
|
||||
|
||||
float sampleX = inPosition.GetX();
|
||||
float sampleY = inPosition.GetY();
|
||||
|
||||
GetHeight(inPosition, sampleFilter, outSurfacePoint.m_position);
|
||||
//outSurfacePoint.m_position = AZ::Vector3(sampleX, sampleY, GetHeightSynchronous(sampleX, sampleY));
|
||||
outSurfacePoint.m_normal = GetNormalSynchronous(sampleX, sampleY);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void TerrainSystem::ProcessHeightsFromRegion(const AZ::Aabb& inRegion, const AZ::Vector2 stepSize, Sampler sampleFilter, SurfacePointRegionFillCallback perPositionCallback, TerrainDataReadyCallback onComplete)
|
||||
{
|
||||
|
||||
@@ -62,7 +62,8 @@ namespace Terrain
|
||||
//! @terrainExistsPtr: 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 become false,
|
||||
//! otherwise *terrainExistsPtr will become true.
|
||||
float GetHeight(AZ::Vector3 position, Sampler sampler = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const override;
|
||||
float GetHeight(const AZ::Vector3& position, Sampler sampler = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const override;
|
||||
float GetHeightFromVector2(const AZ::Vector2& position, Sampler sampler = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const override;
|
||||
float GetHeightFromFloats(float x, float y, Sampler sampler = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const override;
|
||||
|
||||
//! Given an XY coordinate, return the max surface type and weight.
|
||||
@@ -70,7 +71,7 @@ namespace Terrain
|
||||
//! HOLE then *terrainExistsPtr will be set to false,
|
||||
//! otherwise *terrainExistsPtr will be set to true.
|
||||
AzFramework::SurfaceData::SurfaceTagWeight GetMaxSurfaceWeight(
|
||||
const 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(
|
||||
@@ -78,18 +79,18 @@ namespace Terrain
|
||||
|
||||
void GetSurfaceWeights(
|
||||
const AZ::Vector3& inPosition,
|
||||
AzFramework::SurfaceData::OrderedSurfaceTagWeightSet& outSurfaceWeights,
|
||||
AzFramework::SurfaceData::SurfaceTagWeightList& outSurfaceWeights,
|
||||
Sampler sampleFilter = Sampler::DEFAULT,
|
||||
bool* terrainExistsPtr = nullptr) const override;
|
||||
void GetSurfaceWeightsFromVector2(
|
||||
const AZ::Vector2& inPosition,
|
||||
AzFramework::SurfaceData::OrderedSurfaceTagWeightSet& outSurfaceWeights,
|
||||
AzFramework::SurfaceData::SurfaceTagWeightList& outSurfaceWeights,
|
||||
Sampler sampleFilter = Sampler::DEFAULT,
|
||||
bool* terrainExistsPtr = nullptr) const override;
|
||||
void GetSurfaceWeightsFromFloats(
|
||||
float x,
|
||||
float y,
|
||||
AzFramework::SurfaceData::OrderedSurfaceTagWeightSet& outSurfaceWeights,
|
||||
AzFramework::SurfaceData::SurfaceTagWeightList& outSurfaceWeights,
|
||||
Sampler sampleFilter = Sampler::DEFAULT,
|
||||
bool* terrainExistsPtr = nullptr) const override;
|
||||
|
||||
@@ -97,10 +98,12 @@ namespace Terrain
|
||||
//! GetMaxSurfaceWeight or GetMaxSurfaceWeightFromFloats. Not available in the behavior context. Returns nullptr if the position is
|
||||
//! inside a hole or outside of the terrain boundaries.
|
||||
const char* GetMaxSurfaceName(
|
||||
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;
|
||||
|
||||
//! Returns true if there's a hole at location x,y.
|
||||
//! Also returns true if there's no terrain data at location x,y.
|
||||
bool GetIsHole(const AZ::Vector3& position, Sampler sampleFilter = Sampler::BILINEAR) const override;
|
||||
bool GetIsHoleFromVector2(const AZ::Vector2& position, Sampler sampleFilter = Sampler::BILINEAR) const override;
|
||||
bool GetIsHoleFromFloats(float x, float y, Sampler sampleFilter = Sampler::BILINEAR) const override;
|
||||
|
||||
// Given an XY coordinate, return the surface normal.
|
||||
@@ -108,10 +111,30 @@ namespace Terrain
|
||||
//! HOLE then *terrainExistsPtr will be set to false,
|
||||
//! otherwise *terrainExistsPtr will be set to true.
|
||||
AZ::Vector3 GetNormal(
|
||||
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;
|
||||
AZ::Vector3 GetNormalFromVector2(
|
||||
const AZ::Vector2& position, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const override;
|
||||
AZ::Vector3 GetNormalFromFloats(
|
||||
float x, float y, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const override;
|
||||
|
||||
void GetSurfacePoint(
|
||||
const AZ::Vector3& inPosition,
|
||||
AzFramework::SurfaceData::SurfacePoint& outSurfacePoint,
|
||||
Sampler sampleFilter = Sampler::DEFAULT,
|
||||
bool* terrainExistsPtr = nullptr) const override;
|
||||
void GetSurfacePointFromVector2(
|
||||
const AZ::Vector2& inPosition,
|
||||
AzFramework::SurfaceData::SurfacePoint& outSurfacePoint,
|
||||
Sampler sampleFilter = Sampler::DEFAULT,
|
||||
bool* terrainExistsPtr = nullptr) const override;
|
||||
void GetSurfacePointFromFloats(
|
||||
float x,
|
||||
float y,
|
||||
AzFramework::SurfaceData::SurfacePoint& outSurfacePoint,
|
||||
Sampler sampleFilter = Sampler::DEFAULT,
|
||||
bool* terrainExistsPtr = nullptr) const override;
|
||||
|
||||
|
||||
private:
|
||||
void ClampPosition(float x, float y, AZ::Vector2& outPosition, AZ::Vector2& normalizedDelta) const;
|
||||
|
||||
@@ -120,11 +143,11 @@ namespace Terrain
|
||||
const float x,
|
||||
const float y,
|
||||
Sampler sampler,
|
||||
AzFramework::SurfaceData::OrderedSurfaceTagWeightSet& outSurfaceWeights,
|
||||
AzFramework::SurfaceData::SurfaceTagWeightList& 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;
|
||||
AZ::Vector3 GetNormalSynchronous(float x, float y, Sampler sampler, bool* terrainExistsPtr) const;
|
||||
|
||||
// AZ::TickBus::Handler overrides ...
|
||||
void OnTick(float deltaTime, AZ::ScriptTimePoint time) override;
|
||||
|
||||
@@ -91,10 +91,10 @@ namespace UnitTest
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(TerrainSurfaceGradientListTest, SurfaceGradientReturnsSurfaceWeightsInOrder)
|
||||
TEST_F(TerrainSurfaceGradientListTest, SurfaceGradientReturnsSurfaceWeights)
|
||||
{
|
||||
// When there is more that one surface/weight defined and added to the component, they should all
|
||||
// be returned in descending weight order.
|
||||
// When there is more than one surface/weight defined and added to the component, they should all
|
||||
// be returned. The component isn't required to return them in descending order.
|
||||
AddSurfaceGradientListToEntities();
|
||||
|
||||
m_entity->Activate();
|
||||
@@ -109,15 +109,15 @@ namespace UnitTest
|
||||
NiceMock<UnitTest::MockGradientRequests> mockGradientRequests2(m_gradientEntity2->GetId());
|
||||
ON_CALL(mockGradientRequests2, GetValue).WillByDefault(Return(gradient2Value));
|
||||
|
||||
AzFramework::SurfaceData::OrderedSurfaceTagWeightSet weightSet;
|
||||
AzFramework::SurfaceData::SurfaceTagWeightList weightList;
|
||||
Terrain::TerrainAreaSurfaceRequestBus::Event(
|
||||
m_entity->GetId(), &Terrain::TerrainAreaSurfaceRequestBus::Events::GetSurfaceWeights, AZ::Vector3::CreateZero(), weightSet);
|
||||
m_entity->GetId(), &Terrain::TerrainAreaSurfaceRequestBus::Events::GetSurfaceWeights, AZ::Vector3::CreateZero(), weightList);
|
||||
|
||||
AZ::Crc32 expectedCrcList[] = { AZ::Crc32(surfaceTag2), AZ::Crc32(surfaceTag1) };
|
||||
const float expectedWeightList[] = { gradient2Value, gradient1Value };
|
||||
AZ::Crc32 expectedCrcList[] = { AZ::Crc32(surfaceTag1), AZ::Crc32(surfaceTag2) };
|
||||
const float expectedWeightList[] = { gradient1Value, gradient2Value };
|
||||
|
||||
int index = 0;
|
||||
for (const auto& surfaceWeight : weightSet)
|
||||
for (const auto& surfaceWeight : weightList)
|
||||
{
|
||||
EXPECT_EQ(surfaceWeight.m_surfaceType, expectedCrcList[index]);
|
||||
EXPECT_NEAR(surfaceWeight.m_weight, expectedWeightList[index], 0.01f);
|
||||
|
||||
@@ -475,8 +475,10 @@ namespace UnitTest
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TerrainSystemTest, GetSurfaceWeightsReturnsAllValidSurfaceWeights)
|
||||
TEST_F(TerrainSystemTest, GetSurfaceWeightsReturnsAllValidSurfaceWeightsInOrder)
|
||||
{
|
||||
// When there is more than one surface/weight defined, they should all be returned in descending weight order.
|
||||
|
||||
CreateAndActivateTerrainSystem();
|
||||
|
||||
const AZ::Aabb aabb = AZ::Aabb::CreateFromMinMax(AZ::Vector3::CreateZero(), AZ::Vector3::CreateOne());
|
||||
@@ -490,32 +492,41 @@ namespace UnitTest
|
||||
|
||||
const AZ::Crc32 tag1("tag1");
|
||||
const AZ::Crc32 tag2("tag2");
|
||||
const AZ::Crc32 tag3("tag3");
|
||||
const float tag1Weight = 0.8f;
|
||||
const float tag2Weight = 1.0f;
|
||||
const float tag3Weight = 0.5f;
|
||||
|
||||
AzFramework::SurfaceData::OrderedSurfaceTagWeightSet orderedSurfaceWeights;
|
||||
|
||||
AzFramework::SurfaceData::SurfaceTagWeight tagWeight1;
|
||||
tagWeight1.m_surfaceType = tag1;
|
||||
tagWeight1.m_weight = 1.0f;
|
||||
orderedSurfaceWeights.emplace(tagWeight1);
|
||||
|
||||
AzFramework::SurfaceData::SurfaceTagWeight tagWeight2;
|
||||
tagWeight2.m_surfaceType = tag2;
|
||||
tagWeight2.m_weight = 0.8f;
|
||||
orderedSurfaceWeights.emplace(tagWeight2);
|
||||
AzFramework::SurfaceData::SurfaceTagWeightList orderedSurfaceWeights
|
||||
{
|
||||
{ tag1, tag1Weight }, { tag2, tag2Weight }, { tag3, tag3Weight }
|
||||
};
|
||||
|
||||
NiceMock<UnitTest::MockTerrainAreaSurfaceRequestBus> mockSurfaceRequests(entity->GetId());
|
||||
ON_CALL(mockSurfaceRequests, GetSurfaceWeights).WillByDefault(SetArgReferee<1>(orderedSurfaceWeights));
|
||||
|
||||
AzFramework::SurfaceData::OrderedSurfaceTagWeightSet outSurfaceWeights;
|
||||
AzFramework::SurfaceData::SurfaceTagWeightList outSurfaceWeights;
|
||||
|
||||
// Asking for values outside the layer spawner bounds, should result in no results.
|
||||
m_terrainSystem->GetSurfaceWeights(aabb.GetMax() + AZ::Vector3::CreateOne(), outSurfaceWeights);
|
||||
EXPECT_TRUE(outSurfaceWeights.empty());
|
||||
|
||||
// Inside the layer spawner box should give us both the added surface weights.
|
||||
// Inside the layer spawner box should give us all of the added surface weights.
|
||||
m_terrainSystem->GetSurfaceWeights(aabb.GetCenter(), outSurfaceWeights);
|
||||
|
||||
EXPECT_EQ(outSurfaceWeights.size(), 2);
|
||||
EXPECT_EQ(outSurfaceWeights.size(), 3);
|
||||
|
||||
// The weights should be returned in decreasing order.
|
||||
AZ::Crc32 expectedCrcList[] = { tag2, tag1, tag3 };
|
||||
const float expectedWeightList[] = { tag2Weight, tag1Weight, tag3Weight };
|
||||
|
||||
int index = 0;
|
||||
for (const auto& surfaceWeight : outSurfaceWeights)
|
||||
{
|
||||
EXPECT_EQ(surfaceWeight.m_surfaceType, expectedCrcList[index]);
|
||||
EXPECT_NEAR(surfaceWeight.m_weight, expectedWeightList[index], 0.01f);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TerrainSystemTest, GetMaxSurfaceWeightsReturnsBiggestValidSurfaceWeight)
|
||||
@@ -534,17 +545,17 @@ namespace UnitTest
|
||||
const AZ::Crc32 tag1("tag1");
|
||||
const AZ::Crc32 tag2("tag2");
|
||||
|
||||
AzFramework::SurfaceData::OrderedSurfaceTagWeightSet orderedSurfaceWeights;
|
||||
AzFramework::SurfaceData::SurfaceTagWeightList orderedSurfaceWeights;
|
||||
|
||||
AzFramework::SurfaceData::SurfaceTagWeight tagWeight1;
|
||||
tagWeight1.m_surfaceType = tag1;
|
||||
tagWeight1.m_weight = 1.0f;
|
||||
orderedSurfaceWeights.emplace(tagWeight1);
|
||||
orderedSurfaceWeights.emplace_back(tagWeight1);
|
||||
|
||||
AzFramework::SurfaceData::SurfaceTagWeight tagWeight2;
|
||||
tagWeight2.m_surfaceType = tag2;
|
||||
tagWeight2.m_weight = 0.8f;
|
||||
orderedSurfaceWeights.emplace(tagWeight2);
|
||||
orderedSurfaceWeights.emplace_back(tagWeight2);
|
||||
|
||||
NiceMock<UnitTest::MockTerrainAreaSurfaceRequestBus> mockSurfaceRequests(entity->GetId());
|
||||
ON_CALL(mockSurfaceRequests, GetSurfaceWeights).WillByDefault(SetArgReferee<1>(orderedSurfaceWeights));
|
||||
|
||||
Reference in New Issue
Block a user