Merge remote-tracking branch 'upstream/development' into michabr/lyshine_shader_loc
This commit is contained in:
+49
-3
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <scenesrg.srgi>
|
||||
#include <viewsrg.srgi>
|
||||
#include <Atom/RPI/Math.azsli>
|
||||
#include "Shadow.azsli"
|
||||
#include "ShadowmapAtlasLib.azsli"
|
||||
#include "BicubicPcfFilters.azsli"
|
||||
@@ -25,6 +26,10 @@
|
||||
enum class ShadowFilterMethod {None, Pcf, Esm, EsmPcf};
|
||||
option ShadowFilterMethod o_directional_shadow_filtering_method = ShadowFilterMethod::None;
|
||||
option bool o_directional_shadow_receiver_plane_bias_enable = true;
|
||||
option bool o_blend_between_cascades_enable = false;
|
||||
|
||||
static const float CascadeBlendArea = 0.015f; // might be worth exposing this as a slider.
|
||||
|
||||
|
||||
// DirectionalLightShadow calculates lit ratio for a directional light.
|
||||
class DirectionalLightShadow
|
||||
@@ -98,6 +103,8 @@ class DirectionalLightShadow
|
||||
|
||||
float SamplePcfBicubic(float3 shadowCoord, uint indexOfCascade);
|
||||
|
||||
float CalculateCascadeBlendAmount(const float3 texCoord);
|
||||
|
||||
uint m_lightIndex;
|
||||
float3 m_shadowCoords[ViewSrg::MaxCascadeCount];
|
||||
float m_slopeBias[ViewSrg::MaxCascadeCount];
|
||||
@@ -174,6 +181,7 @@ bool2 DirectionalLightShadow::IsShadowed(float3 shadowCoord, uint indexOfCascade
|
||||
const uint cascadeCount = ViewSrg::m_directionalLightShadows[m_lightIndex].m_cascadeCount;
|
||||
Texture2DArray<float> shadowmap = PassSrg::m_directionalLightShadowmap;
|
||||
|
||||
[branch]
|
||||
if (shadowCoord.x >= 0. && shadowCoord.x * size < size - PixelMargin &&
|
||||
shadowCoord.y >= 0. && shadowCoord.y * size < size - PixelMargin)
|
||||
{
|
||||
@@ -213,20 +221,46 @@ float DirectionalLightShadow::GetVisibilityFromLightPcf()
|
||||
static const float PixelMargin = 1.5; // avoiding artifact between cascade levels.
|
||||
static const float DepthMargin = 1e-8; // avoiding artifact when near depth bounds.
|
||||
|
||||
bool cascadeFound = false;
|
||||
int currentCascadeIndex = 0;
|
||||
|
||||
const uint size = ViewSrg::m_directionalLightShadows[m_lightIndex].m_shadowmapSize;
|
||||
const uint cascadeCount = ViewSrg::m_directionalLightShadows[m_lightIndex].m_cascadeCount;
|
||||
for (uint indexOfCascade = 0; indexOfCascade < cascadeCount; ++indexOfCascade)
|
||||
{
|
||||
const float3 shadowCoord = m_shadowCoords[indexOfCascade];
|
||||
|
||||
|
||||
if (shadowCoord.x >= 0. && shadowCoord.x * size < size - PixelMargin &&
|
||||
shadowCoord.y >= 0. && shadowCoord.y * size < size - PixelMargin &&
|
||||
shadowCoord.z < 1. - DepthMargin)
|
||||
{
|
||||
m_debugInfo.m_cascadeIndex = indexOfCascade;
|
||||
return SamplePcfBicubic(shadowCoord, indexOfCascade);
|
||||
currentCascadeIndex = m_debugInfo.m_cascadeIndex = indexOfCascade;
|
||||
cascadeFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
[branch]
|
||||
if (cascadeFound)
|
||||
{
|
||||
float lit = SamplePcfBicubic(m_shadowCoords[currentCascadeIndex], currentCascadeIndex);
|
||||
|
||||
if(o_blend_between_cascades_enable)
|
||||
{
|
||||
const float blendBetweenCascadesAmount = CalculateCascadeBlendAmount(m_shadowCoords[currentCascadeIndex].xyz);
|
||||
|
||||
const int nextCascadeIndex = currentCascadeIndex + 1;
|
||||
[branch]
|
||||
if (blendBetweenCascadesAmount < 1.0f && nextCascadeIndex < cascadeCount)
|
||||
{
|
||||
const float nextLit = SamplePcfBicubic(m_shadowCoords[nextCascadeIndex], nextCascadeIndex);
|
||||
lit = lerp(nextLit, lit, blendBetweenCascadesAmount);
|
||||
}
|
||||
}
|
||||
|
||||
return lit;
|
||||
}
|
||||
|
||||
m_debugInfo.m_cascadeIndex = cascadeCount;
|
||||
return 1.;
|
||||
}
|
||||
@@ -244,6 +278,8 @@ float DirectionalLightShadow::GetVisibilityFromLightEsm()
|
||||
const float distanceMin = ViewSrg::m_esmsDirectional[indexOfCascade].m_lightDistanceOfCameraViewFrustum;
|
||||
bool2 checkedShadowed = IsShadowed(shadowCoord, indexOfCascade);
|
||||
const float depthDiff = shadowCoord.z - distanceMin;
|
||||
|
||||
[branch]
|
||||
if (checkedShadowed.x && depthDiff >= 0)
|
||||
{
|
||||
const float distanceWithinCameraView = depthDiff / (1. - distanceMin);
|
||||
@@ -274,6 +310,8 @@ float DirectionalLightShadow::GetVisibilityFromLightEsmPcf()
|
||||
const float distanceMin = ViewSrg::m_esmsDirectional[indexOfCascade].m_lightDistanceOfCameraViewFrustum;
|
||||
bool2 checkedShadowed = IsShadowed(shadowCoord, indexOfCascade);
|
||||
const float depthDiff = shadowCoord.z - distanceMin;
|
||||
|
||||
[branch]
|
||||
if (checkedShadowed.x && depthDiff >= 0)
|
||||
{
|
||||
const float distanceWithinCameraView = depthDiff / (1. - distanceMin);
|
||||
@@ -319,6 +357,7 @@ float DirectionalLightShadow::SamplePcfBicubic(float3 shadowCoord, uint indexOfC
|
||||
param.samplerState = SceneSrg::m_hwPcfSampler;
|
||||
param.receiverPlaneDepthBias = o_directional_shadow_receiver_plane_bias_enable ? ComputeReceiverPlaneDepthBias(m_shadowPosDX[indexOfCascade], m_shadowPosDY[indexOfCascade]) : 0;
|
||||
|
||||
[branch]
|
||||
if (filteringSampleCount <= 4)
|
||||
{
|
||||
return SampleShadowMapBicubic_4Tap(param);
|
||||
@@ -420,3 +459,10 @@ float3 DirectionalLightShadow::AddDebugColoring(
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
float DirectionalLightShadow::CalculateCascadeBlendAmount(const float3 texCoord)
|
||||
{
|
||||
const float distanceToOneMin = min3(1.0f - texCoord);
|
||||
const float currentPixelsBlendBandLocation = min(min(texCoord.x, texCoord.y), distanceToOneMin);
|
||||
return currentPixelsBlendBandLocation / CascadeBlendArea;
|
||||
}
|
||||
|
||||
@@ -368,16 +368,19 @@ void CullDecals(uint groupIndex, TileLightData tileLightData, float3 aabb_center
|
||||
float3 decalPosition = WorldToView_Point(decal.m_position);
|
||||
|
||||
// just wrapping a bounding sphere around a cube for now to get a minor perf boost. i.e. the sphere radius is sqrt(x*x + y*y + z*z)
|
||||
// ATOM-4224 - try AABB-AABB and implement depth binning for the decals
|
||||
float maxHalfSize = max(max(decal.m_halfSize.x, decal.m_halfSize.y), decal.m_halfSize.z);
|
||||
float boundingSphereRadiusSqr = maxHalfSize * maxHalfSize * 3;
|
||||
// ATOM-4224 - try AABB-AABB
|
||||
float boundingSphereRadiusSqr = dot(decal.m_halfSize, decal.m_halfSize);
|
||||
|
||||
bool potentiallyIntersects = TestSphereVsAabb(decalPosition, boundingSphereRadiusSqr, aabb_center, aabb_extents);
|
||||
|
||||
if (potentiallyIntersects)
|
||||
{
|
||||
// Implement and profile fine-grained light culling testing
|
||||
// ATOM-3732
|
||||
MarkLightAsVisibleInSharedMemory(decalIndex, 0xFFFF);
|
||||
uint inside = 0;
|
||||
float2 minmax = ComputePointLightMinMaxZ(sqrt(boundingSphereRadiusSqr), decalPosition);
|
||||
if (IsObjectInsideTile(tileLightData, minmax, inside))
|
||||
{
|
||||
MarkLightAsVisibleInSharedMemory(decalIndex, inside);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
@@ -163,6 +163,9 @@ namespace AZ
|
||||
|
||||
//! Reduces acne by biasing the shadowmap lookup along the geometric normal.
|
||||
virtual void SetNormalShadowBias(LightHandle handle, float normalShadowBias) = 0;
|
||||
|
||||
//! Sets whether or not blending between shadow map cascades is enabled.
|
||||
virtual void SetCascadeBlendingEnabled(LightHandle handle, bool enable) = 0;
|
||||
};
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
+10
-3
@@ -198,13 +198,15 @@ namespace AZ
|
||||
|
||||
if (m_shadowingLightHandle.IsValid())
|
||||
{
|
||||
uint32_t shadowFilterMethod = m_shadowData.at(nullptr).GetData(m_shadowingLightHandle.GetIndex()).m_shadowFilterMethod;
|
||||
const uint32_t shadowFilterMethod = m_shadowData.at(nullptr).GetData(m_shadowingLightHandle.GetIndex()).m_shadowFilterMethod;
|
||||
RPI::ShaderSystemInterface::Get()->SetGlobalShaderOption(m_directionalShadowFilteringMethodName, AZ::RPI::ShaderOptionValue{shadowFilterMethod});
|
||||
RPI::ShaderSystemInterface::Get()->SetGlobalShaderOption(m_directionalShadowReceiverPlaneBiasEnableName, AZ::RPI::ShaderOptionValue{ m_shadowProperties.GetData(m_shadowingLightHandle.GetIndex()).m_isReceiverPlaneBiasEnabled });
|
||||
RPI::ShaderSystemInterface::Get()->SetGlobalShaderOption(m_directionalShadowReceiverPlaneBiasEnableName, AZ::RPI::ShaderOptionValue{ m_shadowProperties.GetData(m_shadowingLightHandle.GetIndex()).m_isReceiverPlaneBiasEnabled });
|
||||
|
||||
const uint32_t cascadeCount = m_shadowData.at(nullptr).GetData(m_shadowingLightHandle.GetIndex()).m_cascadeCount;
|
||||
ShadowProperty& property = m_shadowProperties.GetData(m_shadowingLightHandle.GetIndex());
|
||||
|
||||
RPI::ShaderSystemInterface::Get()->SetGlobalShaderOption(m_BlendBetweenCascadesEnableName, AZ::RPI::ShaderOptionValue{cascadeCount > 1 && m_shadowProperties.GetData(m_shadowingLightHandle.GetIndex()).m_blendBetwenCascades });
|
||||
|
||||
ShadowProperty& property = m_shadowProperties.GetData(m_shadowingLightHandle.GetIndex());
|
||||
bool segmentsNeedUpdate = property.m_segments.empty();
|
||||
for (const auto& passIt : m_cascadedShadowmapsPasses)
|
||||
{
|
||||
@@ -577,6 +579,11 @@ namespace AZ
|
||||
m_shadowProperties.GetData(handle.GetIndex()).m_isReceiverPlaneBiasEnabled = enable;
|
||||
}
|
||||
|
||||
void DirectionalLightFeatureProcessor::SetCascadeBlendingEnabled(LightHandle handle, bool enable)
|
||||
{
|
||||
m_shadowProperties.GetData(handle.GetIndex()).m_blendBetwenCascades = enable;
|
||||
}
|
||||
|
||||
void DirectionalLightFeatureProcessor::SetShadowBias(LightHandle handle, float bias)
|
||||
{
|
||||
for (auto& it : m_shadowData)
|
||||
|
||||
@@ -176,6 +176,8 @@ namespace AZ
|
||||
// If true, this will reduce the shadow acne introduced by large pcf kernels by estimating the angle of the triangle being shaded
|
||||
// with the ddx/ddy functions.
|
||||
bool m_isReceiverPlaneBiasEnabled = true;
|
||||
|
||||
bool m_blendBetwenCascades = false;
|
||||
};
|
||||
|
||||
static void Reflect(ReflectContext* context);
|
||||
@@ -215,6 +217,7 @@ namespace AZ
|
||||
void SetShadowFilterMethod(LightHandle handle, ShadowFilterMethod method) override;
|
||||
void SetFilteringSampleCount(LightHandle handle, uint16_t count) override;
|
||||
void SetShadowReceiverPlaneBiasEnabled(LightHandle handle, bool enable) override;
|
||||
void SetCascadeBlendingEnabled(LightHandle handle, bool enable) override;
|
||||
void SetShadowBias(LightHandle handle, float bias) override;
|
||||
void SetNormalShadowBias(LightHandle handle, float normalShadowBias) override;
|
||||
|
||||
@@ -367,6 +370,7 @@ namespace AZ
|
||||
Name m_lightTypeName = Name("directional");
|
||||
Name m_directionalShadowFilteringMethodName = Name("o_directional_shadow_filtering_method");
|
||||
Name m_directionalShadowReceiverPlaneBiasEnableName = Name("o_directional_shadow_receiver_plane_bias_enable");
|
||||
Name m_BlendBetweenCascadesEnableName = Name("o_blend_between_cascades_enable");
|
||||
static constexpr const char* FeatureProcessorName = "DirectionalLightFeatureProcessor";
|
||||
};
|
||||
} // namespace Render
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/std/string/conversions.h>
|
||||
|
||||
|
||||
+8
@@ -184,6 +184,14 @@ namespace AZ
|
||||
//! Reduces acne by biasing the shadowmap lookup along the geometric normal.
|
||||
//! @param normalShadowBias Sets the amount of normal shadow bias to apply.
|
||||
virtual void SetNormalShadowBias(float normalShadowBias) = 0;
|
||||
|
||||
//! Gets whether the directional shadow map has cascade blending enabled.
|
||||
//! This smooths out the border between cascades at the cost of some performance in the blend area.
|
||||
virtual bool GetCascadeBlendingEnabled() const = 0;
|
||||
|
||||
//! Sets whether the directional shadow map has cascade blending enabled.
|
||||
//! @param enable flag specifying whether to enable cascade blending.
|
||||
virtual void SetCascadeBlendingEnabled(bool enable) = 0;
|
||||
};
|
||||
using DirectionalLightRequestBus = EBus<DirectionalLightRequests>;
|
||||
|
||||
|
||||
+3
@@ -115,6 +115,9 @@ namespace AZ
|
||||
//! Reduces shadow acne by applying a small amount of offset along shadow-space z.
|
||||
float m_shadowBias = 0.0f;
|
||||
|
||||
// If true, sample between two adjacent shadow map cascades in a small boundary area to smooth out the transition.
|
||||
bool m_cascadeBlendingEnabled = false;
|
||||
|
||||
bool IsSplitManual() const;
|
||||
bool IsSplitAutomatic() const;
|
||||
bool IsCascadeCorrectionDisabled() const;
|
||||
|
||||
+3
-3
@@ -40,7 +40,8 @@ namespace AZ
|
||||
->Field("PcfFilteringSampleCount", &DirectionalLightComponentConfig::m_filteringSampleCount)
|
||||
->Field("ShadowReceiverPlaneBiasEnabled", &DirectionalLightComponentConfig::m_receiverPlaneBiasEnabled)
|
||||
->Field("Shadow Bias", &DirectionalLightComponentConfig::m_shadowBias)
|
||||
->Field("Normal Shadow Bias", &DirectionalLightComponentConfig::m_normalShadowBias);
|
||||
->Field("Normal Shadow Bias", &DirectionalLightComponentConfig::m_normalShadowBias)
|
||||
->Field("CascadeBlendingEnabled", &DirectionalLightComponentConfig::m_cascadeBlendingEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,8 +114,7 @@ namespace AZ
|
||||
|
||||
bool DirectionalLightComponentConfig::IsShadowPcfDisabled() const
|
||||
{
|
||||
return !(m_shadowFilterMethod == ShadowFilterMethod::Pcf ||
|
||||
m_shadowFilterMethod == ShadowFilterMethod::EsmPcf);
|
||||
return !(m_shadowFilterMethod == ShadowFilterMethod::Pcf);
|
||||
}
|
||||
|
||||
bool DirectionalLightComponentConfig::IsEsmDisabled() const
|
||||
|
||||
+16
-1
@@ -88,6 +88,8 @@ namespace AZ
|
||||
->Event("SetShadowBias", &DirectionalLightRequestBus::Events::SetShadowBias)
|
||||
->Event("GetNormalShadowBias", &DirectionalLightRequestBus::Events::GetNormalShadowBias)
|
||||
->Event("SetNormalShadowBias", &DirectionalLightRequestBus::Events::SetNormalShadowBias)
|
||||
->Event("GetCascadeBlendingEnabled", &DirectionalLightRequestBus::Events::GetCascadeBlendingEnabled)
|
||||
->Event("SetCascadeBlendingEnabled", &DirectionalLightRequestBus::Events::SetCascadeBlendingEnabled)
|
||||
->VirtualProperty("Color", "GetColor", "SetColor")
|
||||
->VirtualProperty("Intensity", "GetIntensity", "SetIntensity")
|
||||
->VirtualProperty("AngularDiameter", "GetAngularDiameter", "SetAngularDiameter")
|
||||
@@ -104,7 +106,8 @@ namespace AZ
|
||||
->VirtualProperty("FilteringSampleCount", "GetFilteringSampleCount", "SetFilteringSampleCount")
|
||||
->VirtualProperty("ShadowReceiverPlaneBiasEnabled", "GetShadowReceiverPlaneBiasEnabled", "SetShadowReceiverPlaneBiasEnabled")
|
||||
->VirtualProperty("ShadowBias", "GetShadowBias", "SetShadowBias")
|
||||
->VirtualProperty("NormalShadowBias", "GetNormalShadowBias", "SetNormalShadowBias");
|
||||
->VirtualProperty("NormalShadowBias", "GetNormalShadowBias", "SetNormalShadowBias")
|
||||
->VirtualProperty("BlendBetweenCascadesEnabled", "GetCascadeBlendingEnabled", "SetCascadeBlendingEnabled");
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -537,6 +540,7 @@ namespace AZ
|
||||
SetNormalShadowBias(m_configuration.m_normalShadowBias);
|
||||
SetFilteringSampleCount(m_configuration.m_filteringSampleCount);
|
||||
SetShadowReceiverPlaneBiasEnabled(m_configuration.m_receiverPlaneBiasEnabled);
|
||||
SetCascadeBlendingEnabled(m_configuration.m_cascadeBlendingEnabled);
|
||||
|
||||
// [GFX TODO][ATOM-1726] share config for multiple light (e.g., light ID).
|
||||
// [GFX TODO][ATOM-2416] adapt to multiple viewports.
|
||||
@@ -636,5 +640,16 @@ namespace AZ
|
||||
m_featureProcessor->SetShadowReceiverPlaneBiasEnabled(m_lightHandle, enable);
|
||||
}
|
||||
|
||||
bool DirectionalLightComponentController::GetCascadeBlendingEnabled() const
|
||||
{
|
||||
return m_configuration.m_cascadeBlendingEnabled;
|
||||
}
|
||||
|
||||
void DirectionalLightComponentController::SetCascadeBlendingEnabled(bool enable)
|
||||
{
|
||||
m_configuration.m_cascadeBlendingEnabled = enable;
|
||||
m_featureProcessor->SetCascadeBlendingEnabled(m_lightHandle, enable);
|
||||
}
|
||||
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
+3
-1
@@ -83,7 +83,9 @@ namespace AZ
|
||||
float GetShadowBias() const override;
|
||||
void SetShadowBias(float bias) override;
|
||||
float GetNormalShadowBias() const override;
|
||||
void SetNormalShadowBias(float bias) override;
|
||||
void SetNormalShadowBias(float bias) override;
|
||||
bool GetCascadeBlendingEnabled() const override;
|
||||
void SetCascadeBlendingEnabled(bool enable) override;
|
||||
|
||||
private:
|
||||
friend class EditorDirectionalLightComponent;
|
||||
|
||||
+5
-1
@@ -161,7 +161,11 @@ namespace AZ
|
||||
->Attribute(Edit::Attributes::Min, 0.f)
|
||||
->Attribute(Edit::Attributes::Max, 10.0f)
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
;
|
||||
->DataElement(
|
||||
Edit::UIHandlers::CheckBox, &DirectionalLightComponentConfig::m_cascadeBlendingEnabled,
|
||||
"Blend between cascades\n", "Enables smooth blending between shadow map cascades.")
|
||||
->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsShadowPcfDisabled)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -688,7 +688,7 @@ namespace MCommon
|
||||
const AZ::Vector3 nodeWorldPos = pose->GetWorldSpaceTransform(jointIndex).m_position;
|
||||
const AZ::Vector3 parentWorldPos = pose->GetWorldSpaceTransform(parentIndex).m_position;
|
||||
const AZ::Vector3 bone = parentWorldPos - nodeWorldPos;
|
||||
const AZ::Vector3 boneDirection = MCore::SafeNormalize(bone);
|
||||
const AZ::Vector3 boneDirection = bone.GetNormalizedSafe();
|
||||
const float boneLength = MCore::SafeLength(bone);
|
||||
const float boneScale = GetBoneScale(actorInstance, joint);
|
||||
const float parentBoneScale = GetBoneScale(actorInstance, skeleton->GetNode(parentIndex));
|
||||
|
||||
@@ -258,9 +258,9 @@ namespace EMotionFX
|
||||
// Calculate the matrix to rotate the solve plane.
|
||||
void BlendTreeFootIKNode::CalculateMatrix(const AZ::Vector3& goal, const AZ::Vector3& bendDir, AZ::Matrix3x3* outForward)
|
||||
{
|
||||
const AZ::Vector3 x = MCore::SafeNormalize(goal);
|
||||
const AZ::Vector3 x = goal.GetNormalizedSafe();
|
||||
const float dot = bendDir.Dot(x);
|
||||
const AZ::Vector3 y = MCore::SafeNormalize(bendDir - (dot * x));
|
||||
const AZ::Vector3 y = (bendDir - (dot * x)).GetNormalizedSafe();
|
||||
const AZ::Vector3 z = x.Cross(y);
|
||||
outForward->SetRow(0, x);
|
||||
outForward->SetRow(1, y);
|
||||
|
||||
@@ -189,11 +189,11 @@ namespace EMotionFX
|
||||
void BlendTreeTwoLinkIKNode::CalculateMatrix(const AZ::Vector3& goal, const AZ::Vector3& bendDir, AZ::Matrix3x3* outForward)
|
||||
{
|
||||
// the inverse matrix defines a coordinate system whose x axis contains P, so X = unit(P).
|
||||
const AZ::Vector3 x = MCore::SafeNormalize(goal);
|
||||
const AZ::Vector3 x = goal.GetNormalizedSafe();
|
||||
|
||||
// the y axis of the inverse is perpendicular to P, so Y = unit( D - X(D . X) ).
|
||||
const float dot = bendDir.Dot(x);
|
||||
const AZ::Vector3 y = MCore::SafeNormalize(bendDir - (dot * x));
|
||||
const AZ::Vector3 y = (bendDir - (dot * x)).GetNormalizedSafe();
|
||||
|
||||
// the z axis of the inverse is perpendicular to both X and Y, so Z = X x Y.
|
||||
const AZ::Vector3 z = x.Cross(y);
|
||||
@@ -372,11 +372,11 @@ namespace EMotionFX
|
||||
if (m_relativeBendDir && !m_extractBendDir)
|
||||
{
|
||||
bendDir = actorInstance->GetWorldSpaceTransform().m_rotation.TransformVector(bendDir);
|
||||
bendDir = MCore::SafeNormalize(bendDir);
|
||||
bendDir.NormalizeSafe();
|
||||
}
|
||||
else
|
||||
{
|
||||
bendDir = MCore::SafeNormalize(bendDir);
|
||||
bendDir.NormalizeSafe();
|
||||
}
|
||||
|
||||
// if end node rotation is enabled
|
||||
@@ -470,8 +470,8 @@ namespace EMotionFX
|
||||
// calculate the differences between the current forward vector and the new one after IK
|
||||
AZ::Vector3 oldForward = globalTransformB.m_position - globalTransformA.m_position;
|
||||
AZ::Vector3 newForward = midPos - globalTransformA.m_position;
|
||||
oldForward = MCore::SafeNormalize(oldForward);
|
||||
newForward = MCore::SafeNormalize(newForward);
|
||||
oldForward.NormalizeSafe();
|
||||
newForward.NormalizeSafe();
|
||||
|
||||
// perform a delta rotation to rotate into the new direction after IK
|
||||
float dotProduct = oldForward.Dot(newForward);
|
||||
@@ -499,9 +499,8 @@ namespace EMotionFX
|
||||
oldForward = endEffectorNodePos - globalTransformB.m_position;
|
||||
}
|
||||
|
||||
oldForward = MCore::SafeNormalize(oldForward);
|
||||
newForward = goal - globalTransformB.m_position;
|
||||
newForward = MCore::SafeNormalize(newForward);
|
||||
oldForward.NormalizeSafe();
|
||||
newForward = (goal - globalTransformB.m_position).GetNormalizedSafe();
|
||||
|
||||
// calculate the delta rotation
|
||||
dotProduct = oldForward.Dot(newForward);
|
||||
|
||||
@@ -581,8 +581,8 @@ namespace EMotionFX
|
||||
&curTangent, &curBitangent);
|
||||
|
||||
// normalize the vectors
|
||||
curTangent = MCore::SafeNormalize(curTangent);
|
||||
curBitangent = MCore::SafeNormalize(curBitangent);
|
||||
curTangent.NormalizeSafe();
|
||||
curBitangent.NormalizeSafe();
|
||||
|
||||
// store the tangents in the orgTangents array
|
||||
const AZ::Vector4 vec4Tangent(curTangent.GetX(), curTangent.GetY(), curTangent.GetZ(), 1.0f);
|
||||
@@ -605,7 +605,7 @@ namespace EMotionFX
|
||||
{
|
||||
// get the normal
|
||||
AZ::Vector3 normal(normals[i]);
|
||||
normal = MCore::SafeNormalize(normal);
|
||||
normal.NormalizeSafe();
|
||||
|
||||
// get the tangent
|
||||
AZ::Vector3 tangent = AZ::Vector3(orgTangents[i].GetX(), orgTangents[i].GetY(), orgTangents[i].GetZ());
|
||||
@@ -631,7 +631,7 @@ namespace EMotionFX
|
||||
|
||||
// Gram-Schmidt orthogonalize
|
||||
AZ::Vector3 fixedTangent = tangent - (normal * normal.Dot(tangent));
|
||||
fixedTangent = MCore::SafeNormalize(fixedTangent);
|
||||
fixedTangent.NormalizeSafe();
|
||||
|
||||
// calculate handedness
|
||||
const AZ::Vector3 crossResult = normal.Cross(tangent);
|
||||
@@ -1671,7 +1671,7 @@ namespace EMotionFX
|
||||
const AZ::Vector3& posA = positions[ indexA ];
|
||||
const AZ::Vector3& posB = positions[ indexB ];
|
||||
const AZ::Vector3& posC = positions[ indexC ];
|
||||
AZ::Vector3 faceNormal = MCore::SafeNormalize((posB - posA).Cross(posC - posB));
|
||||
AZ::Vector3 faceNormal = (posB - posA).Cross(posC - posB).GetNormalizedSafe();
|
||||
|
||||
// store the tangents in the orgTangents array
|
||||
smoothNormals[ orgVerts[indexA] ] += faceNormal;
|
||||
@@ -1684,7 +1684,7 @@ namespace EMotionFX
|
||||
// normalize
|
||||
for (uint32 i = 0; i < m_numOrgVerts; ++i)
|
||||
{
|
||||
smoothNormals[i] = MCore::SafeNormalize(smoothNormals[i]);
|
||||
smoothNormals[i].NormalizeSafe();
|
||||
}
|
||||
|
||||
for (uint32 i = 0; i < m_numVertices; ++i)
|
||||
@@ -1721,7 +1721,7 @@ namespace EMotionFX
|
||||
const AZ::Vector3& posA = positions[ indexA ];
|
||||
const AZ::Vector3& posB = positions[ indexB ];
|
||||
const AZ::Vector3& posC = positions[ indexC ];
|
||||
AZ::Vector3 faceNormal = MCore::SafeNormalize((posB - posA).Cross(posC - posB));
|
||||
AZ::Vector3 faceNormal = (posB - posA).Cross(posC - posB).GetNormalizedSafe();
|
||||
|
||||
// store the tangents in the orgTangents array
|
||||
normals[indexA] = normals[indexA] + faceNormal;
|
||||
@@ -1734,7 +1734,7 @@ namespace EMotionFX
|
||||
// normalize the normals
|
||||
for (uint32 i = 0; i < m_numVertices; ++i)
|
||||
{
|
||||
normals[i] = MCore::SafeNormalize(normals[i]);
|
||||
normals[i].NormalizeSafe();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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 <EMotionFX/Source/Velocity.h>
|
||||
#include <AzCore/Math/MathUtils.h>
|
||||
|
||||
namespace EMotionFX
|
||||
{
|
||||
AZ::Vector3 CalculateLinearVelocity(const AZ::Vector3& lastPosition,
|
||||
const AZ::Vector3& currentPosition,
|
||||
float timeDelta)
|
||||
{
|
||||
if (timeDelta <= AZ::Constants::FloatEpsilon)
|
||||
{
|
||||
return AZ::Vector3::CreateZero();
|
||||
}
|
||||
|
||||
const AZ::Vector3 deltaPosition = currentPosition - lastPosition;
|
||||
const AZ::Vector3 velocity = deltaPosition / timeDelta;
|
||||
|
||||
if (velocity.GetLength() > AZ::Constants::FloatEpsilon)
|
||||
{
|
||||
return velocity;
|
||||
}
|
||||
|
||||
return AZ::Vector3::CreateZero();
|
||||
}
|
||||
|
||||
AZ::Vector3 CalculateAngularVelocity(const AZ::Quaternion& lastRotation,
|
||||
const AZ::Quaternion& currentRotation,
|
||||
float timeDelta)
|
||||
{
|
||||
if (timeDelta <= AZ::Constants::FloatEpsilon)
|
||||
{
|
||||
return AZ::Vector3::CreateZero();
|
||||
}
|
||||
|
||||
const AZ::Quaternion deltaRotation = currentRotation * lastRotation.GetInverseFull();
|
||||
const AZ::Quaternion shortestEquivalent = deltaRotation.GetShortestEquivalent().GetNormalized();
|
||||
const AZ::Vector3 scaledAxisAngle = shortestEquivalent.ConvertToScaledAxisAngle();
|
||||
const AZ::Vector3 angularVelocity = scaledAxisAngle / timeDelta;
|
||||
|
||||
if (angularVelocity.GetLength() > AZ::Constants::FloatEpsilon)
|
||||
{
|
||||
return angularVelocity;
|
||||
}
|
||||
|
||||
return AZ::Vector3::CreateZero();
|
||||
}
|
||||
|
||||
void DebugDrawVelocity(AzFramework::DebugDisplayRequests& debugDisplay,
|
||||
const AZ::Vector3& position, const AZ::Vector3& velocity, const AZ::Color& color)
|
||||
{
|
||||
// Don't visualize joints that remain motionless (zero velocity).
|
||||
if (velocity.GetLength() < AZ::Constants::FloatEpsilon)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const float scale = 0.15f;
|
||||
const AZ::Vector3 arrowPosition = position + velocity;
|
||||
|
||||
debugDisplay.DepthTestOff();
|
||||
debugDisplay.SetColor(color);
|
||||
|
||||
debugDisplay.DrawSolidCylinder(/*center=*/(arrowPosition + position) * 0.5f,
|
||||
/*direction=*/(arrowPosition - position).GetNormalizedSafe(),
|
||||
/*radius=*/0.003f,
|
||||
/*height=*/(arrowPosition - position).GetLength(),
|
||||
/*drawShaded=*/false);
|
||||
|
||||
debugDisplay.DrawSolidCone(position + velocity,
|
||||
velocity,
|
||||
0.1f * scale,
|
||||
scale * 0.5f,
|
||||
/*drawShaded=*/false);
|
||||
}
|
||||
} // namespace EMotionFX
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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/Vector3.h>
|
||||
#include <AzCore/Math/Quaternion.h>
|
||||
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
|
||||
#include <EMotionFX/Source/EMotionFXConfig.h>
|
||||
|
||||
namespace EMotionFX
|
||||
{
|
||||
AZ::Vector3 EMFX_API CalculateLinearVelocity(const AZ::Vector3& lastPosition, const AZ::Vector3& currentPosition, float timeDelta);
|
||||
AZ::Vector3 EMFX_API CalculateAngularVelocity(const AZ::Quaternion& lastRotation, const AZ::Quaternion& currentRotation, float timeDelta);
|
||||
|
||||
void EMFX_API DebugDrawVelocity(AzFramework::DebugDisplayRequests& debugDisplay,
|
||||
const AZ::Vector3& position, const AZ::Vector3& velocity, const AZ::Color& color);
|
||||
} // namespace EMotionFX
|
||||
@@ -144,6 +144,8 @@ set(FILES
|
||||
Source/TransformData.h
|
||||
Source/TriggerActionSetup.cpp
|
||||
Source/TriggerActionSetup.h
|
||||
Source/Velocity.cpp
|
||||
Source/Velocity.h
|
||||
Source/VertexAttributeLayer.cpp
|
||||
Source/VertexAttributeLayer.h
|
||||
Source/VertexAttributeLayerAbstractData.cpp
|
||||
|
||||
@@ -17,12 +17,14 @@
|
||||
|
||||
namespace MCore
|
||||
{
|
||||
//! @deprecated Use AZ::Vector3::NormalizeSafeWithLength()
|
||||
inline float SafeLength(const AZ::Vector3& rhs)
|
||||
{
|
||||
const float lenSq = rhs.Dot(rhs);
|
||||
return (lenSq > FLT_EPSILON) ? sqrtf(lenSq) : 0.0f;
|
||||
}
|
||||
|
||||
//! @deprecated Use AZ::Vector3::GetNormalizedSafe()
|
||||
inline AZ::Vector3 SafeNormalize(const AZ::Vector3& rhs)
|
||||
{
|
||||
AZ::Vector3 result(0.0f);
|
||||
@@ -43,6 +45,7 @@ namespace MCore
|
||||
return AZ::Vector3(vec.GetX() - fac * n.GetX(), vec.GetY() - fac * n.GetY(), vec.GetZ() - fac * n.GetZ());
|
||||
}
|
||||
|
||||
//! @deprecated Use AZ::Vector3::Project()
|
||||
MCORE_INLINE AZ::Vector3 Projected(const AZ::Vector3& vec, const AZ::Vector3& projectOnto)
|
||||
{
|
||||
AZ::Vector3 result = projectOnto;
|
||||
@@ -60,6 +63,7 @@ namespace MCore
|
||||
(MCore::Math::Abs(val.GetX() - val.GetZ()) < MCore::Math::epsilon));
|
||||
}
|
||||
|
||||
//! @deprecated Use AZ::Vector3::Lerp()
|
||||
template <>
|
||||
MCORE_INLINE AZ::Vector3 LinearInterpolate(const AZ::Vector3& source, const AZ::Vector3& target, float timeValue)
|
||||
{
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ConstantGradientComponent.h"
|
||||
#include <GradientSignal/Components/ConstantGradientComponent.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "DitherGradientComponent.h"
|
||||
#include <GradientSignal/Components/DitherGradientComponent.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/Math/MathUtils.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "GradientSurfaceDataComponent.h"
|
||||
#include <GradientSignal/Components/GradientSurfaceDataComponent.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "GradientTransformComponent.h"
|
||||
#include <GradientSignal/Components/GradientTransformComponent.h>
|
||||
#include <AzCore/Math/Vector2.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ImageGradientComponent.h"
|
||||
#include <GradientSignal/Components/ImageGradientComponent.h>
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "InvertGradientComponent.h"
|
||||
#include <GradientSignal/Components/InvertGradientComponent.h>
|
||||
#include <AzCore/Math/MathUtils.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LevelsGradientComponent.h"
|
||||
#include <GradientSignal/Components/LevelsGradientComponent.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/Math/MathUtils.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "MixedGradientComponent.h"
|
||||
#include <GradientSignal/Components/MixedGradientComponent.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "PerlinGradientComponent.h"
|
||||
#include <GradientSignal/Components/PerlinGradientComponent.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/Jobs/Job.h>
|
||||
#include <AzCore/Jobs/JobFunction.h>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "PosterizeGradientComponent.h"
|
||||
#include <GradientSignal/Components/PosterizeGradientComponent.h>
|
||||
#include <AzCore/Math/MathUtils.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "RandomGradientComponent.h"
|
||||
#include <GradientSignal/Components/RandomGradientComponent.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ReferenceGradientComponent.h"
|
||||
#include <GradientSignal/Components/ReferenceGradientComponent.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ShapeAreaFalloffGradientComponent.h"
|
||||
#include <GradientSignal/Components/ShapeAreaFalloffGradientComponent.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "SmoothStepGradientComponent.h"
|
||||
#include <GradientSignal/Components/SmoothStepGradientComponent.h>
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "SurfaceAltitudeGradientComponent.h"
|
||||
#include <GradientSignal/Components/SurfaceAltitudeGradientComponent.h>
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "SurfaceMaskGradientComponent.h"
|
||||
#include <GradientSignal/Components/SurfaceMaskGradientComponent.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "SurfaceSlopeGradientComponent.h"
|
||||
#include <GradientSignal/Components/SurfaceSlopeGradientComponent.h>
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/Math/MathUtils.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ThresholdGradientComponent.h"
|
||||
#include <GradientSignal/Components/ThresholdGradientComponent.h>
|
||||
#include <AzCore/Math/MathUtils.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <GradientSignal/Editor/EditorGradientComponentBase.h>
|
||||
#include <Components/ConstantGradientComponent.h>
|
||||
#include <GradientSignal/Components/ConstantGradientComponent.h>
|
||||
|
||||
namespace GradientSignal
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <GradientSignal/Editor/EditorGradientComponentBase.h>
|
||||
#include <Components/DitherGradientComponent.h>
|
||||
#include <GradientSignal/Components/DitherGradientComponent.h>
|
||||
|
||||
namespace GradientSignal
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Components/GradientSurfaceDataComponent.h>
|
||||
#include <GradientSignal/Components/GradientSurfaceDataComponent.h>
|
||||
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
|
||||
#include <LmbrCentral/Component/EditorWrappedComponentBase.h>
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Components/GradientTransformComponent.h>
|
||||
#include <GradientSignal/Components/GradientTransformComponent.h>
|
||||
#include <LmbrCentral/Component/EditorWrappedComponentBase.h>
|
||||
|
||||
namespace GradientSignal
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <GradientSignal/Editor/EditorGradientComponentBase.h>
|
||||
#include <Components/ImageGradientComponent.h>
|
||||
#include <GradientSignal/Components/ImageGradientComponent.h>
|
||||
|
||||
namespace GradientSignal
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <GradientSignal/Editor/EditorGradientComponentBase.h>
|
||||
#include <Components/InvertGradientComponent.h>
|
||||
#include <GradientSignal/Components/InvertGradientComponent.h>
|
||||
|
||||
namespace GradientSignal
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <GradientSignal/Editor/EditorGradientComponentBase.h>
|
||||
#include <Components/LevelsGradientComponent.h>
|
||||
#include <GradientSignal/Components/LevelsGradientComponent.h>
|
||||
|
||||
namespace GradientSignal
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <GradientSignal/Editor/EditorGradientComponentBase.h>
|
||||
#include <Components/MixedGradientComponent.h>
|
||||
#include <GradientSignal/Components/MixedGradientComponent.h>
|
||||
|
||||
namespace GradientSignal
|
||||
{
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
#include <AzCore/Module/Module.h>
|
||||
#include <GradientSignal/Editor/EditorGradientComponentBase.h>
|
||||
#include <Components/PerlinGradientComponent.h>
|
||||
#include <GradientSignal/Components/PerlinGradientComponent.h>
|
||||
|
||||
namespace GradientSignal
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <GradientSignal/Editor/EditorGradientComponentBase.h>
|
||||
#include <Components/PosterizeGradientComponent.h>
|
||||
#include <GradientSignal/Components/PosterizeGradientComponent.h>
|
||||
|
||||
namespace GradientSignal
|
||||
{
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <GradientSignal/Editor/EditorGradientComponentBase.h>
|
||||
#include <GradientSignal/Editor/EditorGradientTypeIds.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorVisibilityBus.h>
|
||||
#include <Components/RandomGradientComponent.h>
|
||||
#include <GradientSignal/Components/RandomGradientComponent.h>
|
||||
|
||||
namespace GradientSignal
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <GradientSignal/Editor/EditorGradientComponentBase.h>
|
||||
#include <Components/ReferenceGradientComponent.h>
|
||||
#include <GradientSignal/Components/ReferenceGradientComponent.h>
|
||||
|
||||
namespace GradientSignal
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <GradientSignal/Editor/EditorGradientComponentBase.h>
|
||||
#include <Components/ShapeAreaFalloffGradientComponent.h>
|
||||
#include <GradientSignal/Components/ShapeAreaFalloffGradientComponent.h>
|
||||
|
||||
namespace GradientSignal
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <GradientSignal/Editor/EditorGradientComponentBase.h>
|
||||
#include <Components/SmoothStepGradientComponent.h>
|
||||
#include <GradientSignal/Components/SmoothStepGradientComponent.h>
|
||||
|
||||
namespace GradientSignal
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <GradientSignal/Editor/EditorGradientComponentBase.h>
|
||||
#include <Components/SurfaceAltitudeGradientComponent.h>
|
||||
#include <GradientSignal/Components/SurfaceAltitudeGradientComponent.h>
|
||||
|
||||
namespace GradientSignal
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <GradientSignal/Editor/EditorGradientComponentBase.h>
|
||||
#include <Components/SurfaceMaskGradientComponent.h>
|
||||
#include <GradientSignal/Components/SurfaceMaskGradientComponent.h>
|
||||
|
||||
namespace GradientSignal
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <GradientSignal/Editor/EditorGradientComponentBase.h>
|
||||
#include <Components/SurfaceSlopeGradientComponent.h>
|
||||
#include <GradientSignal/Components/SurfaceSlopeGradientComponent.h>
|
||||
|
||||
namespace GradientSignal
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <GradientSignal/Editor/EditorGradientComponentBase.h>
|
||||
#include <Components/ThresholdGradientComponent.h>
|
||||
#include <GradientSignal/Components/ThresholdGradientComponent.h>
|
||||
|
||||
namespace GradientSignal
|
||||
{
|
||||
|
||||
@@ -9,24 +9,24 @@
|
||||
|
||||
#include <GradientSignalModule.h>
|
||||
#include <GradientSignalSystemComponent.h>
|
||||
#include <Components/SmoothStepGradientComponent.h>
|
||||
#include <Components/SurfaceAltitudeGradientComponent.h>
|
||||
#include <Components/SurfaceSlopeGradientComponent.h>
|
||||
#include <Components/MixedGradientComponent.h>
|
||||
#include <Components/ImageGradientComponent.h>
|
||||
#include <Components/ConstantGradientComponent.h>
|
||||
#include <Components/ThresholdGradientComponent.h>
|
||||
#include <Components/LevelsGradientComponent.h>
|
||||
#include <Components/ReferenceGradientComponent.h>
|
||||
#include <Components/InvertGradientComponent.h>
|
||||
#include <Components/DitherGradientComponent.h>
|
||||
#include <Components/PosterizeGradientComponent.h>
|
||||
#include <Components/ShapeAreaFalloffGradientComponent.h>
|
||||
#include <Components/PerlinGradientComponent.h>
|
||||
#include <Components/RandomGradientComponent.h>
|
||||
#include <Components/GradientTransformComponent.h>
|
||||
#include <Components/SurfaceMaskGradientComponent.h>
|
||||
#include <Components/GradientSurfaceDataComponent.h>
|
||||
#include <GradientSignal/Components/SmoothStepGradientComponent.h>
|
||||
#include <GradientSignal/Components/SurfaceAltitudeGradientComponent.h>
|
||||
#include <GradientSignal/Components/SurfaceSlopeGradientComponent.h>
|
||||
#include <GradientSignal/Components/MixedGradientComponent.h>
|
||||
#include <GradientSignal/Components/ImageGradientComponent.h>
|
||||
#include <GradientSignal/Components/ConstantGradientComponent.h>
|
||||
#include <GradientSignal/Components/ThresholdGradientComponent.h>
|
||||
#include <GradientSignal/Components/LevelsGradientComponent.h>
|
||||
#include <GradientSignal/Components/ReferenceGradientComponent.h>
|
||||
#include <GradientSignal/Components/InvertGradientComponent.h>
|
||||
#include <GradientSignal/Components/DitherGradientComponent.h>
|
||||
#include <GradientSignal/Components/PosterizeGradientComponent.h>
|
||||
#include <GradientSignal/Components/ShapeAreaFalloffGradientComponent.h>
|
||||
#include <GradientSignal/Components/PerlinGradientComponent.h>
|
||||
#include <GradientSignal/Components/RandomGradientComponent.h>
|
||||
#include <GradientSignal/Components/GradientTransformComponent.h>
|
||||
#include <GradientSignal/Components/SurfaceMaskGradientComponent.h>
|
||||
#include <GradientSignal/Components/GradientSurfaceDataComponent.h>
|
||||
|
||||
namespace GradientSignal
|
||||
{
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
#include <AzFramework/Asset/AssetCatalogBus.h>
|
||||
|
||||
#include <Source/Components/ImageGradientComponent.h>
|
||||
#include <Source/Components/PerlinGradientComponent.h>
|
||||
#include <Source/Components/RandomGradientComponent.h>
|
||||
#include <Source/Components/GradientTransformComponent.h>
|
||||
#include <GradientSignal/Components/ImageGradientComponent.h>
|
||||
#include <GradientSignal/Components/PerlinGradientComponent.h>
|
||||
#include <GradientSignal/Components/RandomGradientComponent.h>
|
||||
#include <GradientSignal/Components/GradientTransformComponent.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
#include <AzCore/Math/Vector2.h>
|
||||
#include <AzFramework/Asset/AssetCatalogBus.h>
|
||||
|
||||
#include <Source/Components/ImageGradientComponent.h>
|
||||
#include <Source/Components/GradientTransformComponent.h>
|
||||
#include <GradientSignal/Components/ImageGradientComponent.h>
|
||||
#include <GradientSignal/Components/GradientTransformComponent.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
|
||||
@@ -12,16 +12,16 @@
|
||||
#include <AzCore/Math/MathUtils.h>
|
||||
#include <Tests/GradientSignalTestFixtures.h>
|
||||
|
||||
#include <Source/Components/MixedGradientComponent.h>
|
||||
#include <Source/Components/ReferenceGradientComponent.h>
|
||||
#include <Source/Components/ShapeAreaFalloffGradientComponent.h>
|
||||
#include <Source/Components/SurfaceAltitudeGradientComponent.h>
|
||||
#include <Source/Components/SurfaceMaskGradientComponent.h>
|
||||
#include <Source/Components/SurfaceSlopeGradientComponent.h>
|
||||
#include <Source/Components/RandomGradientComponent.h>
|
||||
#include <Source/Components/ConstantGradientComponent.h>
|
||||
#include <Source/Components/DitherGradientComponent.h>
|
||||
#include <Components/ImageGradientComponent.h>
|
||||
#include <GradientSignal/Components/MixedGradientComponent.h>
|
||||
#include <GradientSignal/Components/ReferenceGradientComponent.h>
|
||||
#include <GradientSignal/Components/ShapeAreaFalloffGradientComponent.h>
|
||||
#include <GradientSignal/Components/SurfaceAltitudeGradientComponent.h>
|
||||
#include <GradientSignal/Components/SurfaceMaskGradientComponent.h>
|
||||
#include <GradientSignal/Components/SurfaceSlopeGradientComponent.h>
|
||||
#include <GradientSignal/Components/RandomGradientComponent.h>
|
||||
#include <GradientSignal/Components/ConstantGradientComponent.h>
|
||||
#include <GradientSignal/Components/DitherGradientComponent.h>
|
||||
#include <GradientSignal/Components/ImageGradientComponent.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
|
||||
#include <AzTest/AzTest.h>
|
||||
|
||||
#include <Source/Components/ConstantGradientComponent.h>
|
||||
#include <Source/Components/DitherGradientComponent.h>
|
||||
#include <Source/Components/InvertGradientComponent.h>
|
||||
#include <GradientSignal/Components/ConstantGradientComponent.h>
|
||||
#include <GradientSignal/Components/DitherGradientComponent.h>
|
||||
#include <GradientSignal/Components/InvertGradientComponent.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
#include <AzCore/Math/MathUtils.h>
|
||||
#include <Tests/GradientSignalTestFixtures.h>
|
||||
|
||||
#include <Source/Components/ConstantGradientComponent.h>
|
||||
#include <Source/Components/GradientSurfaceDataComponent.h>
|
||||
#include <GradientSignal/Components/ConstantGradientComponent.h>
|
||||
#include <GradientSignal/Components/GradientSurfaceDataComponent.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
|
||||
@@ -11,13 +11,13 @@
|
||||
|
||||
#include <GradientSignal/PerlinImprovedNoise.h>
|
||||
#include <GradientSignal/Ebuses/GradientRequestBus.h>
|
||||
#include <Source/Components/PerlinGradientComponent.h>
|
||||
#include <Source/Components/RandomGradientComponent.h>
|
||||
#include <Source/Components/LevelsGradientComponent.h>
|
||||
#include <Source/Components/PosterizeGradientComponent.h>
|
||||
#include <Source/Components/SmoothStepGradientComponent.h>
|
||||
#include <Source/Components/ThresholdGradientComponent.h>
|
||||
#include <Source/Components/GradientTransformComponent.h>
|
||||
#include <GradientSignal/Components/PerlinGradientComponent.h>
|
||||
#include <GradientSignal/Components/RandomGradientComponent.h>
|
||||
#include <GradientSignal/Components/LevelsGradientComponent.h>
|
||||
#include <GradientSignal/Components/PosterizeGradientComponent.h>
|
||||
#include <GradientSignal/Components/SmoothStepGradientComponent.h>
|
||||
#include <GradientSignal/Components/ThresholdGradientComponent.h>
|
||||
#include <GradientSignal/Components/GradientTransformComponent.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include <AzCore/Math/Vector2.h>
|
||||
#include <AZTestShared/Math/MathTestHelpers.h>
|
||||
|
||||
#include <Source/Components/GradientTransformComponent.h>
|
||||
#include <GradientSignal/Components/GradientTransformComponent.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
|
||||
@@ -15,6 +15,24 @@ set(FILES
|
||||
Include/GradientSignal/PerlinImprovedNoise.h
|
||||
Include/GradientSignal/Util.h
|
||||
Include/GradientSignal/GradientImageConversion.h
|
||||
Include/GradientSignal/Components/ConstantGradientComponent.h
|
||||
Include/GradientSignal/Components/DitherGradientComponent.h
|
||||
Include/GradientSignal/Components/GradientSurfaceDataComponent.h
|
||||
Include/GradientSignal/Components/GradientTransformComponent.h
|
||||
Include/GradientSignal/Components/ImageGradientComponent.h
|
||||
Include/GradientSignal/Components/InvertGradientComponent.h
|
||||
Include/GradientSignal/Components/LevelsGradientComponent.h
|
||||
Include/GradientSignal/Components/MixedGradientComponent.h
|
||||
Include/GradientSignal/Components/PerlinGradientComponent.h
|
||||
Include/GradientSignal/Components/PosterizeGradientComponent.h
|
||||
Include/GradientSignal/Components/RandomGradientComponent.h
|
||||
Include/GradientSignal/Components/ReferenceGradientComponent.h
|
||||
Include/GradientSignal/Components/ShapeAreaFalloffGradientComponent.h
|
||||
Include/GradientSignal/Components/SmoothStepGradientComponent.h
|
||||
Include/GradientSignal/Components/SurfaceAltitudeGradientComponent.h
|
||||
Include/GradientSignal/Components/SurfaceMaskGradientComponent.h
|
||||
Include/GradientSignal/Components/SurfaceSlopeGradientComponent.h
|
||||
Include/GradientSignal/Components/ThresholdGradientComponent.h
|
||||
Include/GradientSignal/Ebuses/GradientTransformRequestBus.h
|
||||
Include/GradientSignal/Ebuses/GradientRequestBus.h
|
||||
Include/GradientSignal/Ebuses/GradientPreviewRequestBus.h
|
||||
@@ -40,41 +58,23 @@ set(FILES
|
||||
Include/GradientSignal/Ebuses/GradientSurfaceDataRequestBus.h
|
||||
Include/GradientSignal/Ebuses/SmoothStepRequestBus.h
|
||||
Source/Components/ConstantGradientComponent.cpp
|
||||
Source/Components/ConstantGradientComponent.h
|
||||
Source/Components/DitherGradientComponent.cpp
|
||||
Source/Components/DitherGradientComponent.h
|
||||
Source/Components/GradientSurfaceDataComponent.cpp
|
||||
Source/Components/GradientSurfaceDataComponent.h
|
||||
Source/Components/GradientTransformComponent.cpp
|
||||
Source/Components/GradientTransformComponent.h
|
||||
Source/Components/ImageGradientComponent.cpp
|
||||
Source/Components/ImageGradientComponent.h
|
||||
Source/Components/InvertGradientComponent.cpp
|
||||
Source/Components/InvertGradientComponent.h
|
||||
Source/Components/LevelsGradientComponent.cpp
|
||||
Source/Components/LevelsGradientComponent.h
|
||||
Source/Components/MixedGradientComponent.cpp
|
||||
Source/Components/MixedGradientComponent.h
|
||||
Source/Components/PerlinGradientComponent.cpp
|
||||
Source/Components/PerlinGradientComponent.h
|
||||
Source/Components/PosterizeGradientComponent.cpp
|
||||
Source/Components/PosterizeGradientComponent.h
|
||||
Source/Components/RandomGradientComponent.cpp
|
||||
Source/Components/RandomGradientComponent.h
|
||||
Source/Components/ReferenceGradientComponent.cpp
|
||||
Source/Components/ReferenceGradientComponent.h
|
||||
Source/Components/ShapeAreaFalloffGradientComponent.cpp
|
||||
Source/Components/ShapeAreaFalloffGradientComponent.h
|
||||
Source/Components/SmoothStepGradientComponent.cpp
|
||||
Source/Components/SmoothStepGradientComponent.h
|
||||
Source/Components/SurfaceAltitudeGradientComponent.cpp
|
||||
Source/Components/SurfaceAltitudeGradientComponent.h
|
||||
Source/Components/SurfaceMaskGradientComponent.cpp
|
||||
Source/Components/SurfaceMaskGradientComponent.h
|
||||
Source/Components/SurfaceSlopeGradientComponent.cpp
|
||||
Source/Components/SurfaceSlopeGradientComponent.h
|
||||
Source/Components/ThresholdGradientComponent.cpp
|
||||
Source/Components/ThresholdGradientComponent.h
|
||||
Source/GradientSampler.cpp
|
||||
Source/GradientSignalSystemComponent.cpp
|
||||
Source/GradientSignalSystemComponent.h
|
||||
|
||||
@@ -159,6 +159,12 @@ namespace PhysX
|
||||
AZStd::swap(m_entityTransformHandlers[index], m_entityTransformHandlers.back());
|
||||
m_entityTransformHandlers.pop_back();
|
||||
|
||||
// When deleting entity from handler's m_entities, the AABB should be appended to m_pendingAabbUpdates
|
||||
// for local wind handler to broadcast OnWindChanged to notify relative entities of wind changes in OnTick().
|
||||
m_pendingAabbUpdates.push_back();
|
||||
ColliderShapeRequestBus::EventResult(m_pendingAabbUpdates.back(),
|
||||
entityId, &ColliderShapeRequestBus::Events::GetColliderShapeAabb);
|
||||
|
||||
m_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,6 +119,11 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
|
||||
NAME Gem::Terrain.Tests
|
||||
)
|
||||
|
||||
ly_add_googlebenchmark(
|
||||
NAME Gem::Terrain.Benchmarks
|
||||
TARGET Gem::Terrain.Tests
|
||||
)
|
||||
|
||||
# If we are a host platform we want to add tools test like editor tests here
|
||||
if(PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
# We support Terrain.Editor.Tests on this platform, add Terrain.Editor.Tests target which depends on Terrain.Editor
|
||||
|
||||
@@ -32,6 +32,13 @@ namespace Terrain
|
||||
AZ_RTTI(TerrainSurfaceGradientMapping, "{473AD2CE-F22A-45A9-803F-2192F3D9F2BF}");
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
TerrainSurfaceGradientMapping() = default;
|
||||
TerrainSurfaceGradientMapping(const AZ::EntityId& entityId, const SurfaceData::SurfaceTag& surfaceTag)
|
||||
: m_gradientEntityId(entityId)
|
||||
, m_surfaceTag(surfaceTag)
|
||||
{
|
||||
}
|
||||
|
||||
AZ::EntityId m_gradientEntityId;
|
||||
SurfaceData::SurfaceTag m_surfaceTag;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,421 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_BENCHMARK
|
||||
|
||||
#include <AzCore/Component/ComponentApplication.h>
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzCore/Memory/PoolAllocator.h>
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
#include <AzFramework/Components/TransformComponent.h>
|
||||
#include <AzFramework/Terrain/TerrainDataRequestBus.h>
|
||||
#include <AzTest/AzTest.h>
|
||||
|
||||
#include <GradientSignal/Components/RandomGradientComponent.h>
|
||||
#include <GradientSignal/Components/GradientTransformComponent.h>
|
||||
#include <GradientSignal/Ebuses/GradientRequestBus.h>
|
||||
|
||||
#include <SurfaceData/SurfaceDataTypes.h>
|
||||
|
||||
#include <LmbrCentral/Shape/ShapeComponentBus.h>
|
||||
#include <MockAxisAlignedBoxShapeComponent.h>
|
||||
|
||||
#include <TerrainSystem/TerrainSystem.h>
|
||||
#include <Components/TerrainLayerSpawnerComponent.h>
|
||||
#include <Components/TerrainHeightGradientListComponent.h>
|
||||
#include <Components/TerrainSurfaceGradientListComponent.h>
|
||||
|
||||
#include <benchmark/benchmark.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
using ::testing::NiceMock;
|
||||
using ::testing::Return;
|
||||
|
||||
class TerrainSystemBenchmarkFixture
|
||||
: public UnitTest::AllocatorsBenchmarkFixture
|
||||
, public UnitTest::TraceBusRedirector
|
||||
{
|
||||
public:
|
||||
void SetUp(const benchmark::State& state) override
|
||||
{
|
||||
InternalSetUp(state);
|
||||
}
|
||||
void SetUp(benchmark::State& state) override
|
||||
{
|
||||
InternalSetUp(state);
|
||||
}
|
||||
|
||||
void TearDown(const benchmark::State& state) override
|
||||
{
|
||||
InternalTearDown(state);
|
||||
}
|
||||
void TearDown(benchmark::State& state) override
|
||||
{
|
||||
InternalTearDown(state);
|
||||
}
|
||||
|
||||
void InternalSetUp(const benchmark::State& state)
|
||||
{
|
||||
AZ::Debug::TraceMessageBus::Handler::BusConnect();
|
||||
UnitTest::AllocatorsBenchmarkFixture::SetUp(state);
|
||||
|
||||
m_app = AZStd::make_unique<AZ::ComponentApplication>();
|
||||
ASSERT_TRUE(m_app != nullptr);
|
||||
|
||||
AZ::ComponentApplication::Descriptor componentAppDesc;
|
||||
|
||||
AZ::Entity* systemEntity = m_app->Create(componentAppDesc);
|
||||
ASSERT_TRUE(systemEntity != nullptr);
|
||||
m_app->AddEntity(systemEntity);
|
||||
|
||||
AZ::AllocatorInstance<AZ::ThreadPoolAllocator>::Create();
|
||||
}
|
||||
|
||||
void InternalTearDown(const benchmark::State& state)
|
||||
{
|
||||
AZ::AllocatorInstance<AZ::ThreadPoolAllocator>::Destroy();
|
||||
|
||||
m_app->Destroy();
|
||||
m_app.reset();
|
||||
|
||||
UnitTest::AllocatorsBenchmarkFixture::TearDown(state);
|
||||
AZ::Debug::TraceMessageBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
AZStd::unique_ptr<AZ::Entity> CreateEntity()
|
||||
{
|
||||
return AZStd::make_unique<AZ::Entity>();
|
||||
}
|
||||
|
||||
void ActivateEntity(AZ::Entity* entity)
|
||||
{
|
||||
entity->Init();
|
||||
entity->Activate();
|
||||
}
|
||||
|
||||
template<typename Component, typename Configuration>
|
||||
Component* CreateComponent(AZ::Entity* entity, const Configuration& config)
|
||||
{
|
||||
m_app->RegisterComponentDescriptor(Component::CreateDescriptor());
|
||||
return entity->CreateComponent<Component>(config);
|
||||
}
|
||||
|
||||
template<typename Component>
|
||||
Component* CreateComponent(AZ::Entity* entity)
|
||||
{
|
||||
m_app->RegisterComponentDescriptor(Component::CreateDescriptor());
|
||||
return entity->CreateComponent<Component>();
|
||||
}
|
||||
|
||||
// Create a terrain system with reasonable defaults for testing, but with the ability to override the defaults
|
||||
// on a test-by-test basis.
|
||||
AZStd::unique_ptr<Terrain::TerrainSystem> CreateAndActivateTerrainSystem(
|
||||
AZ::Vector2 queryResolution = AZ::Vector2(1.0f),
|
||||
AZ::Aabb worldBounds = AZ::Aabb::CreateFromMinMax(AZ::Vector3(-128.0f), AZ::Vector3(128.0f)))
|
||||
{
|
||||
// Create the terrain system and give it one tick to fully initialize itself.
|
||||
auto terrainSystem = AZStd::make_unique<Terrain::TerrainSystem>();
|
||||
terrainSystem->SetTerrainAabb(worldBounds);
|
||||
terrainSystem->SetTerrainHeightQueryResolution(queryResolution);
|
||||
terrainSystem->Activate();
|
||||
AZ::TickBus::Broadcast(&AZ::TickBus::Events::OnTick, 0.f, AZ::ScriptTimePoint{});
|
||||
return terrainSystem;
|
||||
}
|
||||
|
||||
// Create a mock shape bus listener that will listen to the given EntityId for shape requests and returns the following:
|
||||
// - GetEncompassingAabb - returns the given Aabb
|
||||
// - GetTransformAndLocalBounds - returns the center of the Aabb as the transform, and the size of the Aabb as the local bounds
|
||||
// - IsPointInside - true if the point is in the Aabb, false if not
|
||||
AZStd::unique_ptr<NiceMock<UnitTest::MockShapeComponentRequests>> CreateMockShape(
|
||||
const AZ::Aabb& spawnerBox, const AZ::EntityId& shapeEntityId)
|
||||
{
|
||||
AZStd::unique_ptr<NiceMock<UnitTest::MockShapeComponentRequests>> mockShape =
|
||||
AZStd::make_unique<NiceMock<UnitTest::MockShapeComponentRequests>>(shapeEntityId);
|
||||
|
||||
ON_CALL(*mockShape, GetEncompassingAabb).WillByDefault(Return(spawnerBox));
|
||||
ON_CALL(*mockShape, GetTransformAndLocalBounds)
|
||||
.WillByDefault(
|
||||
[spawnerBox](AZ::Transform& transform, AZ::Aabb& bounds)
|
||||
{
|
||||
transform = AZ::Transform::CreateTranslation(spawnerBox.GetCenter());
|
||||
bounds = spawnerBox.GetTranslated(-spawnerBox.GetCenter());
|
||||
});
|
||||
ON_CALL(*mockShape, IsPointInside)
|
||||
.WillByDefault(
|
||||
[spawnerBox](const AZ::Vector3& point) -> bool
|
||||
{
|
||||
return spawnerBox.Contains(point);
|
||||
});
|
||||
|
||||
return mockShape;
|
||||
}
|
||||
|
||||
// Create an entity with a Random Gradient on it that can be used for gradient queries.
|
||||
AZStd::unique_ptr<AZ::Entity> CreateTestRandomGradientEntity(const AZ::Aabb& spawnerBox, uint32_t randomSeed)
|
||||
{
|
||||
// Create the base entity
|
||||
AZStd::unique_ptr<AZ::Entity> testGradientEntity = CreateEntity();
|
||||
|
||||
// Add a mock AABB Shape so that the shape requirement is fulfilled.
|
||||
CreateComponent<UnitTest::MockAxisAlignedBoxShapeComponent>(testGradientEntity.get());
|
||||
|
||||
// Create the Random Gradient Component with some default parameters.
|
||||
GradientSignal::RandomGradientConfig config;
|
||||
config.m_randomSeed = randomSeed;
|
||||
CreateComponent<GradientSignal::RandomGradientComponent>(testGradientEntity.get(), config);
|
||||
|
||||
// Create the Gradient Transform Component with some default parameters.
|
||||
GradientSignal::GradientTransformConfig gradientTransformConfig;
|
||||
gradientTransformConfig.m_wrappingType = GradientSignal::WrappingType::None;
|
||||
CreateComponent<GradientSignal::GradientTransformComponent>(testGradientEntity.get(), gradientTransformConfig);
|
||||
|
||||
// Set the transform to match the given spawnerBox
|
||||
auto transform = CreateComponent<AzFramework::TransformComponent>(testGradientEntity.get());
|
||||
transform->SetLocalTM(AZ::Transform::CreateTranslation(spawnerBox.GetCenter()));
|
||||
transform->SetWorldTM(AZ::Transform::CreateTranslation(spawnerBox.GetCenter()));
|
||||
|
||||
return testGradientEntity;
|
||||
}
|
||||
|
||||
AZStd::unique_ptr<AZ::Entity> CreateTestLayerSpawnerEntity(
|
||||
const AZ::Aabb& spawnerBox, const AZ::EntityId& heightGradientEntityId,
|
||||
const Terrain::TerrainSurfaceGradientListConfig& surfaceConfig)
|
||||
{
|
||||
// Create the base entity
|
||||
AZStd::unique_ptr<AZ::Entity> testLayerSpawnerEntity = CreateEntity();
|
||||
|
||||
// Add a mock AABB Shape so that the shape requirement is fulfilled.
|
||||
CreateComponent<UnitTest::MockAxisAlignedBoxShapeComponent>(testLayerSpawnerEntity.get());
|
||||
|
||||
// Add a Terrain Layer Spawner
|
||||
CreateComponent<Terrain::TerrainLayerSpawnerComponent>(testLayerSpawnerEntity.get());
|
||||
|
||||
// Add a Terrain Height Gradient List with one entry pointing to the given gradient entity
|
||||
Terrain::TerrainHeightGradientListConfig heightConfig;
|
||||
heightConfig.m_gradientEntities.emplace_back(heightGradientEntityId);
|
||||
CreateComponent<Terrain::TerrainHeightGradientListComponent>(testLayerSpawnerEntity.get(), heightConfig);
|
||||
|
||||
// Add a Terrain Surface Gradient List with however many entries we were given
|
||||
CreateComponent<Terrain::TerrainSurfaceGradientListComponent>(testLayerSpawnerEntity.get(), surfaceConfig);
|
||||
|
||||
// Set the transform to match the given spawnerBox
|
||||
auto transform = CreateComponent<AzFramework::TransformComponent>(testLayerSpawnerEntity.get());
|
||||
transform->SetLocalTM(AZ::Transform::CreateTranslation(spawnerBox.GetCenter()));
|
||||
transform->SetWorldTM(AZ::Transform::CreateTranslation(spawnerBox.GetCenter()));
|
||||
|
||||
return testLayerSpawnerEntity;
|
||||
}
|
||||
|
||||
void RunTerrainApiBenchmark(
|
||||
benchmark::State& state,
|
||||
AZStd::function<void(
|
||||
const AZ::Vector2& queryResolution,
|
||||
const AZ::Aabb& worldBounds,
|
||||
AzFramework::Terrain::TerrainDataRequests::Sampler sampler)> ApiCaller)
|
||||
{
|
||||
// Get the ranges for querying from our benchmark parameters
|
||||
float boundsRange = aznumeric_cast<float>(state.range(0));
|
||||
uint32_t numSurfaces = aznumeric_cast<uint32_t>(state.range(1));
|
||||
AzFramework::Terrain::TerrainDataRequests::Sampler sampler =
|
||||
static_cast<AzFramework::Terrain::TerrainDataRequests::Sampler>(state.range(2));
|
||||
|
||||
// Set up our world bounds and query resolution
|
||||
AZ::Aabb worldBounds = AZ::Aabb::CreateFromMinMax(AZ::Vector3(-boundsRange / 2.0f), AZ::Vector3(boundsRange / 2.0f));
|
||||
AZ::Vector2 queryResolution = AZ::Vector2(1.0f);
|
||||
|
||||
// Create a Random Gradient to use as our height provider
|
||||
const uint32_t heightRandomSeed = 12345;
|
||||
auto heightGradientEntity = CreateTestRandomGradientEntity(worldBounds, heightRandomSeed);
|
||||
auto heightGradientShapeRequests = CreateMockShape(worldBounds, heightGradientEntity->GetId());
|
||||
ActivateEntity(heightGradientEntity.get());
|
||||
|
||||
|
||||
// Create a set of Random Gradients to use as our surface providers
|
||||
Terrain::TerrainSurfaceGradientListConfig surfaceConfig;
|
||||
AZStd::vector<AZStd::unique_ptr<AZ::Entity>> surfaceGradientEntities;
|
||||
AZStd::vector<AZStd::unique_ptr<NiceMock<UnitTest::MockShapeComponentRequests>>> surfaceGradientShapeRequests;
|
||||
for (uint32_t surfaces = 0; surfaces < numSurfaces; surfaces++)
|
||||
{
|
||||
const uint32_t surfaceRandomSeed = 23456 + surfaces;
|
||||
auto surfaceGradientEntity = CreateTestRandomGradientEntity(worldBounds, surfaceRandomSeed);
|
||||
auto shapeRequests = CreateMockShape(worldBounds, surfaceGradientEntity->GetId());
|
||||
ActivateEntity(surfaceGradientEntity.get());
|
||||
|
||||
// Give each gradient a new surface tag
|
||||
surfaceConfig.m_gradientSurfaceMappings.emplace_back(
|
||||
surfaceGradientEntity->GetId(), SurfaceData::SurfaceTag(AZStd::string::format("test%u", surfaces)));
|
||||
|
||||
surfaceGradientEntities.emplace_back(AZStd::move(surfaceGradientEntity));
|
||||
surfaceGradientShapeRequests.emplace_back(AZStd::move(shapeRequests));
|
||||
}
|
||||
|
||||
// Create a single Terrain Layer Spawner that covers the entire terrain world bounds
|
||||
// (Do this *after* creating and activating the height and surface gradients)
|
||||
auto testLayerSpawnerEntity = CreateTestLayerSpawnerEntity(worldBounds, heightGradientEntity->GetId(), surfaceConfig);
|
||||
auto spawnerShapeRequests = CreateMockShape(worldBounds, testLayerSpawnerEntity->GetId());
|
||||
ActivateEntity(testLayerSpawnerEntity.get());
|
||||
|
||||
// Create the terrain system (do this after creating the terrain layer entity to ensure that we don't need any data refreshes)
|
||||
auto terrainSystem = CreateAndActivateTerrainSystem(queryResolution, worldBounds);
|
||||
|
||||
// Call the terrain API we're testing for every height and width in our ranges.
|
||||
for (auto stateIterator : state)
|
||||
{
|
||||
ApiCaller(queryResolution, worldBounds, sampler);
|
||||
}
|
||||
|
||||
testLayerSpawnerEntity.reset();
|
||||
spawnerShapeRequests.reset();
|
||||
|
||||
heightGradientEntity.reset();
|
||||
heightGradientShapeRequests.reset();
|
||||
|
||||
surfaceGradientEntities.clear();
|
||||
surfaceGradientShapeRequests.clear();
|
||||
}
|
||||
|
||||
protected:
|
||||
AZStd::unique_ptr<AZ::ComponentApplication> m_app;
|
||||
};
|
||||
|
||||
|
||||
BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_GetHeight)(benchmark::State& state)
|
||||
{
|
||||
// Run the benchmark
|
||||
RunTerrainApiBenchmark(
|
||||
state,
|
||||
[]([[maybe_unused]] const AZ::Vector2& queryResolution, const AZ::Aabb& worldBounds,
|
||||
AzFramework::Terrain::TerrainDataRequests::Sampler sampler)
|
||||
{
|
||||
float worldMinZ = worldBounds.GetMin().GetZ();
|
||||
|
||||
for (float y = worldBounds.GetMin().GetY(); y < worldBounds.GetMax().GetY(); y += 1.0f)
|
||||
{
|
||||
for (float x = worldBounds.GetMin().GetX(); x < worldBounds.GetMax().GetX(); x += 1.0f)
|
||||
{
|
||||
float terrainHeight = worldMinZ;
|
||||
bool terrainExists = false;
|
||||
AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult(
|
||||
terrainHeight, &AzFramework::Terrain::TerrainDataRequests::GetHeightFromFloats, x, y, sampler, &terrainExists);
|
||||
benchmark::DoNotOptimize(terrainHeight);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_GetHeight)
|
||||
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
||||
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
||||
->Args({ 4096, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
||||
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
||||
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
||||
->Args({ 4096, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
||||
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
||||
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
||||
->Args({ 4096, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
||||
->Unit(::benchmark::kMillisecond);
|
||||
|
||||
BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_GetNormal)(benchmark::State& state)
|
||||
{
|
||||
// Run the benchmark
|
||||
RunTerrainApiBenchmark(
|
||||
state,
|
||||
[]([[maybe_unused]] const AZ::Vector2& queryResolution, const AZ::Aabb& worldBounds,
|
||||
AzFramework::Terrain::TerrainDataRequests::Sampler sampler)
|
||||
{
|
||||
for (float y = worldBounds.GetMin().GetY(); y < worldBounds.GetMax().GetY(); y += 1.0f)
|
||||
{
|
||||
for (float x = worldBounds.GetMin().GetX(); x < worldBounds.GetMax().GetX(); x += 1.0f)
|
||||
{
|
||||
AZ::Vector3 terrainNormal;
|
||||
bool terrainExists = false;
|
||||
AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult(
|
||||
terrainNormal, &AzFramework::Terrain::TerrainDataRequests::GetNormalFromFloats, x, y, sampler, &terrainExists);
|
||||
benchmark::DoNotOptimize(terrainNormal);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_GetNormal)
|
||||
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
||||
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
||||
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
||||
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
||||
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
||||
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
||||
->Unit(::benchmark::kMillisecond);
|
||||
|
||||
BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_GetSurfaceWeights)(benchmark::State& state)
|
||||
{
|
||||
// Run the benchmark
|
||||
RunTerrainApiBenchmark(
|
||||
state,
|
||||
[]([[maybe_unused]] const AZ::Vector2& queryResolution, const AZ::Aabb& worldBounds,
|
||||
AzFramework::Terrain::TerrainDataRequests::Sampler sampler)
|
||||
{
|
||||
AzFramework::SurfaceData::SurfaceTagWeightList surfaceWeights;
|
||||
for (float y = worldBounds.GetMin().GetY(); y < worldBounds.GetMax().GetY(); y += 1.0f)
|
||||
{
|
||||
for (float x = worldBounds.GetMin().GetX(); x < worldBounds.GetMax().GetX(); x += 1.0f)
|
||||
{
|
||||
bool terrainExists = false;
|
||||
AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
|
||||
&AzFramework::Terrain::TerrainDataRequests::GetSurfaceWeightsFromFloats, x, y, surfaceWeights, sampler,
|
||||
&terrainExists);
|
||||
benchmark::DoNotOptimize(surfaceWeights);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_GetSurfaceWeights)
|
||||
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
||||
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
||||
->Args({ 1024, 2, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
||||
->Args({ 2048, 2, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
||||
->Args({ 1024, 4, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
||||
->Args({ 2048, 4, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
||||
->Unit(::benchmark::kMillisecond);
|
||||
|
||||
BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_GetSurfacePoints)(benchmark::State& state)
|
||||
{
|
||||
// Run the benchmark
|
||||
RunTerrainApiBenchmark(
|
||||
state,
|
||||
[]([[maybe_unused]] const AZ::Vector2& queryResolution, const AZ::Aabb& worldBounds,
|
||||
AzFramework::Terrain::TerrainDataRequests::Sampler sampler)
|
||||
{
|
||||
AzFramework::SurfaceData::SurfacePoint surfacePoint;
|
||||
for (float y = worldBounds.GetMin().GetY(); y < worldBounds.GetMax().GetY(); y += 1.0f)
|
||||
{
|
||||
for (float x = worldBounds.GetMin().GetX(); x < worldBounds.GetMax().GetX(); x += 1.0f)
|
||||
{
|
||||
bool terrainExists = false;
|
||||
AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
|
||||
&AzFramework::Terrain::TerrainDataRequests::GetSurfacePointFromFloats, x, y, surfacePoint, sampler,
|
||||
&terrainExists);
|
||||
benchmark::DoNotOptimize(surfacePoint);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_GetSurfacePoints)
|
||||
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
||||
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
||||
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
||||
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
||||
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
||||
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
||||
->Unit(::benchmark::kMillisecond);
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -16,4 +16,5 @@ set(FILES
|
||||
Tests/TerrainHeightGradientListTests.cpp
|
||||
Tests/TerrainMacroMaterialTests.cpp
|
||||
Tests/TerrainSurfaceGradientListTests.cpp
|
||||
Tests/TerrainSystemBenchmarks.cpp
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user