Merge pull request #5752 from aws-lumberyard-dev/puvvadar/gitflow_211118_o3de
Merge stabilization/2110
This commit is contained in:
+78
-70
@@ -1016,6 +1016,55 @@ namespace AZ::AtomBridge
|
||||
}
|
||||
}
|
||||
|
||||
void AtomDebugDisplayViewportInterface::DrawWireCylinderNoEnds(const AZ::Vector3& center, const AZ::Vector3& axis, float radius, float height)
|
||||
{
|
||||
if (m_auxGeomPtr)
|
||||
{
|
||||
const float scale = GetCurrentTransform().RetrieveScale().GetMaxElement();
|
||||
const AZ::Vector3 worldCenter = ToWorldSpacePosition(center);
|
||||
const AZ::Vector3 worldAxis = ToWorldSpaceVector(axis);
|
||||
m_auxGeomPtr->DrawCylinderNoEnds(
|
||||
worldCenter,
|
||||
worldAxis,
|
||||
scale * radius,
|
||||
scale * height,
|
||||
m_rendState.m_color,
|
||||
AZ::RPI::AuxGeomDraw::DrawStyle::Line,
|
||||
m_rendState.m_depthTest,
|
||||
m_rendState.m_depthWrite,
|
||||
m_rendState.m_faceCullMode,
|
||||
m_rendState.m_viewProjOverrideIndex
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void AtomDebugDisplayViewportInterface::DrawSolidCylinderNoEnds(
|
||||
const AZ::Vector3& center,
|
||||
const AZ::Vector3& axis,
|
||||
float radius,
|
||||
float height,
|
||||
bool drawShaded)
|
||||
{
|
||||
if (m_auxGeomPtr)
|
||||
{
|
||||
const float scale = GetCurrentTransform().RetrieveScale().GetMaxElement();
|
||||
const AZ::Vector3 worldCenter = ToWorldSpacePosition(center);
|
||||
const AZ::Vector3 worldAxis = ToWorldSpaceVector(axis);
|
||||
m_auxGeomPtr->DrawCylinderNoEnds(
|
||||
worldCenter,
|
||||
worldAxis,
|
||||
scale * radius,
|
||||
scale * height,
|
||||
m_rendState.m_color,
|
||||
drawShaded ? AZ::RPI::AuxGeomDraw::DrawStyle::Shaded : AZ::RPI::AuxGeomDraw::DrawStyle::Solid,
|
||||
m_rendState.m_depthTest,
|
||||
m_rendState.m_depthWrite,
|
||||
m_rendState.m_faceCullMode,
|
||||
m_rendState.m_viewProjOverrideIndex
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void AtomDebugDisplayViewportInterface::DrawWireCapsule(
|
||||
const AZ::Vector3& center,
|
||||
const AZ::Vector3& axis,
|
||||
@@ -1025,83 +1074,24 @@ namespace AZ::AtomBridge
|
||||
if (m_auxGeomPtr && radius > FLT_EPSILON && axis.GetLengthSq() > FLT_EPSILON)
|
||||
{
|
||||
AZ::Vector3 axisNormalized = axis.GetNormalizedEstimate();
|
||||
SingleColorStaticSizeLineHelper<(16+1) * 5> lines; // 360/22.5 = 16, 5 possible calls to CreateArbitraryAxisArc
|
||||
AZ::Vector3 radiusV3 = AZ::Vector3(radius);
|
||||
float stepAngle = DegToRad(22.5f);
|
||||
float Deg0 = DegToRad(0.0f);
|
||||
|
||||
const float scale = GetCurrentTransform().RetrieveScale().GetMaxElement();
|
||||
const AZ::Vector3 worldCenter = ToWorldSpacePosition(center);
|
||||
const AZ::Vector3 worldAxis = ToWorldSpaceVector(axis);
|
||||
|
||||
// Draw cylinder part (or just a circle around the middle)
|
||||
// Draw cylinder part (if cylinder height is too small, ignore cylinder and just draw both hemispheres)
|
||||
if (heightStraightSection > FLT_EPSILON)
|
||||
{
|
||||
DrawWireCylinder(center, axis, radius, heightStraightSection);
|
||||
}
|
||||
else
|
||||
{
|
||||
float Deg360 = DegToRad(360.0f);
|
||||
CreateArbitraryAxisArc(
|
||||
lines,
|
||||
stepAngle,
|
||||
Deg0,
|
||||
Deg360,
|
||||
center,
|
||||
radiusV3,
|
||||
axisNormalized
|
||||
);
|
||||
DrawWireCylinderNoEnds(worldCenter, worldAxis, scale * radius, scale * heightStraightSection);
|
||||
}
|
||||
|
||||
float Deg90 = DegToRad(90.0f);
|
||||
float Deg180 = DegToRad(180.0f);
|
||||
|
||||
AZ::Vector3 ortho1Normalized, ortho2Normalized;
|
||||
CalcBasisVectors(axisNormalized, ortho1Normalized, ortho2Normalized);
|
||||
AZ::Vector3 centerToTopCircleCenter = axisNormalized * heightStraightSection * 0.5f;
|
||||
AZ::Vector3 topCenter = center + centerToTopCircleCenter;
|
||||
AZ::Vector3 bottomCenter = center - centerToTopCircleCenter;
|
||||
|
||||
// Draw top cap as two criss-crossing 180deg arcs
|
||||
CreateArbitraryAxisArc(
|
||||
lines,
|
||||
stepAngle,
|
||||
Deg90,
|
||||
Deg90 + Deg180,
|
||||
topCenter,
|
||||
radiusV3,
|
||||
ortho1Normalized
|
||||
);
|
||||
// Top hemisphere
|
||||
DrawWireHemisphere(center + centerToTopCircleCenter, worldAxis, scale * radius);
|
||||
|
||||
CreateArbitraryAxisArc(
|
||||
lines,
|
||||
stepAngle,
|
||||
Deg180,
|
||||
Deg180 + Deg180,
|
||||
topCenter,
|
||||
radiusV3,
|
||||
ortho2Normalized
|
||||
);
|
||||
|
||||
// Draw bottom cap
|
||||
CreateArbitraryAxisArc(
|
||||
lines,
|
||||
stepAngle,
|
||||
-Deg90,
|
||||
-Deg90 + Deg180,
|
||||
bottomCenter,
|
||||
radiusV3,
|
||||
ortho1Normalized
|
||||
);
|
||||
|
||||
CreateArbitraryAxisArc(
|
||||
lines,
|
||||
stepAngle,
|
||||
Deg0,
|
||||
Deg0 + Deg180,
|
||||
bottomCenter,
|
||||
radiusV3,
|
||||
ortho2Normalized
|
||||
);
|
||||
|
||||
lines.Draw(m_auxGeomPtr, m_rendState);
|
||||
// Bottom hemisphere
|
||||
DrawWireHemisphere(center - centerToTopCircleCenter, -worldAxis, scale * radius);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1148,6 +1138,25 @@ namespace AZ::AtomBridge
|
||||
}
|
||||
}
|
||||
|
||||
void AtomDebugDisplayViewportInterface::DrawWireHemisphere(const AZ::Vector3& pos, const AZ::Vector3& axis, float radius)
|
||||
{
|
||||
if (m_auxGeomPtr)
|
||||
{
|
||||
const float scale = GetCurrentTransform().RetrieveScale().GetMaxElement();
|
||||
m_auxGeomPtr->DrawHemisphere(
|
||||
ToWorldSpacePosition(pos),
|
||||
axis,
|
||||
scale * radius,
|
||||
m_rendState.m_color,
|
||||
AZ::RPI::AuxGeomDraw::DrawStyle::Line,
|
||||
m_rendState.m_depthTest,
|
||||
m_rendState.m_depthWrite,
|
||||
m_rendState.m_faceCullMode,
|
||||
m_rendState.m_viewProjOverrideIndex
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void AtomDebugDisplayViewportInterface::DrawWireDisk(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius)
|
||||
{
|
||||
if (m_auxGeomPtr)
|
||||
@@ -1353,9 +1362,8 @@ namespace AZ::AtomBridge
|
||||
// if 2d draw need to project pos to screen first
|
||||
AzFramework::TextDrawParameters params;
|
||||
AZ::RPI::ViewportContextPtr viewportContext = GetViewportContext();
|
||||
const auto dpiScaleFactor = viewportContext->GetDpiScalingFactor();
|
||||
params.m_drawViewportId = viewportContext->GetId(); // get the viewport ID so default viewport works
|
||||
params.m_position = AZ::Vector3(x * dpiScaleFactor, y * dpiScaleFactor, 1.0f);
|
||||
params.m_position = AZ::Vector3(x, y, 1.0f);
|
||||
params.m_color = m_rendState.m_color;
|
||||
params.m_scale = AZ::Vector2(size);
|
||||
params.m_hAlign = center ? AzFramework::TextHorizontalAlignment::Center : AzFramework::TextHorizontalAlignment::Left; //! Horizontal text alignment
|
||||
|
||||
@@ -168,9 +168,12 @@ namespace AZ::AtomBridge
|
||||
void DrawSolidCone(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius, float height, bool drawShaded) override;
|
||||
void DrawWireCylinder(const AZ::Vector3& center, const AZ::Vector3& axis, float radius, float height) override;
|
||||
void DrawSolidCylinder(const AZ::Vector3& center, const AZ::Vector3& axis, float radius, float height, bool drawShaded) override;
|
||||
void DrawWireCylinderNoEnds(const AZ::Vector3& center, const AZ::Vector3& axis, float radius, float height) override;
|
||||
void DrawSolidCylinderNoEnds(const AZ::Vector3& center, const AZ::Vector3& axis, float radius, float height, bool drawShaded) override;
|
||||
void DrawWireCapsule(const AZ::Vector3& center, const AZ::Vector3& axis, float radius, float heightStraightSection) override;
|
||||
void DrawWireSphere(const AZ::Vector3& pos, float radius) override;
|
||||
void DrawWireSphere(const AZ::Vector3& pos, const AZ::Vector3 radius) override;
|
||||
void DrawWireHemisphere(const AZ::Vector3& pos, const AZ::Vector3& axis, float radius) override;
|
||||
void DrawWireDisk(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius) override;
|
||||
void DrawBall(const AZ::Vector3& pos, float radius, bool drawShaded) override;
|
||||
void DrawDisk(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius) override;
|
||||
|
||||
+7
@@ -132,6 +132,13 @@ namespace AZ
|
||||
//! Sets the Esm exponent. Higher values produce a steeper falloff between light and shadow.
|
||||
virtual void SetEsmExponent(float exponent) = 0;
|
||||
|
||||
//! Reduces acne by biasing the shadowmap lookup along the geometric normal.
|
||||
//! @return Returns the amount of bias to apply.
|
||||
virtual float GetNormalShadowBias() const = 0;
|
||||
|
||||
//! 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;
|
||||
};
|
||||
|
||||
//! The EBus for requests to for setting and getting light component properties.
|
||||
|
||||
+1
@@ -57,6 +57,7 @@ namespace AZ
|
||||
// Shadows (only used for supported shapes)
|
||||
bool m_enableShadow = false;
|
||||
float m_bias = 0.1f;
|
||||
float m_normalShadowBias = 0.0f;
|
||||
ShadowmapSize m_shadowmapMaxSize = ShadowmapSize::Size256;
|
||||
ShadowFilterMethod m_shadowFilterMethod = ShadowFilterMethod::None;
|
||||
uint16_t m_filteringSampleCount = 12;
|
||||
|
||||
+1
@@ -34,6 +34,7 @@ namespace AZ
|
||||
// Shadows
|
||||
->Field("Enable Shadow", &AreaLightComponentConfig::m_enableShadow)
|
||||
->Field("Shadow Bias", &AreaLightComponentConfig::m_bias)
|
||||
->Field("Normal Shadow Bias", &AreaLightComponentConfig::m_normalShadowBias)
|
||||
->Field("Shadowmap Max Size", &AreaLightComponentConfig::m_shadowmapMaxSize)
|
||||
->Field("Shadow Filter Method", &AreaLightComponentConfig::m_shadowFilterMethod)
|
||||
->Field("Filtering Sample Count", &AreaLightComponentConfig::m_filteringSampleCount)
|
||||
|
||||
+18
@@ -70,6 +70,8 @@ namespace AZ::Render
|
||||
->Event("SetEnableShadow", &AreaLightRequestBus::Events::SetEnableShadow)
|
||||
->Event("GetShadowBias", &AreaLightRequestBus::Events::GetShadowBias)
|
||||
->Event("SetShadowBias", &AreaLightRequestBus::Events::SetShadowBias)
|
||||
->Event("GetNormalShadowBias", &AreaLightRequestBus::Events::GetNormalShadowBias)
|
||||
->Event("SetNormalShadowBias", &AreaLightRequestBus::Events::SetNormalShadowBias)
|
||||
->Event("GetShadowmapMaxSize", &AreaLightRequestBus::Events::GetShadowmapMaxSize)
|
||||
->Event("SetShadowmapMaxSize", &AreaLightRequestBus::Events::SetShadowmapMaxSize)
|
||||
->Event("GetShadowFilterMethod", &AreaLightRequestBus::Events::GetShadowFilterMethod)
|
||||
@@ -91,6 +93,7 @@ namespace AZ::Render
|
||||
|
||||
->VirtualProperty("ShadowsEnabled", "GetEnableShadow", "SetEnableShadow")
|
||||
->VirtualProperty("ShadowBias", "GetShadowBias", "SetShadowBias")
|
||||
->VirtualProperty("NormalShadowBias", "GetNormalShadowBias", "SetNormalShadowBias")
|
||||
->VirtualProperty("ShadowmapMaxSize", "GetShadowmapMaxSize", "SetShadowmapMaxSize")
|
||||
->VirtualProperty("ShadowFilterMethod", "GetShadowFilterMethod", "SetShadowFilterMethod")
|
||||
->VirtualProperty("FilteringSampleCount", "GetFilteringSampleCount", "SetFilteringSampleCount")
|
||||
@@ -302,6 +305,7 @@ namespace AZ::Render
|
||||
if (m_configuration.m_enableShadow)
|
||||
{
|
||||
m_lightShapeDelegate->SetShadowBias(m_configuration.m_bias);
|
||||
m_lightShapeDelegate->SetNormalShadowBias(m_configuration.m_normalShadowBias);
|
||||
m_lightShapeDelegate->SetShadowmapMaxSize(m_configuration.m_shadowmapMaxSize);
|
||||
m_lightShapeDelegate->SetShadowFilterMethod(m_configuration.m_shadowFilterMethod);
|
||||
m_lightShapeDelegate->SetFilteringSampleCount(m_configuration.m_filteringSampleCount);
|
||||
@@ -474,6 +478,20 @@ namespace AZ::Render
|
||||
}
|
||||
}
|
||||
|
||||
void AreaLightComponentController::SetNormalShadowBias(float bias)
|
||||
{
|
||||
m_configuration.m_normalShadowBias = bias;
|
||||
if (m_lightShapeDelegate)
|
||||
{
|
||||
m_lightShapeDelegate->SetNormalShadowBias(bias);
|
||||
}
|
||||
}
|
||||
|
||||
float AreaLightComponentController::GetNormalShadowBias() const
|
||||
{
|
||||
return m_configuration.m_normalShadowBias;
|
||||
}
|
||||
|
||||
ShadowmapSize AreaLightComponentController::GetShadowmapMaxSize() const
|
||||
{
|
||||
return m_configuration.m_shadowmapMaxSize;
|
||||
|
||||
+2
@@ -86,6 +86,8 @@ namespace AZ
|
||||
void SetFilteringSampleCount(uint32_t count) override;
|
||||
float GetEsmExponent() const override;
|
||||
void SetEsmExponent(float exponent) override;
|
||||
float GetNormalShadowBias() const override;
|
||||
void SetNormalShadowBias(float bias) override;
|
||||
|
||||
void HandleDisplayEntityViewport(
|
||||
const AzFramework::ViewportInfo& viewportInfo,
|
||||
|
||||
@@ -138,6 +138,14 @@ namespace AZ::Render
|
||||
}
|
||||
}
|
||||
|
||||
void DiskLightDelegate::SetNormalShadowBias(float bias)
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
{
|
||||
GetFeatureProcessor()->SetNormalShadowBias(GetLightHandle(), bias);
|
||||
}
|
||||
}
|
||||
|
||||
void DiskLightDelegate::SetShadowmapMaxSize(ShadowmapSize size)
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
|
||||
@@ -46,6 +46,7 @@ namespace AZ
|
||||
void SetShadowFilterMethod(ShadowFilterMethod method) override;
|
||||
void SetFilteringSampleCount(uint32_t count) override;
|
||||
void SetEsmExponent(float exponent) override;
|
||||
void SetNormalShadowBias(float bias) override;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
+11
-2
@@ -136,7 +136,7 @@ namespace AZ
|
||||
->Attribute(Edit::Attributes::Min, 0.0f)
|
||||
->Attribute(Edit::Attributes::Max, 100.0f)
|
||||
->Attribute(Edit::Attributes::SoftMin, 0.0f)
|
||||
->Attribute(Edit::Attributes::SoftMax, 2.0f)
|
||||
->Attribute(Edit::Attributes::SoftMax, 10.0f)
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::ShadowsDisabled)
|
||||
@@ -171,7 +171,16 @@ namespace AZ
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::IsEsmDisabled)
|
||||
;
|
||||
->DataElement(
|
||||
Edit::UIHandlers::Slider, &AreaLightComponentConfig::m_normalShadowBias, "Normal Shadow Bias\n",
|
||||
"Reduces acne by biasing the shadowmap lookup along the geometric normal.\n"
|
||||
"If this is 0, no biasing is applied.")
|
||||
->Attribute(Edit::Attributes::Min, 0.f)
|
||||
->Attribute(Edit::Attributes::Max, 10.0f)
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::ShadowsDisabled)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,8 @@ namespace AZ
|
||||
void SetShadowFilterMethod([[maybe_unused]] ShadowFilterMethod method) override {};
|
||||
void SetFilteringSampleCount([[maybe_unused]] uint32_t count) override {};
|
||||
void SetEsmExponent([[maybe_unused]] float esmExponent) override{};
|
||||
|
||||
void SetNormalShadowBias([[maybe_unused]] float bias) override{};
|
||||
|
||||
protected:
|
||||
void InitBase(EntityId entityId);
|
||||
|
||||
|
||||
@@ -79,6 +79,8 @@ namespace AZ
|
||||
virtual void SetFilteringSampleCount(uint32_t count) = 0;
|
||||
//! Sets the Esm exponent to use. Higher values produce a steeper falloff between light and shadow.
|
||||
virtual void SetEsmExponent(float exponent) = 0;
|
||||
//! Sets the normal bias. Reduces acne by biasing the shadowmap lookup along the geometric normal.
|
||||
virtual void SetNormalShadowBias(float bias) = 0;
|
||||
};
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
@@ -107,4 +107,13 @@ namespace AZ::Render
|
||||
GetFeatureProcessor()->SetEsmExponent(GetLightHandle(), esmExponent);
|
||||
}
|
||||
}
|
||||
|
||||
void SphereLightDelegate::SetNormalShadowBias(float bias)
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
{
|
||||
GetFeatureProcessor()->SetNormalShadowBias(GetLightHandle(), bias);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace AZ::Render
|
||||
|
||||
@@ -36,6 +36,7 @@ namespace AZ
|
||||
void SetShadowFilterMethod(ShadowFilterMethod method) override;
|
||||
void SetFilteringSampleCount(uint32_t count) override;
|
||||
void SetEsmExponent(float esmExponent) override;
|
||||
void SetNormalShadowBias(float bias) override;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
+1
-1
@@ -134,7 +134,7 @@ namespace AZ
|
||||
propertyValue = AZ::RPI::MaterialPropertyValue::FromAny(propertyOverrideItr->second);
|
||||
}
|
||||
|
||||
if (!AtomToolsFramework::ConvertToExportFormat(path, propertyDefinition, propertyValue))
|
||||
if (!AtomToolsFramework::ConvertToExportFormat(path, propertyId.GetFullName(), propertyDefinition, propertyValue))
|
||||
{
|
||||
AZ_Error("AZ::Render::EditorMaterialComponentUtil", false, "Failed to export: %s", path.c_str());
|
||||
result = false;
|
||||
|
||||
+3
-3
@@ -163,9 +163,9 @@ namespace AZ
|
||||
m_modelAsset->GetAabb().GetAsSphere(center, radius);
|
||||
}
|
||||
|
||||
const auto distance = radius + NearDist;
|
||||
const auto cameraRotation = Quaternion::CreateFromAxisAngle(Vector3::CreateAxisZ(), CameraRotationAngle);
|
||||
const auto cameraPosition = center + cameraRotation.TransformVector(Vector3(0.0f, distance, 0.0f));
|
||||
const auto distance = fabsf(radius / sinf(FieldOfView)) + NearDist;
|
||||
const auto cameraRotation = Quaternion::CreateFromAxisAngle(Vector3::CreateAxisX(), -CameraRotationAngle);
|
||||
const auto cameraPosition = center + cameraRotation.TransformVector(-Vector3::CreateAxisY() * distance);
|
||||
const auto cameraTransform = Transform::CreateLookAt(cameraPosition, center);
|
||||
m_view->SetCameraTransform(Matrix3x4::CreateFromTransform(cameraTransform));
|
||||
}
|
||||
|
||||
+1
-1
@@ -51,7 +51,7 @@ namespace AZ
|
||||
static constexpr float NearDist = 0.001f;
|
||||
static constexpr float FarDist = 100.0f;
|
||||
static constexpr float FieldOfView = Constants::HalfPi;
|
||||
static constexpr float CameraRotationAngle = Constants::QuarterPi / 2.0f;
|
||||
static constexpr float CameraRotationAngle = Constants::QuarterPi / 3.0f;
|
||||
|
||||
RPI::ScenePtr m_scene;
|
||||
RPI::ViewPtr m_view;
|
||||
|
||||
+44
-49
@@ -9,9 +9,11 @@
|
||||
#include <API/EditorAssetSystemAPI.h>
|
||||
#include <AssetBrowser/Thumbnails/ProductThumbnail.h>
|
||||
#include <AssetBrowser/Thumbnails/SourceThumbnail.h>
|
||||
#include <Atom/RPI.Reflect/Asset/AssetUtils.h>
|
||||
#include <Atom/RPI.Reflect/Material/MaterialAsset.h>
|
||||
#include <Atom/RPI.Reflect/Model/ModelAsset.h>
|
||||
#include <Atom/RPI.Reflect/System/AnyAsset.h>
|
||||
#include <AtomToolsFramework/Util/Util.h>
|
||||
#include <SharedPreview/SharedPreviewUtils.h>
|
||||
|
||||
namespace AZ
|
||||
@@ -20,45 +22,64 @@ namespace AZ
|
||||
{
|
||||
namespace SharedPreviewUtils
|
||||
{
|
||||
Data::AssetId GetAssetId(
|
||||
AzToolsFramework::Thumbnailer::SharedThumbnailKey key,
|
||||
const Data::AssetType& assetType,
|
||||
const Data::AssetId& defaultAssetId)
|
||||
AZStd::unordered_set<AZ::Uuid> GetSupportedAssetTypes()
|
||||
{
|
||||
return { RPI::AnyAsset::RTTI_Type(), RPI::MaterialAsset::RTTI_Type(), RPI::ModelAsset::RTTI_Type() };
|
||||
}
|
||||
|
||||
bool IsSupportedAssetType(AzToolsFramework::Thumbnailer::SharedThumbnailKey key)
|
||||
{
|
||||
return GetSupportedAssetInfo(key).m_assetId.IsValid();
|
||||
}
|
||||
|
||||
AZ::Data::AssetInfo GetSupportedAssetInfo(AzToolsFramework::Thumbnailer::SharedThumbnailKey key)
|
||||
{
|
||||
const auto& supportedTypeIds = GetSupportedAssetTypes();
|
||||
|
||||
// if it's a source thumbnail key, find first product with a matching asset type
|
||||
auto sourceKey = azrtti_cast<const AzToolsFramework::AssetBrowser::SourceThumbnailKey*>(key.data());
|
||||
if (sourceKey)
|
||||
{
|
||||
bool foundIt = false;
|
||||
AZStd::vector<Data::AssetInfo> productsAssetInfo;
|
||||
AZStd::vector<AZ::Data::AssetInfo> productsAssetInfo;
|
||||
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(
|
||||
foundIt, &AzToolsFramework::AssetSystemRequestBus::Events::GetAssetsProducedBySourceUUID,
|
||||
sourceKey->GetSourceUuid(), productsAssetInfo);
|
||||
if (!foundIt)
|
||||
{
|
||||
return defaultAssetId;
|
||||
}
|
||||
auto assetInfoIt = AZStd::find_if(
|
||||
productsAssetInfo.begin(), productsAssetInfo.end(),
|
||||
[&assetType](const Data::AssetInfo& assetInfo)
|
||||
{
|
||||
return assetInfo.m_assetType == assetType;
|
||||
});
|
||||
if (assetInfoIt == productsAssetInfo.end())
|
||||
{
|
||||
return defaultAssetId;
|
||||
}
|
||||
|
||||
return assetInfoIt->m_assetId;
|
||||
for (const auto& assetInfo : productsAssetInfo)
|
||||
{
|
||||
if (supportedTypeIds.find(assetInfo.m_assetType) != supportedTypeIds.end())
|
||||
{
|
||||
return assetInfo;
|
||||
}
|
||||
}
|
||||
return AZ::Data::AssetInfo();
|
||||
}
|
||||
|
||||
// if it's a product thumbnail key just return its assetId
|
||||
AZ::Data::AssetInfo assetInfo;
|
||||
auto productKey = azrtti_cast<const AzToolsFramework::AssetBrowser::ProductThumbnailKey*>(key.data());
|
||||
if (productKey && productKey->GetAssetType() == assetType)
|
||||
if (productKey && supportedTypeIds.find(productKey->GetAssetType()) != supportedTypeIds.end())
|
||||
{
|
||||
return productKey->GetAssetId();
|
||||
AZ::Data::AssetCatalogRequestBus::BroadcastResult(
|
||||
assetInfo, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetInfoById, productKey->GetAssetId());
|
||||
}
|
||||
return defaultAssetId;
|
||||
return assetInfo;
|
||||
}
|
||||
|
||||
AZ::Data::AssetId GetSupportedAssetId(AzToolsFramework::Thumbnailer::SharedThumbnailKey key, const AZ::Data::AssetId& defaultAssetId)
|
||||
{
|
||||
const AZ::Data::AssetInfo assetInfo = GetSupportedAssetInfo(key);
|
||||
return assetInfo.m_assetId.IsValid() ? assetInfo.m_assetId : defaultAssetId;
|
||||
}
|
||||
|
||||
AZ::Data::AssetId GetAssetIdForProductPath(const AZStd::string_view productPath)
|
||||
{
|
||||
if (!productPath.empty())
|
||||
{
|
||||
return AZ::RPI::AssetUtils::GetAssetIdForProductPath(productPath.data());
|
||||
}
|
||||
return AZ::Data::AssetId();
|
||||
}
|
||||
|
||||
QString WordWrap(const QString& string, int maxLength)
|
||||
@@ -85,32 +106,6 @@ namespace AZ
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
AZStd::unordered_set<AZ::Uuid> GetSupportedAssetTypes()
|
||||
{
|
||||
return { RPI::AnyAsset::RTTI_Type(), RPI::MaterialAsset::RTTI_Type(), RPI::ModelAsset::RTTI_Type() };
|
||||
}
|
||||
|
||||
bool IsSupportedAssetType(AzToolsFramework::Thumbnailer::SharedThumbnailKey key)
|
||||
{
|
||||
for (const AZ::Uuid& typeId : SharedPreviewUtils::GetSupportedAssetTypes())
|
||||
{
|
||||
const AZ::Data::AssetId& assetId = SharedPreviewUtils::GetAssetId(key, typeId);
|
||||
if (assetId.IsValid())
|
||||
{
|
||||
if (typeId == RPI::AnyAsset::RTTI_Type())
|
||||
{
|
||||
AZ::Data::AssetInfo assetInfo;
|
||||
AZ::Data::AssetCatalogRequestBus::BroadcastResult(
|
||||
assetInfo, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetInfoById, assetId);
|
||||
return AzFramework::StringFunc::EndsWith(assetInfo.m_relativePath.c_str(), "lightingpreset.azasset");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
} // namespace SharedPreviewUtils
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
|
||||
+16
-12
@@ -8,9 +8,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/Asset/AssetManagerBus.h>
|
||||
#include <AzToolsFramework/Thumbnails/Thumbnail.h>
|
||||
#endif
|
||||
|
||||
@@ -20,21 +20,25 @@ namespace AZ
|
||||
{
|
||||
namespace SharedPreviewUtils
|
||||
{
|
||||
//! Get assetId by assetType that belongs to either source or product thumbnail key
|
||||
Data::AssetId GetAssetId(
|
||||
AzToolsFramework::Thumbnailer::SharedThumbnailKey key,
|
||||
const Data::AssetType& assetType,
|
||||
const Data::AssetId& defaultAssetId = {});
|
||||
|
||||
//! Word wrap function for previewer QLabel, since by default it does not break long words such as filenames, so manual word
|
||||
//! wrap needed
|
||||
QString WordWrap(const QString& string, int maxLength);
|
||||
|
||||
//! Get the set of all asset types supported by the shared preview
|
||||
AZStd::unordered_set<AZ::Uuid> GetSupportedAssetTypes();
|
||||
|
||||
//! Determine if a thumbnail key has an asset supported by the shared preview
|
||||
bool IsSupportedAssetType(AzToolsFramework::Thumbnailer::SharedThumbnailKey key);
|
||||
|
||||
//! Get assetInfo of source or product thumbnail key if asset type is supported by the shared preview
|
||||
AZ::Data::AssetInfo GetSupportedAssetInfo(AzToolsFramework::Thumbnailer::SharedThumbnailKey key);
|
||||
|
||||
//! Get assetId of source or product thumbnail key if asset type is supported by the shared preview
|
||||
AZ::Data::AssetId GetSupportedAssetId(
|
||||
AzToolsFramework::Thumbnailer::SharedThumbnailKey key, const AZ::Data::AssetId& defaultAssetId = {});
|
||||
|
||||
//! Wraps AZ::RPI::AssetUtils::GetAssetIdForProductPath to handle empty productPath
|
||||
AZ::Data::AssetId GetAssetIdForProductPath(const AZStd::string_view productPath);
|
||||
|
||||
//! Inserts new line characters into a string whenever the maximum number of characters per line is exceeded
|
||||
QString WordWrap(const QString& string, int maxLength);
|
||||
|
||||
} // namespace SharedPreviewUtils
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
|
||||
+9
-12
@@ -22,18 +22,13 @@ namespace AZ
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
SharedThumbnail::SharedThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey key)
|
||||
: Thumbnail(key)
|
||||
, m_assetInfo(SharedPreviewUtils::GetSupportedAssetInfo(key))
|
||||
{
|
||||
for (const AZ::Uuid& typeId : SharedPreviewUtils::GetSupportedAssetTypes())
|
||||
if (m_assetInfo.m_assetId.IsValid())
|
||||
{
|
||||
const AZ::Data::AssetId& assetId = SharedPreviewUtils::GetAssetId(key, typeId);
|
||||
if (assetId.IsValid())
|
||||
{
|
||||
m_assetId = assetId;
|
||||
m_typeId = typeId;
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Handler::BusConnect(key);
|
||||
AzFramework::AssetCatalogEventBus::Handler::BusConnect();
|
||||
return;
|
||||
}
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Handler::BusConnect(key);
|
||||
AzFramework::AssetCatalogEventBus::Handler::BusConnect();
|
||||
return;
|
||||
}
|
||||
|
||||
AZ_Error("SharedThumbnail", false, "Failed to find matching assetId for the thumbnailKey.");
|
||||
@@ -43,7 +38,9 @@ namespace AZ
|
||||
void SharedThumbnail::LoadThread()
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::QueueEvent(
|
||||
m_typeId, &AzToolsFramework::Thumbnailer::ThumbnailerRendererRequests::RenderThumbnail, m_key, SharedThumbnailSize);
|
||||
m_assetInfo.m_assetType, &AzToolsFramework::Thumbnailer::ThumbnailerRendererRequests::RenderThumbnail, m_key,
|
||||
SharedThumbnailSize);
|
||||
|
||||
// wait for response from thumbnail renderer
|
||||
m_renderWait.acquire();
|
||||
}
|
||||
@@ -68,7 +65,7 @@ namespace AZ
|
||||
|
||||
void SharedThumbnail::OnCatalogAssetChanged([[maybe_unused]] const AZ::Data::AssetId& assetId)
|
||||
{
|
||||
if (m_assetId == assetId && m_state == State::Ready)
|
||||
if (m_assetInfo.m_assetId == assetId && m_state == State::Ready)
|
||||
{
|
||||
m_state = State::Unloaded;
|
||||
Load();
|
||||
|
||||
@@ -43,8 +43,7 @@ namespace AZ
|
||||
void OnCatalogAssetChanged(const AZ::Data::AssetId& assetId) override;
|
||||
|
||||
AZStd::binary_semaphore m_renderWait;
|
||||
Data::AssetId m_assetId;
|
||||
AZ::Uuid m_typeId;
|
||||
Data::AssetInfo m_assetInfo;
|
||||
};
|
||||
|
||||
//! Cache configuration for shared thumbnails
|
||||
|
||||
+56
-6
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <AtomToolsFramework/PreviewRenderer/PreviewRendererCaptureRequest.h>
|
||||
#include <AtomToolsFramework/PreviewRenderer/PreviewRendererInterface.h>
|
||||
#include <AtomToolsFramework/Util/Util.h>
|
||||
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailerBus.h>
|
||||
#include <SharedPreview/SharedPreviewContent.h>
|
||||
@@ -20,9 +21,9 @@ namespace AZ
|
||||
{
|
||||
SharedThumbnailRenderer::SharedThumbnailRenderer()
|
||||
{
|
||||
m_defaultModelAsset.Create(DefaultModelAssetId, true);
|
||||
m_defaultMaterialAsset.Create(DefaultMaterialAssetId, true);
|
||||
m_defaultLightingPresetAsset.Create(DefaultLightingPresetAssetId, true);
|
||||
m_defaultModelAsset.Create(SharedPreviewUtils::GetAssetIdForProductPath(DefaultModelPath), true);
|
||||
m_defaultMaterialAsset.Create(SharedPreviewUtils::GetAssetIdForProductPath(DefaultMaterialPath), true);
|
||||
m_defaultLightingPresetAsset.Create(SharedPreviewUtils::GetAssetIdForProductPath(DefaultLightingPresetPath), true);
|
||||
|
||||
for (const AZ::Uuid& typeId : SharedPreviewUtils::GetSupportedAssetTypes())
|
||||
{
|
||||
@@ -37,17 +38,66 @@ namespace AZ
|
||||
SystemTickBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
SharedThumbnailRenderer::ThumbnailConfig SharedThumbnailRenderer::GetThumbnailConfig(
|
||||
AzToolsFramework::Thumbnailer::SharedThumbnailKey thumbnailKey)
|
||||
{
|
||||
ThumbnailConfig thumbnailConfig;
|
||||
|
||||
const auto assetInfo = SharedPreviewUtils::GetSupportedAssetInfo(thumbnailKey);
|
||||
if (assetInfo.m_assetType == RPI::ModelAsset::RTTI_Type())
|
||||
{
|
||||
static constexpr const char* MaterialAssetPathSetting =
|
||||
"/O3DE/Atom/CommonFeature/SharedPreview/ModelAssetType/MaterialAssetPath";
|
||||
static constexpr const char* LightingAssetPathSetting =
|
||||
"/O3DE/Atom/CommonFeature/SharedPreview/ModelAssetType/LightingAssetPath";
|
||||
|
||||
thumbnailConfig.m_modelId = assetInfo.m_assetId;
|
||||
thumbnailConfig.m_materialId = SharedPreviewUtils::GetAssetIdForProductPath(
|
||||
AtomToolsFramework::GetSettingOrDefault<AZStd::string>(MaterialAssetPathSetting, DefaultMaterialPath));
|
||||
thumbnailConfig.m_lightingId = SharedPreviewUtils::GetAssetIdForProductPath(
|
||||
AtomToolsFramework::GetSettingOrDefault<AZStd::string>(LightingAssetPathSetting, DefaultLightingPresetPath));
|
||||
}
|
||||
else if (assetInfo.m_assetType == RPI::MaterialAsset::RTTI_Type())
|
||||
{
|
||||
static constexpr const char* ModelAssetPathSetting =
|
||||
"/O3DE/Atom/CommonFeature/SharedPreview/MaterialAssetType/ModelAssetPath";
|
||||
static constexpr const char* LightingAssetPathSetting =
|
||||
"/O3DE/Atom/CommonFeature/SharedPreview/MaterialAssetType/LightingAssetPath";
|
||||
|
||||
thumbnailConfig.m_modelId = SharedPreviewUtils::GetAssetIdForProductPath(
|
||||
AtomToolsFramework::GetSettingOrDefault<AZStd::string>(ModelAssetPathSetting, DefaultModelPath));
|
||||
thumbnailConfig.m_materialId = assetInfo.m_assetId;
|
||||
thumbnailConfig.m_lightingId = SharedPreviewUtils::GetAssetIdForProductPath(
|
||||
AtomToolsFramework::GetSettingOrDefault<AZStd::string>(LightingAssetPathSetting, DefaultLightingPresetPath));
|
||||
}
|
||||
else if (assetInfo.m_assetType == RPI::AnyAsset::RTTI_Type())
|
||||
{
|
||||
static constexpr const char* ModelAssetPathSetting =
|
||||
"/O3DE/Atom/CommonFeature/SharedPreview/LightingAssetType/ModelAssetPath";
|
||||
static constexpr const char* MaterialAssetPathSetting =
|
||||
"/O3DE/Atom/CommonFeature/SharedPreview/LightingAssetType/MaterialAssetPath";
|
||||
|
||||
thumbnailConfig.m_modelId = SharedPreviewUtils::GetAssetIdForProductPath(
|
||||
AtomToolsFramework::GetSettingOrDefault<AZStd::string>(ModelAssetPathSetting, DefaultModelPath));
|
||||
thumbnailConfig.m_materialId = SharedPreviewUtils::GetAssetIdForProductPath(
|
||||
AtomToolsFramework::GetSettingOrDefault<AZStd::string>(MaterialAssetPathSetting, "materials/reflectionprobe/reflectionprobevisualization.azmaterial"));
|
||||
thumbnailConfig.m_lightingId = assetInfo.m_assetId;
|
||||
}
|
||||
|
||||
return thumbnailConfig;
|
||||
}
|
||||
|
||||
void SharedThumbnailRenderer::RenderThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey thumbnailKey, int thumbnailSize)
|
||||
{
|
||||
if (auto previewRenderer = AZ::Interface<AtomToolsFramework::PreviewRendererInterface>::Get())
|
||||
{
|
||||
const auto& thumbnailConfig = GetThumbnailConfig(thumbnailKey);
|
||||
|
||||
previewRenderer->AddCaptureRequest(
|
||||
{ thumbnailSize,
|
||||
AZStd::make_shared<SharedPreviewContent>(
|
||||
previewRenderer->GetScene(), previewRenderer->GetView(), previewRenderer->GetEntityContextId(),
|
||||
SharedPreviewUtils::GetAssetId(thumbnailKey, RPI::ModelAsset::RTTI_Type(), DefaultModelAssetId),
|
||||
SharedPreviewUtils::GetAssetId(thumbnailKey, RPI::MaterialAsset::RTTI_Type(), DefaultMaterialAssetId),
|
||||
SharedPreviewUtils::GetAssetId(thumbnailKey, RPI::AnyAsset::RTTI_Type(), DefaultLightingPresetAssetId),
|
||||
thumbnailConfig.m_modelId, thumbnailConfig.m_materialId, thumbnailConfig.m_lightingId,
|
||||
Render::MaterialPropertyOverrideMap()),
|
||||
[thumbnailKey]()
|
||||
{
|
||||
|
||||
+9
-3
@@ -33,6 +33,15 @@ namespace AZ
|
||||
~SharedThumbnailRenderer();
|
||||
|
||||
private:
|
||||
struct ThumbnailConfig
|
||||
{
|
||||
Data::AssetId m_modelId;
|
||||
Data::AssetId m_materialId;
|
||||
Data::AssetId m_lightingId;
|
||||
};
|
||||
|
||||
ThumbnailConfig GetThumbnailConfig(AzToolsFramework::Thumbnailer::SharedThumbnailKey thumbnailKey);
|
||||
|
||||
//! ThumbnailerRendererRequestsBus::Handler interface overrides...
|
||||
void RenderThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey thumbnailKey, int thumbnailSize) override;
|
||||
bool Installed() const override;
|
||||
@@ -42,15 +51,12 @@ namespace AZ
|
||||
|
||||
// Default assets to be kept loaded and used for rendering if not overridden
|
||||
static constexpr const char* DefaultLightingPresetPath = "lightingpresets/thumbnail.lightingpreset.azasset";
|
||||
const Data::AssetId DefaultLightingPresetAssetId = AZ::RPI::AssetUtils::GetAssetIdForProductPath(DefaultLightingPresetPath);
|
||||
Data::Asset<RPI::AnyAsset> m_defaultLightingPresetAsset;
|
||||
|
||||
static constexpr const char* DefaultModelPath = "models/sphere.azmodel";
|
||||
const Data::AssetId DefaultModelAssetId = AZ::RPI::AssetUtils::GetAssetIdForProductPath(DefaultModelPath);
|
||||
Data::Asset<RPI::ModelAsset> m_defaultModelAsset;
|
||||
|
||||
static constexpr const char* DefaultMaterialPath = "";
|
||||
const Data::AssetId DefaultMaterialAssetId;
|
||||
Data::Asset<RPI::MaterialAsset> m_defaultMaterialAsset;
|
||||
};
|
||||
} // namespace LyIntegration
|
||||
|
||||
Reference in New Issue
Block a user