Merge branch 'development' into Atom/santorac/RemixableMaterialTypes3
There were lots of material system conflicts that had to be resolved. I expect the build is broken at this commit, and I'll fix it in followup commits. Signed-off-by: santorac <55155825+santorac@users.noreply.github.com>
This commit is contained in:
@@ -1,149 +0,0 @@
|
||||
/*
|
||||
* 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 <Atom/Features/SrgSemantics.azsli>
|
||||
|
||||
#include <Atom/Features/PostProcessing/PostProcessUtil.azsli>
|
||||
|
||||
// If true pixels with an alpha value of less than 0.5 are clipped
|
||||
option bool o_alphaTest;
|
||||
|
||||
// If true both the texture color and diffuse color are converted from linear to sRGB color space
|
||||
option bool o_srgbWrite;
|
||||
|
||||
// Indicates how to use the second texture indexed by a vertex (if at all)
|
||||
option enum class Modulate { None, Alpha, AlphaAndColor } o_modulate;
|
||||
|
||||
// Each vertex can select one or two of the 16 textures bound
|
||||
// We use an array of textures and a bitmask that indicates whether to use clamp
|
||||
// sampler (bit set) or wrap. The nth bit has the correct sampler value for the nth texture
|
||||
ShaderResourceGroup InstanceSrg : SRG_PerDraw
|
||||
{
|
||||
row_major float4x4 m_worldToProj;
|
||||
uint m_isClamp;
|
||||
Texture2D m_texture[16];
|
||||
|
||||
Sampler m_wrapSampler
|
||||
{
|
||||
MaxAnisotropy = 16;
|
||||
AddressU = Wrap;
|
||||
AddressV = Wrap;
|
||||
AddressW = Wrap;
|
||||
};
|
||||
|
||||
Sampler m_clampSampler
|
||||
{
|
||||
MaxAnisotropy = 16;
|
||||
AddressU = Clamp;
|
||||
AddressV = Clamp;
|
||||
AddressW = Clamp;
|
||||
};
|
||||
};
|
||||
|
||||
struct VSInput
|
||||
{
|
||||
float2 m_position : POSITION;
|
||||
float4 m_color : COLOR0;
|
||||
float2 m_uv : TEXCOORD0;
|
||||
uint2 m_flags : BLENDINDICES;
|
||||
};
|
||||
|
||||
struct VSOutput
|
||||
{
|
||||
float4 m_position : SV_Position;
|
||||
float4 m_color : COLOR0;
|
||||
float2 m_uv : TEXCOORD0;
|
||||
nointerpolation uint m_texIndex : COLOR1;
|
||||
nointerpolation uint m_texHasColorChannel : COLOR2;
|
||||
nointerpolation uint m_texIndex2 : COLOR3;
|
||||
};
|
||||
|
||||
VSOutput MainVS(VSInput IN)
|
||||
{
|
||||
float4x4 worldToProj = InstanceSrg::m_worldToProj;
|
||||
float4 posPS = mul(worldToProj, float4(IN.m_position, 1.0f, 1.0f));
|
||||
|
||||
VSOutput OUT;
|
||||
OUT.m_position = posPS;
|
||||
OUT.m_color = IN.m_color;
|
||||
OUT.m_uv = IN.m_uv;
|
||||
OUT.m_texIndex = IN.m_flags.x & 0x00FF;
|
||||
OUT.m_texHasColorChannel = ((IN.m_flags.x & 0xFF00) > 0) ? 1 : 0;
|
||||
OUT.m_texIndex2 = IN.m_flags.y & 0x00FF;
|
||||
return OUT;
|
||||
};
|
||||
|
||||
struct PSOutput
|
||||
{
|
||||
float4 m_color : SV_Target0;
|
||||
};
|
||||
|
||||
float4 SampleTriangleTexture(uint texIndex, float2 uv)
|
||||
{
|
||||
if ((InstanceSrg::m_isClamp & (1U << texIndex)) != 0)
|
||||
{
|
||||
return InstanceSrg::m_texture[texIndex].Sample(InstanceSrg::m_clampSampler, uv);
|
||||
}
|
||||
else
|
||||
{
|
||||
return InstanceSrg::m_texture[texIndex].Sample(InstanceSrg::m_wrapSampler, uv);
|
||||
}
|
||||
}
|
||||
|
||||
PSOutput MainPS(VSOutput IN)
|
||||
{
|
||||
PSOutput OUT;
|
||||
|
||||
float4 baseTex = SampleTriangleTexture(IN.m_texIndex, IN.m_uv.xy);
|
||||
float4 inDiffuse = IN.m_color;
|
||||
|
||||
// If the texture does not have a color channel then the alpha channel will be in the R channel of the R8 texture
|
||||
baseTex = (IN.m_texHasColorChannel) ? baseTex : float4(1.0f, 1.0f, 1.0f, baseTex.x);
|
||||
float4 resColor = baseTex * inDiffuse;
|
||||
|
||||
if (o_alphaTest)
|
||||
{
|
||||
clip(resColor.w - 0.5);
|
||||
}
|
||||
|
||||
// Should use srgb anytime after tonemapping
|
||||
if (o_srgbWrite)
|
||||
{
|
||||
resColor.xyz = LinearToSRGB(resColor.xyz);
|
||||
}
|
||||
|
||||
// If the o_modulate option is not None it means that the verts have two texture indicies. The second texture is used to
|
||||
// mask the first. This is used for gradient masks.
|
||||
if (o_modulate == Modulate::Alpha)
|
||||
{
|
||||
float4 maskTexAlpha = SampleTriangleTexture(IN.m_texIndex2, IN.m_uv.xy);
|
||||
resColor.w *= maskTexAlpha.w;
|
||||
|
||||
if (o_alphaTest)
|
||||
{
|
||||
// This is a rare case that would only happen if a gradient mask is used inside the mask primitive for a stencil mask
|
||||
clip(resColor.w - 0.5);
|
||||
}
|
||||
}
|
||||
else if (o_modulate == Modulate::AlphaAndColor)
|
||||
{
|
||||
float4 maskTex = SampleTriangleTexture(IN.m_texIndex2, IN.m_uv.xy);
|
||||
resColor *= maskTex.w;
|
||||
|
||||
if (o_alphaTest)
|
||||
{
|
||||
// This is a rare case that would only happen if a gradient mask is used inside the mask primitive for a stencil mask
|
||||
clip(resColor.w - 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
OUT.m_color = resColor;
|
||||
|
||||
return OUT;
|
||||
};
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
{
|
||||
"Source" : "LyShineUI",
|
||||
|
||||
"DepthStencilState" : {
|
||||
"Depth" : {
|
||||
"Enable" : false,
|
||||
"CompareFunc" : "Always"
|
||||
}
|
||||
},
|
||||
|
||||
"RasterState" : {
|
||||
"DepthClipEnable" : false,
|
||||
"CullMode" : "None"
|
||||
},
|
||||
|
||||
"BlendState" : {
|
||||
"Enable" : true,
|
||||
"BlendSource" : "AlphaSource",
|
||||
"BlendDest" : "AlphaSourceInverse",
|
||||
"BlendOp" : "Add"
|
||||
},
|
||||
|
||||
"DrawList" : "2dpass",
|
||||
|
||||
"ProgramSettings":
|
||||
{
|
||||
"EntryPoints":
|
||||
[
|
||||
{
|
||||
"name": "MainVS",
|
||||
"type": "Vertex"
|
||||
},
|
||||
{
|
||||
"name": "MainPS",
|
||||
"type": "Fragment"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
{
|
||||
"Shader" : "LyShineUI.shader",
|
||||
"Variants" : [
|
||||
{
|
||||
"StableId": 1,
|
||||
"Options": {
|
||||
"o_alphaTest": "false",
|
||||
"o_srgbWrite": "true",
|
||||
"o_modulate": "Modulate::None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"StableId": 2,
|
||||
"Options": {
|
||||
"o_alphaTest": "false",
|
||||
"o_srgbWrite": "false",
|
||||
"o_modulate": "Modulate::None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"StableId": 3,
|
||||
"Options": {
|
||||
"o_alphaTest": "true",
|
||||
"o_srgbWrite": "false",
|
||||
"o_modulate": "Modulate::None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"StableId": 4,
|
||||
"Options": {
|
||||
"o_alphaTest": "false",
|
||||
"o_srgbWrite": "false",
|
||||
"o_modulate": "Modulate::Alpha"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"Source" : "SimpleTextured",
|
||||
"Source" : "SimpleTextured.azsl",
|
||||
|
||||
"DepthStencilState" : {
|
||||
"Depth" : {
|
||||
|
||||
@@ -6,4 +6,8 @@
|
||||
#
|
||||
#
|
||||
|
||||
set(gem_path ${CMAKE_CURRENT_LIST_DIR})
|
||||
set(gem_json ${gem_path}/gem.json)
|
||||
o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path)
|
||||
|
||||
add_subdirectory(Code)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
#
|
||||
|
||||
ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME})
|
||||
o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path})
|
||||
|
||||
ly_add_target(
|
||||
NAME Atom_AtomBridge.Static STATIC
|
||||
@@ -68,6 +68,14 @@ ly_create_alias(NAME Atom_AtomBridge.Clients NAMESPACE Gem TARGETS Gem::Atom_Ato
|
||||
ly_create_alias(NAME Atom_AtomBridge.Servers NAMESPACE Gem TARGETS Gem::Atom_AtomBridge)
|
||||
|
||||
if(PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
|
||||
set(additional_tool_deps ${pal_dir}/additional_${PAL_PLATFORM_NAME_LOWERCASE}_tool_deps.cmake)
|
||||
foreach(pal_tools_platform ${LY_PAL_TOOLS_ENABLED})
|
||||
string(TOLOWER ${pal_tools_platform} pal_tools_platform_lowercase)
|
||||
ly_get_list_relative_pal_filename(pal_runtime_dependencies_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${pal_tools_platform})
|
||||
list(APPEND additional_tool_deps ${pal_runtime_dependencies_source_dir}/additional_${pal_tools_platform_lowercase}_tool_deps.cmake)
|
||||
endforeach()
|
||||
|
||||
ly_add_target(
|
||||
NAME Atom_AtomBridge.Editor ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
|
||||
NAMESPACE Gem
|
||||
@@ -79,7 +87,7 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
PUBLIC
|
||||
Include
|
||||
PLATFORM_INCLUDE_FILES
|
||||
${pal_dir}/additional_${PAL_PLATFORM_NAME_LOWERCASE}_tool_deps.cmake
|
||||
${additional_tool_deps}
|
||||
COMPILE_DEFINITIONS
|
||||
PRIVATE
|
||||
EDITOR
|
||||
|
||||
@@ -67,12 +67,12 @@ namespace AZ
|
||||
|
||||
void AtomBridgeSystemComponent::GetProvidedServices(ComponentDescriptor::DependencyArrayType& provided)
|
||||
{
|
||||
provided.push_back(AZ_CRC("AtomBridgeService", 0xdb816a99));
|
||||
provided.push_back(AZ_CRC("AtomBridgeService", 0x92d990b5));
|
||||
}
|
||||
|
||||
void AtomBridgeSystemComponent::GetIncompatibleServices(ComponentDescriptor::DependencyArrayType& incompatible)
|
||||
{
|
||||
incompatible.push_back(AZ_CRC("AtomBridgeService", 0xdb816a99));
|
||||
incompatible.push_back(AZ_CRC("AtomBridgeService", 0x92d990b5));
|
||||
}
|
||||
|
||||
void AtomBridgeSystemComponent::GetRequiredServices(ComponentDescriptor::DependencyArrayType& required)
|
||||
@@ -108,7 +108,7 @@ namespace AZ
|
||||
{
|
||||
m_dynamicDrawManager.reset();
|
||||
AZ::RPI::ViewportContextManagerNotificationsBus::Handler::BusDisconnect();
|
||||
RPI::Scene* scene = RPI::RPISystemInterface::Get()->GetDefaultScene().get();
|
||||
RPI::Scene* scene = AZ::RPI::Scene::GetSceneForEntityContextId(m_entityContextId);
|
||||
// Check if scene is emptry since scene might be released already when running AtomSampleViewer
|
||||
if (scene)
|
||||
{
|
||||
@@ -157,9 +157,9 @@ namespace AZ
|
||||
|
||||
void AtomBridgeSystemComponent::OnBootstrapSceneReady(AZ::RPI::Scene* bootstrapScene)
|
||||
{
|
||||
AZ_UNUSED(bootstrapScene);
|
||||
// Make default AtomDebugDisplayViewportInterface
|
||||
AZStd::shared_ptr<AtomDebugDisplayViewportInterface> mainEntityDebugDisplay = AZStd::make_shared<AtomDebugDisplayViewportInterface>(AzFramework::g_defaultSceneEntityDebugDisplayId);
|
||||
AZStd::shared_ptr<AtomDebugDisplayViewportInterface> mainEntityDebugDisplay =
|
||||
AZStd::make_shared<AtomDebugDisplayViewportInterface>(AzFramework::g_defaultSceneEntityDebugDisplayId, bootstrapScene);
|
||||
m_activeViewportsList[AzFramework::g_defaultSceneEntityDebugDisplayId] = mainEntityDebugDisplay;
|
||||
}
|
||||
|
||||
|
||||
+83
-80
@@ -256,12 +256,11 @@ namespace AZ::AtomBridge
|
||||
viewportContextPtr->ConnectSceneChangedHandler(m_sceneChangeHandler);
|
||||
}
|
||||
|
||||
AtomDebugDisplayViewportInterface::AtomDebugDisplayViewportInterface(uint32_t defaultInstanceAddress)
|
||||
AtomDebugDisplayViewportInterface::AtomDebugDisplayViewportInterface(uint32_t defaultInstanceAddress, RPI::Scene* scene)
|
||||
{
|
||||
ResetRenderState();
|
||||
m_viewportId = defaultInstanceAddress;
|
||||
m_defaultInstance = true;
|
||||
RPI::Scene* scene = RPI::RPISystemInterface::Get()->GetDefaultScene().get();
|
||||
InitInternal(scene, nullptr);
|
||||
}
|
||||
|
||||
@@ -349,14 +348,7 @@ namespace AZ::AtomBridge
|
||||
void AtomDebugDisplayViewportInterface::SetAlpha(float a)
|
||||
{
|
||||
m_rendState.m_color.SetA(a);
|
||||
if (a < 1.0f)
|
||||
{
|
||||
m_rendState.m_opacityType = AZ::RPI::AuxGeomDraw::OpacityType::Opaque;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rendState.m_opacityType = AZ::RPI::AuxGeomDraw::OpacityType::Translucent;
|
||||
}
|
||||
m_rendState.m_opacityType = a < 1.0f ? AZ::RPI::AuxGeomDraw::OpacityType::Translucent : AZ::RPI::AuxGeomDraw::OpacityType::Opaque;
|
||||
}
|
||||
|
||||
void AtomDebugDisplayViewportInterface::DrawQuad(
|
||||
@@ -800,7 +792,8 @@ namespace AZ::AtomBridge
|
||||
const float startAngle = DegToRad(startAngleDegrees);
|
||||
const float stopAngle = DegToRad(sweepAngleDegrees) + startAngle;
|
||||
SingleColorDynamicSizeLineHelper lines(1+static_cast<int>(sweepAngleDegrees/angularStepDegrees));
|
||||
AZ::Vector3 radiusV3 = AZ::Vector3(radius);
|
||||
float aspectRadius = radius / GetAspectRatio();
|
||||
AZ::Vector3 radiusV3 = AZ::Vector3(aspectRadius, radius, radius);
|
||||
AZ::Vector3 pos = AZ::Vector3(center.GetX(), center.GetY(), z);
|
||||
CreateAxisAlignedArc(
|
||||
lines,
|
||||
@@ -1016,6 +1009,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 +1067,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 +1131,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,8 +1355,9 @@ 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, y, 1.0f);
|
||||
params.m_position = AZ::Vector3(x * dpiScaleFactor, y * dpiScaleFactor, 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
|
||||
|
||||
@@ -124,7 +124,7 @@ namespace AZ::AtomBridge
|
||||
AZ_RTTI(AtomDebugDisplayViewportInterface, "{09AF6A46-0100-4FBF-8F94-E6B221322D14}", AzFramework::DebugDisplayRequestBus::Handler);
|
||||
|
||||
explicit AtomDebugDisplayViewportInterface(AZ::RPI::ViewportContextPtr viewportContextPtr);
|
||||
explicit AtomDebugDisplayViewportInterface(uint32_t defaultInstanceAddress);
|
||||
explicit AtomDebugDisplayViewportInterface(uint32_t defaultInstanceAddress, RPI::Scene* scene);
|
||||
~AtomDebugDisplayViewportInterface();
|
||||
|
||||
void ResetRenderState();
|
||||
@@ -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;
|
||||
|
||||
+2
-2
@@ -109,12 +109,12 @@ namespace AZ
|
||||
|
||||
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services)
|
||||
{
|
||||
services.push_back(AZ_CRC("AssetCollectionAsyncLoaderTest", 0xdd5ab934));
|
||||
services.push_back(AZ_CRC("AssetCollectionAsyncLoaderTest", 0x66d04369));
|
||||
}
|
||||
|
||||
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services)
|
||||
{
|
||||
services.push_back(AZ_CRC("AssetCollectionAsyncLoaderTest", 0xdd5ab934));
|
||||
services.push_back(AZ_CRC("AssetCollectionAsyncLoaderTest", 0x66d04369));
|
||||
}
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "FlyCameraInputComponent.h"
|
||||
|
||||
#include <ISystem.h>
|
||||
#include <ITimer.h>
|
||||
#include <IConsole.h>
|
||||
|
||||
#include <AzCore/Component/Component.h>
|
||||
|
||||
@@ -2,14 +2,17 @@
|
||||
"gem_name": "Atom_AtomBridge",
|
||||
"display_name": "Atom Bridge",
|
||||
"license": "Apache-2.0 Or MIT",
|
||||
"license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt",
|
||||
"origin": "Open 3D Engine - o3de.org",
|
||||
"origin_url": "https://github.com/o3de/o3de",
|
||||
"type": "Code",
|
||||
"summary": "",
|
||||
"summary": "Atom Bridge",
|
||||
"canonical_tags": [
|
||||
"Gem"
|
||||
],
|
||||
"user_tags": [],
|
||||
"requirements": "",
|
||||
"documentation_url": "",
|
||||
"dependencies": [
|
||||
"Atom_RPI",
|
||||
"Atom_Bootstrap",
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<ObjectStream version="3">
|
||||
<Class name="AZStd::vector" type="{82FC5264-88D0-57CD-9307-FC52E4DAD550}">
|
||||
<Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
|
||||
<Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
|
||||
<Class name="AZ::Uuid" field="guid" value="{400C0F36-1069-5F0E-8E55-87123BA075CD}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
<Class name="unsigned int" field="subId" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
</Class>
|
||||
<Class name="unsigned int" field="platformFlags" value="3" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="AZStd::string" field="pathHint" value="shaders/simpletextured.azshader" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
</ObjectStream>
|
||||
|
||||
@@ -6,4 +6,8 @@
|
||||
#
|
||||
#
|
||||
|
||||
set(gem_path ${CMAKE_CURRENT_LIST_DIR})
|
||||
set(gem_json ${gem_path}/gem.json)
|
||||
o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path)
|
||||
|
||||
add_subdirectory(Code)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
#
|
||||
|
||||
ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME})
|
||||
o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path})
|
||||
|
||||
ly_add_target(
|
||||
NAME AtomFont ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
|
||||
|
||||
@@ -133,18 +133,6 @@ namespace AZ
|
||||
typedef std::vector<FontEffect> FontEffects;
|
||||
typedef FontEffects::iterator FontEffectsIterator;
|
||||
|
||||
struct FontPipelineStateMapKey
|
||||
{
|
||||
AZ::RPI::SceneId m_sceneId; // which scene pipeline state is attached to (via Render Pipeline)
|
||||
AZ::RHI::DrawListTag m_drawListTag; // which render pass this pipeline draws in by default
|
||||
|
||||
bool operator<(const FontPipelineStateMapKey& other) const
|
||||
{
|
||||
return m_sceneId < other.m_sceneId
|
||||
|| (m_sceneId == other.m_sceneId && m_drawListTag < other.m_drawListTag);
|
||||
}
|
||||
};
|
||||
|
||||
struct FontShaderData
|
||||
{
|
||||
AZ::RHI::ShaderInputNameIndex m_imageInputIndex = "m_texture";
|
||||
|
||||
@@ -46,7 +46,7 @@ static void DumfontTexture(IConsoleCmdArgs* cmdArgs)
|
||||
|
||||
if (fontName && *fontName && *fontName != '0')
|
||||
{
|
||||
AZStd::string fontFilePath("@devroot@/");
|
||||
AZStd::string fontFilePath("@engroot@/");
|
||||
fontFilePath += fontName;
|
||||
fontFilePath += ".bmp";
|
||||
|
||||
|
||||
@@ -561,12 +561,10 @@ uint32_t AZ::FFont::GetNumQuadsForText(const char* str, const bool asciiMultiLin
|
||||
++numQuads;
|
||||
}
|
||||
|
||||
uint32_t nextCh = 0;
|
||||
const wchar_t* pChar = strW.c_str();
|
||||
while (uint32_t ch = *pChar)
|
||||
{
|
||||
++pChar;
|
||||
nextCh = *pChar;
|
||||
|
||||
switch (ch)
|
||||
{
|
||||
@@ -1726,15 +1724,13 @@ void AZ::FFont::DrawScreenAlignedText3d(
|
||||
{
|
||||
return;
|
||||
}
|
||||
AZ::Vector3 positionNDC = AzFramework::WorldToScreenNdc(
|
||||
params.m_position,
|
||||
currentView->GetWorldToViewMatrix(),
|
||||
currentView->GetViewToClipMatrix()
|
||||
);
|
||||
|
||||
// Text behind the camera shouldn't get rendered. WorldToScreenNDC returns values in the range 0 - 1, so Z < 0.5 is behind the screen
|
||||
const AZ::Vector3 positionNdc = AzFramework::WorldToScreenNdc(
|
||||
params.m_position, currentView->GetWorldToViewMatrixAsMatrix3x4(), currentView->GetViewToClipMatrix());
|
||||
|
||||
// Text behind the camera shouldn't get rendered. WorldToScreenNdc returns values in the range 0 - 1, so Z < 0.5 is behind the screen
|
||||
// and >= 0.5 is in front of the screen.
|
||||
if (positionNDC.GetZ() < 0.5f)
|
||||
if (positionNdc.GetZ() < 0.5f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1744,9 +1740,9 @@ void AZ::FFont::DrawScreenAlignedText3d(
|
||||
DrawStringUInternal(
|
||||
*internalParams.m_viewport,
|
||||
internalParams.m_viewportContext,
|
||||
positionNDC.GetX() * internalParams.m_viewport->GetWidth(),
|
||||
(1.0f - positionNDC.GetY()) * internalParams.m_viewport->GetHeight(),
|
||||
positionNDC.GetZ(), // Z
|
||||
positionNdc.GetX() * internalParams.m_viewport->GetWidth(),
|
||||
(1.0f - positionNdc.GetY()) * internalParams.m_viewport->GetHeight(),
|
||||
positionNdc.GetZ(), // Z
|
||||
text.data(),
|
||||
params.m_multiline,
|
||||
internalParams.m_ctx
|
||||
|
||||
@@ -2,14 +2,17 @@
|
||||
"gem_name": "AtomFont",
|
||||
"display_name": "Atom Font",
|
||||
"license": "Apache-2.0 Or MIT",
|
||||
"license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt",
|
||||
"origin": "Open 3D Engine - o3de.org",
|
||||
"origin_url": "https://github.com/o3de/o3de",
|
||||
"type": "Code",
|
||||
"summary": "",
|
||||
"summary": "Font Rendering for Atom",
|
||||
"canonical_tags": [
|
||||
"Gem"
|
||||
],
|
||||
"user_tags": [],
|
||||
"requirements": "",
|
||||
"documentation_url": "",
|
||||
"dependencies": [
|
||||
"Atom_RHI",
|
||||
"Atom_RPI",
|
||||
|
||||
@@ -84,14 +84,6 @@ namespace AtomImGuiTools
|
||||
{
|
||||
m_imguiGpuProfiler.Draw(m_showGpuProfiler, AZ::RPI::PassSystemInterface::Get()->GetRootPass().get());
|
||||
}
|
||||
if (m_showCpuProfiler)
|
||||
{
|
||||
const AZ::RHI::CpuTimingStatistics* stats = AZ::RHI::RHISystemInterface::Get()->GetCpuTimingStatistics();
|
||||
if (stats)
|
||||
{
|
||||
m_imguiCpuProfiler.Draw(m_showCpuProfiler, *stats);
|
||||
}
|
||||
}
|
||||
if (m_showTransientAttachmentProfiler)
|
||||
{
|
||||
auto* transientStats = AZ::RHI::RHISystemInterface::Get()->GetTransientAttachmentStatistics();
|
||||
@@ -112,12 +104,6 @@ namespace AtomImGuiTools
|
||||
{
|
||||
ImGui::MenuItem("Pass Viewer", "", &m_showPassTree);
|
||||
ImGui::MenuItem("Gpu Profiler", "", &m_showGpuProfiler);
|
||||
if (ImGui::MenuItem("Cpu Profiler", "", &m_showCpuProfiler))
|
||||
{
|
||||
AZ::RHI::RHISystemInterface::Get()->ModifyFrameSchedulerStatisticsFlags(
|
||||
AZ::RHI::FrameSchedulerStatisticsFlags::GatherCpuTimingStatistics, m_showCpuProfiler);
|
||||
AZ::RHI::CpuProfiler::Get()->SetProfilerEnabled(m_showCpuProfiler);
|
||||
}
|
||||
if (ImGui::MenuItem("Transient Attachment Profiler", "", &m_showTransientAttachmentProfiler))
|
||||
{
|
||||
AZ::RHI::RHISystemInterface::Get()->ModifyFrameSchedulerStatisticsFlags(
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#if defined(IMGUI_ENABLED)
|
||||
#include <ImGuiBus.h>
|
||||
#include <imgui/imgui.h>
|
||||
#include <Atom/Utils/ImGuiCpuProfiler.h>
|
||||
#include <Atom/Utils/ImGuiGpuProfiler.h>
|
||||
#include <Atom/Utils/ImGuiPassTree.h>
|
||||
#include <Atom/Utils/ImGuiShaderMetrics.h>
|
||||
@@ -63,9 +62,6 @@ namespace AtomImGuiTools
|
||||
AZ::Render::ImGuiGpuProfiler m_imguiGpuProfiler;
|
||||
bool m_showGpuProfiler = false;
|
||||
|
||||
AZ::Render::ImGuiCpuProfiler m_imguiCpuProfiler;
|
||||
bool m_showCpuProfiler = false;
|
||||
|
||||
AZ::Render::ImGuiTransientAttachmentProfiler m_imguiTransientAttachmentProfiler;
|
||||
bool m_showTransientAttachmentProfiler = false;
|
||||
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
"gem_name": "AtomImGuiTools",
|
||||
"display_name": "Atom ImGui",
|
||||
"license": "Apache-2.0 Or MIT",
|
||||
"license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt",
|
||||
"origin": "Open 3D Engine - o3de.org",
|
||||
"origin_url": "https://github.com/o3de/o3de",
|
||||
"type": "Tool",
|
||||
"summary": "",
|
||||
"summary": "ImGui tools for Atom",
|
||||
"canonical_tags": [
|
||||
"Gem"
|
||||
],
|
||||
@@ -13,6 +15,7 @@
|
||||
"Rendering"
|
||||
],
|
||||
"requirements": "",
|
||||
"documentation_url": "",
|
||||
"dependencies": [
|
||||
"ImguiAtom",
|
||||
"Atom"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"Source" : "TexturedIcon",
|
||||
"Source" : "TexturedIcon.azsl",
|
||||
|
||||
"DepthStencilState" : {
|
||||
"Depth" : {
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<ObjectStream version="3">
|
||||
<Class name="AZStd::vector" type="{82FC5264-88D0-57CD-9307-FC52E4DAD550}">
|
||||
<Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
|
||||
<Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
|
||||
<Class name="AZ::Uuid" field="guid" value="{7B093FA3-A834-5061-9ADD-C6DCA97A4B60}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
<Class name="unsigned int" field="subId" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
</Class>
|
||||
<Class name="unsigned int" field="platformFlags" value="3" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="AZStd::string" field="pathHint" value="shaders/texturedicon.azshader" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
</ObjectStream>
|
||||
|
||||
+24
-17
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "AtomViewportDisplayIconsSystemComponent.h"
|
||||
|
||||
#include <AzCore/Math/VectorConversions.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/EditContextConstants.inl>
|
||||
@@ -73,7 +74,7 @@ namespace AZ::Render
|
||||
void AtomViewportDisplayIconsSystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
|
||||
{
|
||||
required.push_back(AZ_CRC("RPISystem", 0xf2add773));
|
||||
required.push_back(AZ_CRC("AtomBridgeService", 0xdb816a99));
|
||||
required.push_back(AZ_CRC("AtomBridgeService", 0x92d990b5));
|
||||
}
|
||||
|
||||
void AtomViewportDisplayIconsSystemComponent::GetDependentServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& dependent)
|
||||
@@ -117,8 +118,7 @@ namespace AZ::Render
|
||||
return;
|
||||
}
|
||||
|
||||
auto perViewportDynamicDrawInterface =
|
||||
AtomBridge::PerViewportDynamicDraw::Get();
|
||||
auto perViewportDynamicDrawInterface = AtomBridge::PerViewportDynamicDraw::Get();
|
||||
if (!perViewportDynamicDrawInterface)
|
||||
{
|
||||
return;
|
||||
@@ -131,7 +131,7 @@ namespace AZ::Render
|
||||
return;
|
||||
}
|
||||
|
||||
// Find our icon, falling back on a grey placeholder if its image is unavailable
|
||||
// Find our icon, falling back on a gray placeholder if its image is unavailable
|
||||
AZ::Data::Instance<AZ::RPI::Image> image = AZ::RPI::ImageSystemInterface::Get()->GetSystemImage(AZ::RPI::SystemImage::Grey);
|
||||
if (auto iconIt = m_iconData.find(drawParameters.m_icon); iconIt != m_iconData.end())
|
||||
{
|
||||
@@ -172,13 +172,16 @@ namespace AZ::Render
|
||||
}
|
||||
else if (drawParameters.m_positionSpace == CoordinateSpace::WorldSpace)
|
||||
{
|
||||
// Calculate the ndc point (0.0-1.0 range) including depth
|
||||
const AZ::Vector3 ndcPoint = AzFramework::WorldToScreenNdc(
|
||||
drawParameters.m_position, viewportContext->GetCameraViewMatrixAsMatrix3x4(),
|
||||
viewportContext->GetCameraProjectionMatrix());
|
||||
|
||||
// Calculate our screen space position using the viewport size
|
||||
// We want this instead of RenderViewportWidget::WorldToScreen which works in QWidget virtual coordinate space
|
||||
AzFramework::ScreenPoint position = AzFramework::WorldToScreen(
|
||||
drawParameters.m_position, viewportContext->GetCameraViewMatrix(), viewportContext->GetCameraProjectionMatrix(),
|
||||
viewportSize);
|
||||
screenPosition.SetX(aznumeric_cast<float>(position.m_x));
|
||||
screenPosition.SetY(aznumeric_cast<float>(position.m_y));
|
||||
const AzFramework::ScreenPoint screenPoint = AzFramework::ScreenPointFromNdc(AZ::Vector3ToVector2(ndcPoint), viewportSize);
|
||||
|
||||
screenPosition = AzFramework::Vector3FromScreenPoint(screenPoint, ndcPoint.GetZ());
|
||||
}
|
||||
|
||||
struct Vertex
|
||||
@@ -210,7 +213,12 @@ namespace AZ::Render
|
||||
createVertex(-0.5f, 0.5f, 0.f, 1.f)
|
||||
};
|
||||
AZStd::array<Indice, 6> indices = {0, 1, 2, 0, 2, 3};
|
||||
dynamicDraw->DrawIndexed(&vertices, static_cast<uint32_t>(vertices.size()), &indices, static_cast<uint32_t>(indices.size()), RHI::IndexFormat::Uint16, drawSrg);
|
||||
|
||||
dynamicDraw->SetSortKey(
|
||||
aznumeric_cast<int64_t>(screenPosition.GetZ() * aznumeric_cast<float>(AZStd::numeric_limits<int64_t>::max())));
|
||||
dynamicDraw->DrawIndexed(
|
||||
&vertices, static_cast<uint32_t>(vertices.size()), &indices, static_cast<uint32_t>(indices.size()), RHI::IndexFormat::Uint16,
|
||||
drawSrg);
|
||||
}
|
||||
|
||||
QString AtomViewportDisplayIconsSystemComponent::FindAssetPath(const QString& path) const
|
||||
@@ -354,7 +362,7 @@ namespace AZ::Render
|
||||
{
|
||||
// Once the shader is loaded, register it with the dynamic draw context
|
||||
Data::Asset<RPI::ShaderAsset> shaderAsset = asset;
|
||||
AtomBridge::PerViewportDynamicDraw::Get()->RegisterDynamicDrawContext(m_drawContextName, [shaderAsset](RPI::Ptr<RPI::DynamicDrawContext> drawContext)
|
||||
AtomBridge::PerViewportDynamicDraw::Get()->RegisterDynamicDrawContext(m_drawContextName, [shaderAsset](RPI::Ptr<RPI::DynamicDrawContext> dynamicDraw)
|
||||
{
|
||||
AZ_Assert(shaderAsset->IsReady(), "Attempting to register the AtomViewportDisplayIconsSystemComponent"
|
||||
" dynamic draw context before the shader asset is loaded. The shader should be loaded first"
|
||||
@@ -362,12 +370,11 @@ namespace AZ::Render
|
||||
" will be executed during scene processing and there may be multiple scenes executing in parallel.");
|
||||
|
||||
Data::Instance<RPI::Shader> shader = RPI::Shader::FindOrCreate(shaderAsset);
|
||||
drawContext->InitShader(shader);
|
||||
drawContext->InitVertexFormat(
|
||||
{ {"POSITION", RHI::Format::R32G32B32_FLOAT},
|
||||
{"COLOR", RHI::Format::R8G8B8A8_UNORM},
|
||||
{"TEXCOORD", RHI::Format::R32G32_FLOAT} });
|
||||
drawContext->EndInit();
|
||||
dynamicDraw->InitShader(shader);
|
||||
dynamicDraw->InitVertexFormat({ { "POSITION", RHI::Format::R32G32B32_FLOAT },
|
||||
{ "COLOR", RHI::Format::R8G8B8A8_UNORM },
|
||||
{ "TEXCOORD", RHI::Format::R32G32_FLOAT } });
|
||||
dynamicDraw->EndInit();
|
||||
});
|
||||
|
||||
m_drawContextRegistered = true;
|
||||
|
||||
@@ -2,14 +2,17 @@
|
||||
"gem_name": "AtomViewportDisplayIcons",
|
||||
"display_name": "Atom Viewport Display Icons",
|
||||
"license": "Apache-2.0 Or MIT",
|
||||
"license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt",
|
||||
"origin": "Open 3D Engine - o3de.org",
|
||||
"origin_url": "https://github.com/o3de/o3de",
|
||||
"type": "Code",
|
||||
"summary": "",
|
||||
"summary": "Viewport display icons for Atom",
|
||||
"canonical_tags": [
|
||||
"Gem"
|
||||
],
|
||||
"user_tags": [],
|
||||
"requirements": "",
|
||||
"documentation_url": "",
|
||||
"dependencies": [
|
||||
"Atom_RHI",
|
||||
"Atom_RPI",
|
||||
|
||||
+20
-28
@@ -130,7 +130,8 @@ namespace AZ::Render
|
||||
}
|
||||
AZ::RPI::ViewportContextPtr viewportContext = GetViewportContext();
|
||||
|
||||
if (!m_fontDrawInterface || !viewportContext || !viewportContext->GetRenderScene())
|
||||
if (!m_fontDrawInterface || !viewportContext || !viewportContext->GetRenderScene() ||
|
||||
!AZ::Interface<AzFramework::FontQueryInterface>::Get())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -183,15 +184,6 @@ namespace AZ::Render
|
||||
DrawFramerate();
|
||||
}
|
||||
|
||||
void AtomViewportDisplayInfoSystemComponent::OnFrameEnd()
|
||||
{
|
||||
auto currentTime = AZStd::chrono::system_clock::now();
|
||||
if (!m_fpsHistory.empty())
|
||||
{
|
||||
m_fpsHistory.back().m_endFrameTime = currentTime;
|
||||
}
|
||||
}
|
||||
|
||||
AtomBridge::ViewportInfoDisplayState AtomViewportDisplayInfoSystemComponent::GetDisplayState() const
|
||||
{
|
||||
return aznumeric_cast<AtomBridge::ViewportInfoDisplayState>(r_displayInfo.operator int());
|
||||
@@ -257,11 +249,11 @@ namespace AZ::Render
|
||||
void AtomViewportDisplayInfoSystemComponent::UpdateFramerate()
|
||||
{
|
||||
auto currentTime = AZStd::chrono::system_clock::now();
|
||||
while (!m_fpsHistory.empty() && (currentTime - m_fpsHistory.front().m_beginFrameTime) > m_fpsInterval)
|
||||
while (!m_fpsHistory.empty() && (currentTime - m_fpsHistory.front()) > m_fpsInterval)
|
||||
{
|
||||
m_fpsHistory.pop_front();
|
||||
}
|
||||
m_fpsHistory.push_back(FrameTimingInfo(currentTime));
|
||||
m_fpsHistory.push_back(currentTime);
|
||||
}
|
||||
|
||||
void AtomViewportDisplayInfoSystemComponent::DrawFramerate()
|
||||
@@ -270,42 +262,42 @@ namespace AZ::Render
|
||||
double minFPS = DBL_MAX;
|
||||
double maxFPS = 0;
|
||||
AZStd::chrono::duration<double> deltaTime;
|
||||
AZStd::chrono::milliseconds totalFrameMS(0);
|
||||
for (const auto& time : m_fpsHistory)
|
||||
{
|
||||
if (lastTime.has_value())
|
||||
{
|
||||
deltaTime = time.m_beginFrameTime - lastTime.value();
|
||||
deltaTime = time - lastTime.value();
|
||||
double fps = AZStd::chrono::seconds(1) / deltaTime;
|
||||
minFPS = AZStd::min(minFPS, fps);
|
||||
maxFPS = AZStd::max(maxFPS, fps);
|
||||
}
|
||||
lastTime = time.m_beginFrameTime;
|
||||
|
||||
if (time.m_endFrameTime.has_value())
|
||||
{
|
||||
totalFrameMS += time.m_endFrameTime.value() - time.m_beginFrameTime;
|
||||
}
|
||||
lastTime = time;
|
||||
}
|
||||
|
||||
double averageFPS = 0;
|
||||
double averageFrameMs = 0;
|
||||
if (m_fpsHistory.size() > 1)
|
||||
{
|
||||
deltaTime = m_fpsHistory.back().m_beginFrameTime - m_fpsHistory.front().m_beginFrameTime;
|
||||
averageFPS = AZStd::chrono::seconds(m_fpsHistory.size() - 1) / deltaTime;
|
||||
averageFrameMs = aznumeric_cast<double>(totalFrameMS.count()) / (m_fpsHistory.size() - 1);
|
||||
deltaTime = m_fpsHistory.back() - m_fpsHistory.front();
|
||||
averageFPS = AZStd::chrono::seconds(m_fpsHistory.size()) / deltaTime;
|
||||
averageFrameMs = 1000.0f/averageFPS;
|
||||
}
|
||||
|
||||
const double frameIntervalSeconds = m_fpsInterval.count();
|
||||
|
||||
auto ClampedFloatDisplay = [](double value, const char* format) -> AZStd::string
|
||||
{
|
||||
constexpr float upperLimit = 10000.0f;
|
||||
return value > upperLimit ? "inf" : AZStd::string::format(format, value);
|
||||
};
|
||||
|
||||
DrawLine(
|
||||
AZStd::string::format(
|
||||
"FPS %.1f [%.0f..%.0f], %.1fms/frame, avg over %.1fs",
|
||||
averageFPS,
|
||||
minFPS == DBL_MAX ? 0.0 : minFPS,
|
||||
maxFPS,
|
||||
averageFrameMs,
|
||||
"FPS %s [%s..%s], %sms/frame, avg over %.1fs",
|
||||
ClampedFloatDisplay(averageFPS, "%.1f").c_str(),
|
||||
ClampedFloatDisplay(minFPS, "%.0f").c_str(),
|
||||
ClampedFloatDisplay(maxFPS, "%.0f").c_str(),
|
||||
ClampedFloatDisplay(averageFrameMs, "%.1f").c_str(),
|
||||
frameIntervalSeconds),
|
||||
AZ::Colors::Yellow);
|
||||
}
|
||||
|
||||
+1
-14
@@ -45,7 +45,6 @@ namespace AZ
|
||||
|
||||
// AZ::RPI::ViewportContextNotificationBus::Handler overrides...
|
||||
void OnRenderTick() override;
|
||||
void OnFrameEnd() override;
|
||||
|
||||
// AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Handler overrides...
|
||||
AtomBridge::ViewportInfoDisplayState GetDisplayState() const override;
|
||||
@@ -62,8 +61,6 @@ namespace AZ
|
||||
void DrawPassInfo();
|
||||
void DrawFramerate();
|
||||
|
||||
void UpdateScene(AZ::RPI::ScenePtr scene);
|
||||
|
||||
static constexpr float BaseFontSize = 0.7f;
|
||||
|
||||
AZStd::string m_rendererDescription;
|
||||
@@ -71,17 +68,7 @@ namespace AZ
|
||||
AzFramework::FontDrawInterface* m_fontDrawInterface = nullptr;
|
||||
float m_lineSpacing;
|
||||
AZStd::chrono::duration<double> m_fpsInterval = AZStd::chrono::seconds(1);
|
||||
struct FrameTimingInfo
|
||||
{
|
||||
AZStd::chrono::system_clock::time_point m_beginFrameTime;
|
||||
AZStd::optional<AZStd::chrono::system_clock::time_point> m_endFrameTime;
|
||||
|
||||
explicit FrameTimingInfo(AZStd::chrono::system_clock::time_point beginFrameTime)
|
||||
: m_beginFrameTime(beginFrameTime)
|
||||
{
|
||||
}
|
||||
};
|
||||
AZStd::deque<FrameTimingInfo> m_fpsHistory;
|
||||
AZStd::deque<AZStd::chrono::system_clock::time_point> m_fpsHistory;
|
||||
AZStd::optional<AZStd::chrono::system_clock::time_point> m_lastMemoryUpdate;
|
||||
bool m_updateRootPassQuery = true;
|
||||
};
|
||||
|
||||
@@ -2,14 +2,17 @@
|
||||
"gem_name": "AtomViewportDisplayInfo",
|
||||
"display_name": "Atom Viewport Display Info",
|
||||
"license": "Apache-2.0 Or MIT",
|
||||
"license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt",
|
||||
"origin": "Open 3D Engine - o3de.org",
|
||||
"origin_url": "https://github.com/o3de/o3de",
|
||||
"type": "Code",
|
||||
"summary": "",
|
||||
"summary": "Viewport Display Information for Atom",
|
||||
"canonical_tags": [
|
||||
"Gem"
|
||||
],
|
||||
"user_tags": [],
|
||||
"requirements": "",
|
||||
"documentation_url": "",
|
||||
"dependencies": [
|
||||
"Atom_RHI",
|
||||
"Atom_RPI"
|
||||
|
||||
@@ -6,13 +6,4 @@
|
||||
#
|
||||
#
|
||||
|
||||
add_subdirectory(CommonFeatures)
|
||||
add_subdirectory(ImguiAtom)
|
||||
add_subdirectory(AtomImGuiTools)
|
||||
add_subdirectory(EMotionFXAtom)
|
||||
add_subdirectory(AtomFont)
|
||||
add_subdirectory(TechnicalArt)
|
||||
add_subdirectory(AtomBridge)
|
||||
add_subdirectory(AtomViewportDisplayInfo)
|
||||
add_subdirectory(AtomViewportDisplayIcons)
|
||||
|
||||
|
||||
@@ -836,7 +836,7 @@
|
||||
</Class>
|
||||
<Class name="AZ::Render::MeshComponentController" field="Controller" type="{D0F35FAC-4194-4C89-9487-D000DDB8B272}">
|
||||
<Class name="AZ::Render::MeshComponentConfig" field="Configuration" version="1" type="{63737345-51B1-472B-9355-98F99993909B}">
|
||||
<Class name="Asset" field="ModelAsset" value="id={935F694A-8639-515B-8133-81CDC7948E5B}:1087c6db,type={2C7477B6-69C5-45BE-8163-BCD6A275B6D8},hint={objects/groudplane/groundplane_521x521m.azmodel},loadBehavior=1" version="2" type="{77A19D40-8731-4D3C-9041-1B43047366A4}"/>
|
||||
<Class name="Asset" field="ModelAsset" value="id={0CD745C0-6AA8-569A-A68A-73A3270986C4}:10904372,type={2C7477B6-69C5-45BE-8163-BCD6A275B6D8},hint={objects/groudplane/groundplane_512x512m.azmodel},loadBehavior=1" version="2" type="{77A19D40-8731-4D3C-9041-1B43047366A4}"/>
|
||||
<Class name="AZ::s64" field="SortKey" value="0" type="{70D8A282-A1EA-462D-9D04-51EDE81FAC2F}"/>
|
||||
<Class name="unsigned char" field="LodOverride" value="255" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
|
||||
<Class name="bool" field="ExcludeFromReflectionCubeMaps" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d72cec207a7677ba027eac72f41285907237e04a45ebacf64341de86fc6f022d
|
||||
size 159115308
|
||||
+10
-16
@@ -1,39 +1,33 @@
|
||||
{
|
||||
"description": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"parentMaterial": "Materials/Presets/PBR/metal_brass.material",
|
||||
"propertyLayoutVersion": 3,
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 4,
|
||||
"properties": {
|
||||
"occlusion": {
|
||||
"diffuseTextureMap": "Objects/Lucy/Lucy_ao.tif",
|
||||
"diffuseTextureMapUv": "Unwrapped"
|
||||
},
|
||||
"baseColor": {
|
||||
"color": [
|
||||
0.6745098233222961,
|
||||
0.48627451062202456,
|
||||
0.19607843458652497,
|
||||
1.0
|
||||
],
|
||||
"factor": 1.0,
|
||||
"textureBlendMode": "Lerp",
|
||||
"textureMap": "Objects/Lucy/Lucy_bronze_BaseColor.png",
|
||||
"textureMap": "Hermanubis_bronze_BaseColor.png",
|
||||
"textureMapUv": "Unwrapped"
|
||||
},
|
||||
"general": {
|
||||
"applySpecularAA": true
|
||||
},
|
||||
"metallic": {
|
||||
"textureMap": "Objects/Lucy/Lucy_bronze_Metallic.png",
|
||||
"textureMap": "Hermanubis_bronze_Metallic.png",
|
||||
"textureMapUv": "Unwrapped"
|
||||
},
|
||||
"normal": {
|
||||
"flipY": true,
|
||||
"textureMap": "Objects/Lucy/Lucy_Normal.png",
|
||||
"textureMap": "Hermanubis_Normal.png",
|
||||
"textureMapUv": "Unwrapped"
|
||||
},
|
||||
"occlusion": {
|
||||
"diffuseTextureMap": "Hermanubis_ao.tif",
|
||||
"diffuseTextureMapUv": "Unwrapped"
|
||||
},
|
||||
"roughness": {
|
||||
"textureMap": "Objects/Lucy/Lucy_bronze_Roughness.png",
|
||||
"textureMap": "Hermanubis_bronze_Roughness.png",
|
||||
"textureMapUv": "Unwrapped",
|
||||
"upperBound": 0.6767677068710327
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:4c9d1030b9467b58d640fbedf1bc58ab9a5f7d68811b2452dd8d60114287b731
|
||||
size 12410812
|
||||
+10
-10
@@ -1,13 +1,9 @@
|
||||
{
|
||||
"description": "",
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"parentMaterial": "Materials/Presets/PBR/metal_brass.material",
|
||||
"propertyLayoutVersion": 3,
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 4,
|
||||
"properties": {
|
||||
"occlusion": {
|
||||
"diffuseTextureMap": "Objects/Lucy/Lucy_ao.tif",
|
||||
"diffuseTextureMapUv": "Unwrapped"
|
||||
},
|
||||
"baseColor": {
|
||||
"color": [
|
||||
1.0,
|
||||
@@ -17,7 +13,7 @@
|
||||
],
|
||||
"factor": 1.0,
|
||||
"textureBlendMode": "Lerp",
|
||||
"textureMap": "Objects/Lucy/Lucy_Stone_BaseColor.png",
|
||||
"textureMap": "Hermanubis_Stone_BaseColor.png",
|
||||
"textureMapUv": "Unwrapped"
|
||||
},
|
||||
"clearCoat": {
|
||||
@@ -39,13 +35,17 @@
|
||||
},
|
||||
"normal": {
|
||||
"flipY": true,
|
||||
"textureMap": "Objects/Lucy/Lucy_Normal.png",
|
||||
"textureMap": "Hermanubis_Normal.png",
|
||||
"textureMapUv": "Unwrapped"
|
||||
},
|
||||
"occlusion": {
|
||||
"diffuseTextureMap": "Hermanubis_ao.tif",
|
||||
"diffuseTextureMapUv": "Unwrapped"
|
||||
},
|
||||
"roughness": {
|
||||
"factor": 1.0,
|
||||
"lowerBound": 0.15000000596046449,
|
||||
"textureMap": "Objects/Lucy/Lucy_bronze_Roughness.png",
|
||||
"lowerBound": 0.15000000596046448,
|
||||
"textureMap": "Hermanubis_bronze_Roughness.png",
|
||||
"textureMapUv": "Unwrapped",
|
||||
"upperBound": 0.7300000190734863
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:00e19e317613be5420fd78bac1159e66d1c4deeb1f32cd4fc8c20b1ea3a5ead1
|
||||
size 153114272
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6a4a65d139a6088dd4ac34f3ba3f6a7a98b8fe9545150ee7d9879fbc2a55d8d4
|
||||
size 9022128
|
||||
@@ -0,0 +1,45 @@
|
||||
<ObjectStream version="3">
|
||||
<Class name="AZStd::vector" type="{82FC5264-88D0-57CD-9307-FC52E4DAD550}">
|
||||
<Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
|
||||
<Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
|
||||
<Class name="AZ::Uuid" field="guid" value="{4F3761EF-E279-5FDD-98C3-EF90F924FBAC}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
<Class name="unsigned int" field="subId" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
</Class>
|
||||
<Class name="unsigned int" field="platformFlags" value="3" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="AZStd::string" field="pathHint" value="lightingpresets/thumbnail.lightingpreset.azasset" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
</Class>
|
||||
<Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
|
||||
<Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
|
||||
<Class name="AZ::Uuid" field="guid" value="{6DE0E9A8-A1C7-5D0F-9407-4E627C1F223C}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
<Class name="unsigned int" field="subId" value="284780167" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
</Class>
|
||||
<Class name="unsigned int" field="platformFlags" value="3" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="AZStd::string" field="pathHint" value="models/sphere.azmodel" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
</Class>
|
||||
<Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
|
||||
<Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
|
||||
<Class name="AZ::Uuid" field="guid" value="{CF91AE08-8FD5-538B-A5F2-427DFA9D5E1C}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
<Class name="unsigned int" field="subId" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
</Class>
|
||||
<Class name="unsigned int" field="platformFlags" value="3" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="AZStd::string" field="pathHint" value="materials/basic_grey.azmaterial" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
</Class>
|
||||
<Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
|
||||
<Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
|
||||
<Class name="AZ::Uuid" field="guid" value="{DCE9A5B2-1907-5A0D-8A96-5ABF608D103B}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
<Class name="unsigned int" field="subId" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
</Class>
|
||||
<Class name="unsigned int" field="platformFlags" value="3" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="AZStd::string" field="pathHint" value="passes/mainpipeline.pass" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
</Class>
|
||||
<Class name="SeedInfo" field="element" version="2" type="{FACC3682-2ACA-4AA4-B85A-07AD276D18A0}">
|
||||
<Class name="AssetId" field="assetId" version="1" type="{652ED536-3402-439B-AEBE-4A5DBC554085}">
|
||||
<Class name="AZ::Uuid" field="guid" value="{6B01EDAB-1951-5588-AB7B-DF2F703950D4}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
<Class name="unsigned int" field="subId" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
</Class>
|
||||
<Class name="unsigned int" field="platformFlags" value="3" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="AZStd::string" field="pathHint" value="passes/smaaconfiguration.azasset" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
</ObjectStream>
|
||||
|
||||
@@ -6,4 +6,8 @@
|
||||
#
|
||||
#
|
||||
|
||||
set(gem_path ${CMAKE_CURRENT_LIST_DIR})
|
||||
set(gem_json ${gem_path}/gem.json)
|
||||
o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path)
|
||||
|
||||
add_subdirectory(Code)
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
#
|
||||
#
|
||||
|
||||
ly_get_list_relative_pal_filename(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME})
|
||||
ly_get_list_relative_pal_filename(common_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/Common)
|
||||
o3de_pal_dir(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${gem_restricted_path} ${gem_path} ${gem_parent_relative_path})
|
||||
set(common_source_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/Common)
|
||||
|
||||
ly_add_target(
|
||||
NAME AtomLyIntegration_CommonFeatures.Public HEADERONLY
|
||||
@@ -77,8 +77,7 @@ ly_create_alias(NAME AtomLyIntegration_CommonFeatures.Servers NAMESPACE Gem
|
||||
|
||||
if(PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
ly_add_target(
|
||||
NAME AtomLyIntegration_CommonFeatures.Editor GEM_MODULE
|
||||
|
||||
NAME AtomLyIntegration_CommonFeatures.Editor.Static STATIC
|
||||
NAMESPACE Gem
|
||||
AUTOUIC
|
||||
AUTOMOC
|
||||
@@ -86,6 +85,8 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
FILES_CMAKE
|
||||
atomlyintegration_commonfeatures_editor_files.cmake
|
||||
${pal_source_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
|
||||
PLATFORM_INCLUDE_FILES
|
||||
${pal_source_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}.cmake
|
||||
INCLUDE_DIRECTORIES
|
||||
PRIVATE
|
||||
.
|
||||
@@ -96,7 +97,7 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
PRIVATE
|
||||
ATOMLYINTEGRATION_FEATURE_COMMON_EDITOR
|
||||
BUILD_DEPENDENCIES
|
||||
PRIVATE
|
||||
PUBLIC
|
||||
Gem::AtomLyIntegration_CommonFeatures.Static
|
||||
Gem::Atom_RPI.Edit
|
||||
Gem::AtomToolsFramework.Static
|
||||
@@ -106,9 +107,28 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
Legacy::Editor.Headers
|
||||
Legacy::EditorCommon
|
||||
Legacy::CryCommon
|
||||
)
|
||||
|
||||
ly_add_target(
|
||||
NAME AtomLyIntegration_CommonFeatures.Editor GEM_MODULE
|
||||
NAMESPACE Gem
|
||||
FILES_CMAKE
|
||||
atomlyintegration_commonfeatures_shared_files.cmake
|
||||
INCLUDE_DIRECTORIES
|
||||
PRIVATE
|
||||
Source
|
||||
PUBLIC
|
||||
Include
|
||||
COMPILE_DEFINITIONS
|
||||
PRIVATE
|
||||
ATOMLYINTEGRATION_FEATURE_COMMON_EDITOR
|
||||
BUILD_DEPENDENCIES
|
||||
PRIVATE
|
||||
Gem::AtomLyIntegration_CommonFeatures.Editor.Static
|
||||
RUNTIME_DEPENDENCIES
|
||||
Gem::Atom_RPI.Editor
|
||||
Gem::Atom_Feature_Common.Editor
|
||||
Gem::AtomToolsFramework.Editor
|
||||
Legacy::EditorCommon
|
||||
)
|
||||
|
||||
@@ -125,6 +145,33 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
Gem::AtomLyIntegration_CommonFeatures.Editor
|
||||
Gem::GradientSignal.Tools
|
||||
)
|
||||
|
||||
################################################################################
|
||||
# Tests
|
||||
################################################################################
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
|
||||
ly_add_target(
|
||||
NAME AtomLyIntegration_CommonFeatures.Editor.Tests ${PAL_TRAIT_TEST_TARGET_TYPE}
|
||||
NAMESPACE Gem
|
||||
FILES_CMAKE
|
||||
atomlyintegration_commonfeatures_editor_test_files.cmake
|
||||
INCLUDE_DIRECTORIES
|
||||
PRIVATE
|
||||
Tests
|
||||
Source
|
||||
BUILD_DEPENDENCIES
|
||||
PRIVATE
|
||||
AZ::AzTest
|
||||
AZ::AzTestShared
|
||||
AZ::AzToolsFramework
|
||||
AZ::AzToolsFrameworkTestCommon
|
||||
Gem::AtomLyIntegration_CommonFeatures.Static
|
||||
Gem::AtomLyIntegration_CommonFeatures.Editor.Static
|
||||
)
|
||||
ly_add_googletest(
|
||||
NAME Gem::AtomLyIntegration_CommonFeatures.Editor.Tests
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# AtomLyIntegration_CommonFeatures gem targets are required as part of the Editor and AssetProcessor
|
||||
|
||||
+7
-7
@@ -120,13 +120,6 @@ namespace AZ
|
||||
//! Sets the filter method of shadows.
|
||||
virtual void SetShadowFilterMethod(ShadowFilterMethod method) = 0;
|
||||
|
||||
//! Gets the width of softening boundary between shadowed area and lit area in degrees.
|
||||
virtual float GetSofteningBoundaryWidthAngle() const = 0;
|
||||
|
||||
//! Sets the width of softening boundary between shadowed area and lit area in degrees.
|
||||
//! 0 disables softening.
|
||||
virtual void SetSofteningBoundaryWidthAngle(float degrees) = 0;
|
||||
|
||||
//! Gets the sample count for filtering of the shadow boundary.
|
||||
virtual uint32_t GetFilteringSampleCount() const = 0;
|
||||
|
||||
@@ -139,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
-1
@@ -57,9 +57,9 @@ 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;
|
||||
float m_boundaryWidthInDegrees = 0.25f;
|
||||
uint16_t m_filteringSampleCount = 12;
|
||||
float m_esmExponent = 87.0f;
|
||||
|
||||
|
||||
+24
-9
@@ -153,15 +153,6 @@ namespace AZ
|
||||
//! @param method filter method.
|
||||
virtual void SetShadowFilterMethod(ShadowFilterMethod method) = 0;
|
||||
|
||||
//! This gets the width of boundary between shadowed area and lit area.
|
||||
//! @return Boundary width. The shadow is gradually changed the degree of shadowed.
|
||||
virtual float GetSofteningBoundaryWidth() const = 0;
|
||||
|
||||
//! This specifies the width of boundary between shadowed area and lit area.
|
||||
//! @param width Boundary width. The shadow is gradually changed the degree of shadowed.
|
||||
//! If width == 0, softening edge is disabled. Units are in meters.
|
||||
virtual void SetSofteningBoundaryWidth(float width) = 0;
|
||||
|
||||
//! This gets the sample count for filtering of the shadow boundary.
|
||||
//! @return Sample Count for filtering (up to 64)
|
||||
virtual uint32_t GetFilteringSampleCount() const = 0;
|
||||
@@ -177,6 +168,30 @@ namespace AZ
|
||||
//! Sets whether the directional shadowmap should use receiver plane bias.
|
||||
//! @param enable flag specifying whether to enable the receiver plane bias feature
|
||||
virtual void SetShadowReceiverPlaneBiasEnabled(bool enable) = 0;
|
||||
|
||||
//! Shadow bias reduces acne by applying a small amount of offset along shadow-space z.
|
||||
//! @return Returns the amount of bias to apply.
|
||||
virtual float GetShadowBias() const = 0;
|
||||
|
||||
//! Shadow bias reduces acne by applying a small amount of offset along shadow-space z.
|
||||
//! @param Sets the amount of bias to apply.
|
||||
virtual void SetShadowBias(float bias) = 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;
|
||||
|
||||
//! 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>;
|
||||
|
||||
|
||||
+8
-3
@@ -101,9 +101,8 @@ namespace AZ
|
||||
//! Method of shadow's filtering.
|
||||
ShadowFilterMethod m_shadowFilterMethod = ShadowFilterMethod::None;
|
||||
|
||||
//! Width of the boundary between shadowed area and lit one.
|
||||
//! If this is 0, edge softening is disabled. Units are in meters.
|
||||
float m_boundaryWidth = 0.03f; // 3cm
|
||||
// Reduces acne by biasing the shadowmap lookup along the geometric normal.
|
||||
float m_normalShadowBias = 0.0f;
|
||||
|
||||
//! Sample Count for filtering (from 4 to 64)
|
||||
//! It is used only when the pixel is predicted as on the boundary.
|
||||
@@ -113,6 +112,12 @@ namespace AZ
|
||||
//! This uses partial derivatives to reduce shadow acne when using large pcf kernels.
|
||||
bool m_receiverPlaneBiasEnabled = true;
|
||||
|
||||
//! 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;
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <Atom/Feature/Material/MaterialAssignmentId.h>
|
||||
#include <AzCore/Component/EntityId.h>
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
|
||||
class QPixmap;
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
//! EditorMaterialSystemComponentNotifications is an interface for handling notifications from EditorMaterialSystemComponent, like
|
||||
//! being informed that material preview images are available
|
||||
class EditorMaterialSystemComponentNotifications : public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
|
||||
|
||||
//! Notify that a material preview image is ready
|
||||
virtual void OnRenderMaterialPreviewComplete(
|
||||
const AZ::EntityId& entityId, const AZ::Render::MaterialAssignmentId& materialAssignmentId, const QPixmap& pixmap) = 0;
|
||||
};
|
||||
using EditorMaterialSystemComponentNotificationBus = AZ::EBus<EditorMaterialSystemComponentNotifications>;
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
+13
-3
@@ -5,20 +5,22 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Atom/Feature/Material/MaterialAssignmentId.h>
|
||||
#include <AzCore/Component/EntityId.h>
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <QPixmap>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
//! EditorMaterialSystemComponentRequests provides an interface to communicate with MaterialEditor
|
||||
class EditorMaterialSystemComponentRequests
|
||||
: public AZ::EBusTraits
|
||||
//! EditorMaterialSystemComponentRequests provides an interface for interacting with EditorMaterialSystemComponent, performing
|
||||
//! different operations like opening the material editor, the material instance inspector, and managing material preview images
|
||||
class EditorMaterialSystemComponentRequests : public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
// Only a single handler is allowed
|
||||
@@ -31,6 +33,14 @@ namespace AZ
|
||||
//! Open material instance editor
|
||||
virtual void OpenMaterialInspector(
|
||||
const AZ::EntityId& entityId, const AZ::Render::MaterialAssignmentId& materialAssignmentId) = 0;
|
||||
|
||||
//! Generate a material preview image
|
||||
virtual void RenderMaterialPreview(
|
||||
const AZ::EntityId& entityId, const AZ::Render::MaterialAssignmentId& materialAssignmentId) = 0;
|
||||
|
||||
//! Get recently rendered material preview image
|
||||
virtual QPixmap GetRenderedMaterialPreview(
|
||||
const AZ::EntityId& entityId, const AZ::Render::MaterialAssignmentId& materialAssignmentId) const = 0;
|
||||
};
|
||||
using EditorMaterialSystemComponentRequestBus = AZ::EBus<EditorMaterialSystemComponentRequests>;
|
||||
} // namespace Render
|
||||
|
||||
+21
-44
@@ -43,6 +43,9 @@ namespace AZ
|
||||
virtual void ClearInvalidMaterialOverrides() = 0;
|
||||
//! Repair materials that reference missing assets by assigning the default asset
|
||||
virtual void RepairInvalidMaterialOverrides() = 0;
|
||||
//! Repair material property overrides that reference missing properties by auto-renaming them where possible
|
||||
//! @return the number of properties that were updated
|
||||
virtual uint32_t ApplyAutomaticPropertyUpdates() = 0;
|
||||
//! Set default material override
|
||||
virtual void SetDefaultMaterialOverride(const AZ::Data::AssetId& materialAssetId) = 0;
|
||||
//! Get default material override
|
||||
@@ -57,52 +60,8 @@ namespace AZ
|
||||
virtual void ClearMaterialOverride(const MaterialAssignmentId& materialAssignmentId) = 0;
|
||||
//! Set a material property override value wrapped by an AZStd::any
|
||||
virtual void SetPropertyOverride(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName, const AZStd::any& value) = 0;
|
||||
//! Set a material property override value to a bool
|
||||
virtual void SetPropertyOverrideBool(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName, const bool& value) = 0;
|
||||
//! Set a material property override value to a integer
|
||||
virtual void SetPropertyOverrideInt32(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName, const int32_t& value) = 0;
|
||||
//! Set a material property override value to a unsigned integer
|
||||
virtual void SetPropertyOverrideUInt32(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName, const uint32_t& value) = 0;
|
||||
//! Set a material property override value to a float
|
||||
virtual void SetPropertyOverrideFloat(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName, const float& value) = 0;
|
||||
//! Set a material property override value to a Vector2
|
||||
virtual void SetPropertyOverrideVector2(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName, const AZ::Vector2& value) = 0;
|
||||
//! Set a material property override value to a Vector3
|
||||
virtual void SetPropertyOverrideVector3(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName, const AZ::Vector3& value) = 0;
|
||||
//! Set a material property override value to a Vector4
|
||||
virtual void SetPropertyOverrideVector4(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName, const AZ::Vector4& value) = 0;
|
||||
//! Set a material property override value to a color
|
||||
virtual void SetPropertyOverrideColor(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName, const AZ::Color& value) = 0;
|
||||
//! Set a material property override value to an image asset
|
||||
virtual void SetPropertyOverrideImageAsset(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName, const AZ::Data::Asset<AZ::RPI::ImageAsset>& value) = 0;
|
||||
//! Set a material property override value to an image instance
|
||||
virtual void SetPropertyOverrideImageInstance(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName, const AZ::Data::Instance<AZ::RPI::Image>& value) = 0;
|
||||
//! Set a material property override value to a string
|
||||
virtual void SetPropertyOverrideString(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName, const AZStd::string& value) = 0;
|
||||
//! Get a material property override value wrapped by an AZStd::any
|
||||
virtual AZStd::any GetPropertyOverride(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName) const = 0;
|
||||
//! Get a material property override value as a bool
|
||||
virtual bool GetPropertyOverrideBool(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName) const = 0;
|
||||
//! Get a material property override value as an integer
|
||||
virtual int32_t GetPropertyOverrideInt32(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName) const = 0;
|
||||
//! Get a material property override value as an unsigned integer
|
||||
virtual uint32_t GetPropertyOverrideUInt32(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName) const = 0;
|
||||
//! Get a material property override value as a float
|
||||
virtual float GetPropertyOverrideFloat(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName) const = 0;
|
||||
//! Get a material property override value as a Vector2
|
||||
virtual AZ::Vector2 GetPropertyOverrideVector2(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName) const = 0;
|
||||
//! Get a material property override value as a Vector3
|
||||
virtual AZ::Vector3 GetPropertyOverrideVector3(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName) const = 0;
|
||||
//! Get a material property override value as a Vector4
|
||||
virtual AZ::Vector4 GetPropertyOverrideVector4(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName) const = 0;
|
||||
//! Get a material property override value as a Color
|
||||
virtual AZ::Color GetPropertyOverrideColor(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName) const = 0;
|
||||
//! Get a material property override value as an image asset
|
||||
virtual AZ::Data::Asset<AZ::RPI::ImageAsset> GetPropertyOverrideImageAsset(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName) const = 0;
|
||||
//! Get a material property override value as an image instance
|
||||
virtual AZ::Data::Instance<AZ::RPI::Image> GetPropertyOverrideImageInstance(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName) const = 0;
|
||||
//! Get a material property override value as a string
|
||||
virtual AZStd::string GetPropertyOverrideString(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName) const = 0;
|
||||
//! Clear property override for a specific material assignment
|
||||
virtual void ClearPropertyOverride(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName) = 0;
|
||||
//! Clear property overrides for a specific material assignment
|
||||
@@ -119,6 +78,21 @@ namespace AZ
|
||||
const MaterialAssignmentId& materialAssignmentId, const AZ::RPI::MaterialModelUvOverrideMap& modelUvOverrides) = 0;
|
||||
//! Get Model UV overrides for a specific material assignment
|
||||
virtual AZ::RPI::MaterialModelUvOverrideMap GetModelUvOverrides(const MaterialAssignmentId& materialAssignmentId) const = 0;
|
||||
|
||||
//! Set material property override value with a specific type
|
||||
template<typename T>
|
||||
void SetPropertyOverrideT(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName, const T& value)
|
||||
{
|
||||
SetPropertyOverride(materialAssignmentId, propertyName, AZStd::any(value));
|
||||
}
|
||||
|
||||
//! Get material property override value with a specific type
|
||||
template<typename T>
|
||||
T GetPropertyOverrideT(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName) const
|
||||
{
|
||||
const AZStd::any& value = GetPropertyOverride(materialAssignmentId, propertyName);
|
||||
return !value.empty() && value.is<T>() ? AZStd::any_cast<T>(value) : T{};
|
||||
}
|
||||
};
|
||||
using MaterialComponentRequestBus = EBus<MaterialComponentRequests>;
|
||||
|
||||
@@ -151,7 +125,9 @@ namespace AZ
|
||||
//! Returns the list of all ModelMaterialSlot's for the model, across all LODs.
|
||||
virtual RPI::ModelMaterialSlotMap GetModelMaterialSlots() const = 0;
|
||||
|
||||
//! Returns the available, overridable material slots and the default assigned materials
|
||||
virtual MaterialAssignmentMap GetMaterialAssignments() const = 0;
|
||||
|
||||
virtual AZStd::unordered_set<AZ::Name> GetModelUvNames() const = 0;
|
||||
};
|
||||
using MaterialReceiverRequestBus = EBus<MaterialReceiverRequests>;
|
||||
@@ -161,6 +137,7 @@ namespace AZ
|
||||
: public ComponentBus
|
||||
{
|
||||
public:
|
||||
//! Notification that overridable material slots are available or have changed
|
||||
virtual void OnMaterialAssignmentsChanged() = 0;
|
||||
};
|
||||
using MaterialReceiverNotificationBus = EBus<MaterialReceiverNotifications>;
|
||||
|
||||
+3
@@ -51,6 +51,9 @@ namespace AZ
|
||||
virtual void SetVisibility(bool visible) = 0;
|
||||
virtual bool GetVisibility() const = 0;
|
||||
|
||||
virtual void SetRayTracingEnabled(bool enabled) = 0;
|
||||
virtual bool GetRayTracingEnabled() const = 0;
|
||||
|
||||
virtual AZ::Aabb GetWorldBounds() = 0;
|
||||
|
||||
virtual AZ::Aabb GetLocalBounds() = 0;
|
||||
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* 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/EBus/EBus.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace LyIntegration
|
||||
{
|
||||
namespace Thumbnails
|
||||
{
|
||||
//! ThumbnailFeatureProcessorProviderRequests allows registering custom Feature Processors for thumbnail generation
|
||||
//! Duplicates will be ignored
|
||||
//! You can check minimal feature processors that are already registered in CommonThumbnailRenderer.cpp
|
||||
class ThumbnailFeatureProcessorProviderRequests
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
//! Get a list of custom feature processors to register with thumbnail renderer
|
||||
virtual const AZStd::vector<AZStd::string>& GetCustomFeatureProcessors() const = 0;
|
||||
};
|
||||
|
||||
using ThumbnailFeatureProcessorProviderBus = AZ::EBus<ThumbnailFeatureProcessorProviderRequests>;
|
||||
} // namespace Thumbnails
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
@@ -6,10 +6,10 @@
|
||||
*
|
||||
*/
|
||||
#include "AttachmentComponent.h"
|
||||
#include <Atom/RPI.Reflect/Model/ModelAsset.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <MathConversion.h>
|
||||
#include <LmbrCentral/Rendering/MeshAsset.h>
|
||||
#include <LmbrCentral/Animation/AttachmentComponentBus.h>
|
||||
#include <LmbrCentral/Animation/SkeletalHierarchyRequestBus.h>
|
||||
@@ -57,13 +57,17 @@ namespace AZ
|
||||
behaviorContext->EBus<LmbrCentral::AttachmentComponentRequestBus>("AttachmentComponentRequestBus")
|
||||
->Event("Attach", &LmbrCentral::AttachmentComponentRequestBus::Events::Attach)
|
||||
->Event("Detach", &LmbrCentral::AttachmentComponentRequestBus::Events::Detach)
|
||||
->Event("SetAttachmentOffset", &LmbrCentral::AttachmentComponentRequestBus::Events::SetAttachmentOffset);
|
||||
->Event("SetAttachmentOffset", &LmbrCentral::AttachmentComponentRequestBus::Events::SetAttachmentOffset)
|
||||
->Event("GetJointName", &LmbrCentral::AttachmentComponentRequestBus::Events::GetJointName)
|
||||
->Event("GetTargetEntityId", &LmbrCentral::AttachmentComponentRequestBus::Events::GetTargetEntityId)
|
||||
->Event("GetOffset", &LmbrCentral::AttachmentComponentRequestBus::Events::GetOffset);
|
||||
|
||||
behaviorContext->EBus<LmbrCentral::AttachmentComponentNotificationBus>("AttachmentComponentNotificationBus")
|
||||
->Handler<BehaviorAttachmentComponentNotificationBusHandler>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AttachmentComponent::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
AttachmentConfiguration::Reflect(context);
|
||||
|
||||
+2
-1
@@ -12,6 +12,7 @@
|
||||
#include <AzCore/Math/Quaternion.h>
|
||||
#include <AzCore/Math/Transform.h>
|
||||
#include <LmbrCentral/Animation/SkeletalHierarchyRequestBus.h>
|
||||
#include <Atom/RPI.Reflect/Model/ModelAsset.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -70,7 +71,7 @@ namespace AZ
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->Attribute(
|
||||
AZ::Edit::Attributes::HelpPageURL,
|
||||
"https://o3de.org/docs/user-guide/components/reference/attachment/")
|
||||
"https://o3de.org/docs/user-guide/components/reference/animation/attachment/")
|
||||
->DataElement(0, &EditorAttachmentComponent::m_targetId, "Target entity", "Attach to this entity.")
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorAttachmentComponent::OnTargetIdChanged)
|
||||
->DataElement(
|
||||
|
||||
+1
-1
@@ -34,9 +34,9 @@ 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("Softening Boundary Width", &AreaLightComponentConfig::m_boundaryWidthInDegrees)
|
||||
->Field("Filtering Sample Count", &AreaLightComponentConfig::m_filteringSampleCount)
|
||||
->Field("Esm Exponent", &AreaLightComponentConfig::m_esmExponent)
|
||||
;
|
||||
|
||||
+23
-18
@@ -70,12 +70,12 @@ 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)
|
||||
->Event("SetShadowFilterMethod", &AreaLightRequestBus::Events::SetShadowFilterMethod)
|
||||
->Event("GetSofteningBoundaryWidthAngle", &AreaLightRequestBus::Events::GetSofteningBoundaryWidthAngle)
|
||||
->Event("SetSofteningBoundaryWidthAngle", &AreaLightRequestBus::Events::SetSofteningBoundaryWidthAngle)
|
||||
->Event("GetFilteringSampleCount", &AreaLightRequestBus::Events::GetFilteringSampleCount)
|
||||
->Event("SetFilteringSampleCount", &AreaLightRequestBus::Events::SetFilteringSampleCount)
|
||||
->Event("GetEsmExponent", &AreaLightRequestBus::Events::GetEsmExponent)
|
||||
@@ -93,9 +93,9 @@ namespace AZ::Render
|
||||
|
||||
->VirtualProperty("ShadowsEnabled", "GetEnableShadow", "SetEnableShadow")
|
||||
->VirtualProperty("ShadowBias", "GetShadowBias", "SetShadowBias")
|
||||
->VirtualProperty("NormalShadowBias", "GetNormalShadowBias", "SetNormalShadowBias")
|
||||
->VirtualProperty("ShadowmapMaxSize", "GetShadowmapMaxSize", "SetShadowmapMaxSize")
|
||||
->VirtualProperty("ShadowFilterMethod", "GetShadowFilterMethod", "SetShadowFilterMethod")
|
||||
->VirtualProperty("SofteningBoundaryWidthAngle", "GetSofteningBoundaryWidthAngle", "SetSofteningBoundaryWidthAngle")
|
||||
->VirtualProperty("FilteringSampleCount", "GetFilteringSampleCount", "SetFilteringSampleCount")
|
||||
->VirtualProperty("EsmExponent", "GetEsmExponent", "SetEsmExponent");
|
||||
;
|
||||
@@ -261,6 +261,11 @@ namespace AZ::Render
|
||||
m_lightShapeDelegate->SetPhotometricUnit(m_configuration.m_intensityMode);
|
||||
m_lightShapeDelegate->SetIntensity(m_configuration.m_intensity);
|
||||
}
|
||||
|
||||
if (m_configuration.m_attenuationRadiusMode == LightAttenuationRadiusMode::Automatic)
|
||||
{
|
||||
AttenuationRadiusChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void AreaLightComponentController::ChromaChanged()
|
||||
@@ -305,9 +310,9 @@ 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->SetSofteningBoundaryWidthAngle(m_configuration.m_boundaryWidthInDegrees);
|
||||
m_lightShapeDelegate->SetFilteringSampleCount(m_configuration.m_filteringSampleCount);
|
||||
m_lightShapeDelegate->SetEsmExponent(m_configuration.m_esmExponent);
|
||||
}
|
||||
@@ -478,6 +483,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;
|
||||
@@ -506,20 +525,6 @@ namespace AZ::Render
|
||||
}
|
||||
}
|
||||
|
||||
float AreaLightComponentController::GetSofteningBoundaryWidthAngle() const
|
||||
{
|
||||
return m_configuration.m_boundaryWidthInDegrees;
|
||||
}
|
||||
|
||||
void AreaLightComponentController::SetSofteningBoundaryWidthAngle(float width)
|
||||
{
|
||||
m_configuration.m_boundaryWidthInDegrees = width;
|
||||
if (m_lightShapeDelegate)
|
||||
{
|
||||
m_lightShapeDelegate->SetSofteningBoundaryWidthAngle(width);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t AreaLightComponentController::GetFilteringSampleCount() const
|
||||
{
|
||||
return m_configuration.m_filteringSampleCount;
|
||||
|
||||
+2
-2
@@ -82,12 +82,12 @@ namespace AZ
|
||||
void SetShadowmapMaxSize(ShadowmapSize size) override;
|
||||
ShadowFilterMethod GetShadowFilterMethod() const override;
|
||||
void SetShadowFilterMethod(ShadowFilterMethod method) override;
|
||||
float GetSofteningBoundaryWidthAngle() const override;
|
||||
void SetSofteningBoundaryWidthAngle(float width) override;
|
||||
uint32_t GetFilteringSampleCount() const override;
|
||||
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,
|
||||
|
||||
+5
-4
@@ -37,9 +37,11 @@ namespace AZ
|
||||
->Field("IsCascadeCorrectionEnabled", &DirectionalLightComponentConfig::m_isCascadeCorrectionEnabled)
|
||||
->Field("IsDebugColoringEnabled", &DirectionalLightComponentConfig::m_isDebugColoringEnabled)
|
||||
->Field("ShadowFilterMethod", &DirectionalLightComponentConfig::m_shadowFilterMethod)
|
||||
->Field("SofteningBoundaryWidth", &DirectionalLightComponentConfig::m_boundaryWidth)
|
||||
->Field("PcfFilteringSampleCount", &DirectionalLightComponentConfig::m_filteringSampleCount)
|
||||
->Field("ShadowReceiverPlaneBiasEnabled", &DirectionalLightComponentConfig::m_receiverPlaneBiasEnabled);
|
||||
->Field("ShadowReceiverPlaneBiasEnabled", &DirectionalLightComponentConfig::m_receiverPlaneBiasEnabled)
|
||||
->Field("Shadow Bias", &DirectionalLightComponentConfig::m_shadowBias)
|
||||
->Field("Normal Shadow Bias", &DirectionalLightComponentConfig::m_normalShadowBias)
|
||||
->Field("CascadeBlendingEnabled", &DirectionalLightComponentConfig::m_cascadeBlendingEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,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
|
||||
|
||||
+52
-20
@@ -80,12 +80,16 @@ namespace AZ
|
||||
->Event("SetDebugColoringEnabled", &DirectionalLightRequestBus::Events::SetDebugColoringEnabled)
|
||||
->Event("GetShadowFilterMethod", &DirectionalLightRequestBus::Events::GetShadowFilterMethod)
|
||||
->Event("SetShadowFilterMethod", &DirectionalLightRequestBus::Events::SetShadowFilterMethod)
|
||||
->Event("GetSofteningBoundaryWidth", &DirectionalLightRequestBus::Events::GetSofteningBoundaryWidth)
|
||||
->Event("SetSofteningBoundaryWidth", &DirectionalLightRequestBus::Events::SetSofteningBoundaryWidth)
|
||||
->Event("GetFilteringSampleCount", &DirectionalLightRequestBus::Events::GetFilteringSampleCount)
|
||||
->Event("SetFilteringSampleCount", &DirectionalLightRequestBus::Events::SetFilteringSampleCount)
|
||||
->Event("GetShadowReceiverPlaneBiasEnabled", &DirectionalLightRequestBus::Events::GetShadowReceiverPlaneBiasEnabled)
|
||||
->Event("SetShadowReceiverPlaneBiasEnabled", &DirectionalLightRequestBus::Events::SetShadowReceiverPlaneBiasEnabled)
|
||||
->Event("GetShadowBias", &DirectionalLightRequestBus::Events::GetShadowBias)
|
||||
->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")
|
||||
@@ -99,9 +103,11 @@ namespace AZ
|
||||
->VirtualProperty("ViewFrustumCorrectionEnabled", "GetViewFrustumCorrectionEnabled", "SetViewFrustumCorrectionEnabled")
|
||||
->VirtualProperty("DebugColoringEnabled", "GetDebugColoringEnabled", "SetDebugColoringEnabled")
|
||||
->VirtualProperty("ShadowFilterMethod", "GetShadowFilterMethod", "SetShadowFilterMethod")
|
||||
->VirtualProperty("SofteningBoundaryWidth", "GetSofteningBoundaryWidth", "SetSofteningBoundaryWidth")
|
||||
->VirtualProperty("FilteringSampleCount", "GetFilteringSampleCount", "SetFilteringSampleCount")
|
||||
->VirtualProperty("ShadowReceiverPlaneBiasEnabled", "GetShadowReceiverPlaneBiasEnabled", "SetShadowReceiverPlaneBiasEnabled");
|
||||
->VirtualProperty("ShadowReceiverPlaneBiasEnabled", "GetShadowReceiverPlaneBiasEnabled", "SetShadowReceiverPlaneBiasEnabled")
|
||||
->VirtualProperty("ShadowBias", "GetShadowBias", "SetShadowBias")
|
||||
->VirtualProperty("NormalShadowBias", "GetNormalShadowBias", "SetNormalShadowBias")
|
||||
->VirtualProperty("BlendBetweenCascadesEnabled", "GetCascadeBlendingEnabled", "SetCascadeBlendingEnabled");
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -404,26 +410,39 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
float DirectionalLightComponentController::GetSofteningBoundaryWidth() const
|
||||
{
|
||||
return m_configuration.m_boundaryWidth;
|
||||
}
|
||||
|
||||
void DirectionalLightComponentController::SetSofteningBoundaryWidth(float width)
|
||||
{
|
||||
width = GetMin(Shadow::MaxSofteningBoundaryWidth, GetMax(0.f, width));
|
||||
m_configuration.m_boundaryWidth = width;
|
||||
if (m_featureProcessor)
|
||||
{
|
||||
m_featureProcessor->SetShadowBoundaryWidth(m_lightHandle, width);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t DirectionalLightComponentController::GetFilteringSampleCount() const
|
||||
{
|
||||
return aznumeric_cast<uint32_t>(m_configuration.m_filteringSampleCount);
|
||||
}
|
||||
|
||||
void DirectionalLightComponentController::SetShadowBias(float bias)
|
||||
{
|
||||
m_configuration.m_shadowBias = bias;
|
||||
if (m_featureProcessor)
|
||||
{
|
||||
m_featureProcessor->SetShadowBias(m_lightHandle, bias);
|
||||
}
|
||||
}
|
||||
|
||||
float DirectionalLightComponentController::GetShadowBias() const
|
||||
{
|
||||
return m_configuration.m_shadowBias;
|
||||
}
|
||||
|
||||
void DirectionalLightComponentController::SetNormalShadowBias(float bias)
|
||||
{
|
||||
m_configuration.m_normalShadowBias = bias;
|
||||
if (m_featureProcessor)
|
||||
{
|
||||
m_featureProcessor->SetNormalShadowBias(m_lightHandle, bias);
|
||||
}
|
||||
}
|
||||
|
||||
float DirectionalLightComponentController::GetNormalShadowBias() const
|
||||
{
|
||||
return m_configuration.m_normalShadowBias;
|
||||
}
|
||||
|
||||
void DirectionalLightComponentController::SetFilteringSampleCount(uint32_t count)
|
||||
{
|
||||
const uint16_t count16 = GetMin(Shadow::MaxPcfSamplingCount, aznumeric_cast<uint16_t>(count));
|
||||
@@ -517,9 +536,11 @@ namespace AZ
|
||||
SetViewFrustumCorrectionEnabled(m_configuration.m_isCascadeCorrectionEnabled);
|
||||
SetDebugColoringEnabled(m_configuration.m_isDebugColoringEnabled);
|
||||
SetShadowFilterMethod(m_configuration.m_shadowFilterMethod);
|
||||
SetSofteningBoundaryWidth(m_configuration.m_boundaryWidth);
|
||||
SetShadowBias(m_configuration.m_shadowBias);
|
||||
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.
|
||||
@@ -619,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
|
||||
|
||||
+6
-2
@@ -76,12 +76,16 @@ namespace AZ
|
||||
void SetDebugColoringEnabled(bool enabled) override;
|
||||
ShadowFilterMethod GetShadowFilterMethod() const override;
|
||||
void SetShadowFilterMethod(ShadowFilterMethod method) override;
|
||||
float GetSofteningBoundaryWidth() const override;
|
||||
void SetSofteningBoundaryWidth(float width) override;
|
||||
uint32_t GetFilteringSampleCount() const override;
|
||||
void SetFilteringSampleCount(uint32_t count) override;
|
||||
bool GetShadowReceiverPlaneBiasEnabled() const override;
|
||||
void SetShadowReceiverPlaneBiasEnabled(bool enable) override;
|
||||
float GetShadowBias() const override;
|
||||
void SetShadowBias(float bias) override;
|
||||
float GetNormalShadowBias() const override;
|
||||
void SetNormalShadowBias(float bias) override;
|
||||
bool GetCascadeBlendingEnabled() const override;
|
||||
void SetCascadeBlendingEnabled(bool enable) override;
|
||||
|
||||
private:
|
||||
friend class EditorDirectionalLightComponent;
|
||||
|
||||
+56
-49
@@ -47,53 +47,60 @@ namespace AZ::Render
|
||||
return m_shapeBus->GetRadius() * GetTransform().GetUniformScale();
|
||||
}
|
||||
|
||||
void DiskLightDelegate::DrawDebugDisplay(const Transform& transform, const Color& /*color*/, AzFramework::DebugDisplayRequests& debugDisplay, bool isSelected) const
|
||||
void DiskLightDelegate::DrawDebugDisplay(const Transform& transform, [[maybe_unused]]const Color&, AzFramework::DebugDisplayRequests& debugDisplay, bool isSelected) const
|
||||
{
|
||||
if (isSelected)
|
||||
debugDisplay.PushMatrix(transform);
|
||||
const float radius = GetConfig()->m_attenuationRadius;
|
||||
const float shapeRadius = m_shapeBus->GetRadius();
|
||||
|
||||
auto DrawConicalFrustum = [&debugDisplay](uint32_t numRadiusLines, const Color& color, float brightness, float topRadius, float bottomRadius, float height)
|
||||
{
|
||||
debugDisplay.PushMatrix(transform);
|
||||
float radius = GetConfig()->m_attenuationRadius;
|
||||
const Color displayColor = Color(color.GetAsVector3() * brightness);
|
||||
debugDisplay.SetColor(displayColor);
|
||||
debugDisplay.DrawWireDisk(Vector3(0.0, 0.0, height), Vector3::CreateAxisZ(), bottomRadius);
|
||||
|
||||
if (GetConfig()->m_enableShutters)
|
||||
for (uint32_t i = 0; i < numRadiusLines; ++i)
|
||||
{
|
||||
|
||||
float innerRadians = DegToRad(GetConfig()->m_innerShutterAngleDegrees);
|
||||
float outerRadians = DegToRad(GetConfig()->m_outerShutterAngleDegrees);
|
||||
|
||||
// Draw a cone using the cone angle and attenuation radius
|
||||
innerRadians = GetMin(innerRadians, outerRadians);
|
||||
float coneRadiusInner = sin(innerRadians) * radius;
|
||||
float coneHeightInner = cos(innerRadians) * radius;
|
||||
float coneRadiusOuter = sin(outerRadians) * radius;
|
||||
float coneHeightOuter = cos(outerRadians) * radius;
|
||||
|
||||
auto DrawConicalFrustum = [&debugDisplay](uint32_t numRadiusLines, float topRadius, float bottomRadius, float height, float brightness)
|
||||
{
|
||||
debugDisplay.SetColor(Color(brightness, brightness, brightness, 1.0f));
|
||||
debugDisplay.DrawWireDisk(Vector3(0.0, 0.0, height), Vector3::CreateAxisZ(), bottomRadius);
|
||||
|
||||
for (uint32_t i = 0; i < numRadiusLines; ++i)
|
||||
{
|
||||
float radiusLineAngle = float(i) / numRadiusLines * Constants::TwoPi;
|
||||
debugDisplay.DrawLine(
|
||||
Vector3(cos(radiusLineAngle) * topRadius, sin(radiusLineAngle) * topRadius, 0),
|
||||
Vector3(cos(radiusLineAngle) * bottomRadius, sin(radiusLineAngle) * bottomRadius, height)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
DrawConicalFrustum(16, m_shapeBus->GetRadius(), m_shapeBus->GetRadius() + coneRadiusInner, coneHeightInner, 1.0f);
|
||||
DrawConicalFrustum(16, m_shapeBus->GetRadius(), m_shapeBus->GetRadius() + coneRadiusOuter, coneHeightOuter, 0.65f);
|
||||
|
||||
float radiusLineAngle = float(i) / numRadiusLines * Constants::TwoPi;
|
||||
float cosAngle = cos(radiusLineAngle);
|
||||
float sinAngle = sin(radiusLineAngle);
|
||||
debugDisplay.DrawLine(
|
||||
Vector3(cosAngle * topRadius, sinAngle * topRadius, 0),
|
||||
Vector3(cosAngle * bottomRadius,sinAngle * bottomRadius, height)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
debugDisplay.DrawWireDisk(Vector3::CreateZero(), Vector3::CreateAxisZ(), radius);
|
||||
debugDisplay.DrawArc(Vector3::CreateZero(), radius, 270.0f, 180.0f, 3.0f, 0);
|
||||
debugDisplay.DrawArc(Vector3::CreateZero(), radius, 0.0f, 180.0f, 3.0f, 1);
|
||||
}
|
||||
debugDisplay.PopMatrix();
|
||||
};
|
||||
|
||||
const Color coneColor = isSelected ? Color::CreateOne() : Color(0.0f, 0.75f, 0.75f, 1.0);
|
||||
const uint32_t innerConeLines = 8;
|
||||
float innerRadians, outerRadians;
|
||||
if (GetConfig()->m_enableShutters)
|
||||
{ // With shutters enabled, draw inner and outer debug display frustums
|
||||
innerRadians = DegToRad(GetConfig()->m_innerShutterAngleDegrees);
|
||||
outerRadians = DegToRad(GetConfig()->m_outerShutterAngleDegrees);
|
||||
|
||||
// Draw a cone using the cone angle and attenuation radius
|
||||
innerRadians = GetMin(innerRadians, outerRadians);
|
||||
|
||||
float coneRadiusOuter = sin(outerRadians) * radius;
|
||||
float coneHeightOuter = cos(outerRadians) * radius;
|
||||
|
||||
// Outer cone frustum 'faded' debug cone
|
||||
const uint32_t outerConeLines = 9;
|
||||
DrawConicalFrustum(outerConeLines, coneColor, 0.75f, shapeRadius, shapeRadius + coneRadiusOuter, coneHeightOuter);
|
||||
}
|
||||
else
|
||||
{ // Generic debug display frustum
|
||||
const float coneAngle = 25.0f;
|
||||
innerRadians = DegToRad(coneAngle); // 25 degrees debug display
|
||||
}
|
||||
|
||||
// Inner cone frustum
|
||||
float coneRadiusInner = sin(innerRadians) * radius;
|
||||
float coneHeightInner = cos(innerRadians) * radius;
|
||||
DrawConicalFrustum(innerConeLines, coneColor, 1.0f, shapeRadius, shapeRadius + coneRadiusInner, coneHeightInner);
|
||||
|
||||
debugDisplay.PopMatrix();
|
||||
}
|
||||
|
||||
void DiskLightDelegate::SetEnableShutters(bool enabled)
|
||||
@@ -131,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())
|
||||
@@ -147,14 +162,6 @@ namespace AZ::Render
|
||||
}
|
||||
}
|
||||
|
||||
void DiskLightDelegate::SetSofteningBoundaryWidthAngle(float widthInDegrees)
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
{
|
||||
GetFeatureProcessor()->SetSofteningBoundaryWidthAngle(GetLightHandle(), DegToRad(widthInDegrees));
|
||||
}
|
||||
}
|
||||
|
||||
void DiskLightDelegate::SetFilteringSampleCount(uint32_t count)
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
|
||||
@@ -44,9 +44,9 @@ namespace AZ
|
||||
void SetShadowBias(float bias) override;
|
||||
void SetShadowmapMaxSize(ShadowmapSize size) override;
|
||||
void SetShadowFilterMethod(ShadowFilterMethod method) override;
|
||||
void SetSofteningBoundaryWidthAngle(float widthInDegrees) override;
|
||||
void SetFilteringSampleCount(uint32_t count) override;
|
||||
void SetEsmExponent(float exponent) override;
|
||||
void SetNormalShadowBias(float bias) override;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
+13
-13
@@ -49,7 +49,7 @@ namespace AZ
|
||||
->Attribute(Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/AreaLight.svg")
|
||||
->Attribute(Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game", 0x232b318c))
|
||||
->Attribute(Edit::Attributes::AutoExpand, true)
|
||||
->Attribute(Edit::Attributes::HelpPageURL, "https://o3de.org/docs/user-guide/components/reference/atom/area-light/")
|
||||
->Attribute(Edit::Attributes::HelpPageURL, "https://o3de.org/docs/user-guide/components/reference/atom/light/")
|
||||
;
|
||||
|
||||
editContext->Class<AreaLightComponentController>(
|
||||
@@ -75,7 +75,7 @@ namespace AZ
|
||||
->DataElement(Edit::UIHandlers::Color, &AreaLightComponentConfig::m_color, "Color", "Color of the light")
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::LightTypeIsSelected)
|
||||
->Attribute("ColorEditorConfiguration", RPI::ColorUtils::GetLinearRgbEditorConfig())
|
||||
->Attribute("ColorEditorConfiguration", RPI::ColorUtils::GetRgbEditorConfig())
|
||||
->DataElement(Edit::UIHandlers::ComboBox, &AreaLightComponentConfig::m_intensityMode, "Intensity mode", "Allows specifying which photometric unit to work in.")
|
||||
->Attribute(AZ::Edit::Attributes::EnumValues, &AreaLightComponentConfig::GetValidPhotometricUnits)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::LightTypeIsSelected)
|
||||
@@ -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, 1.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)
|
||||
@@ -154,15 +154,6 @@ namespace AZ
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::AttributesAndValues)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::ShadowsDisabled)
|
||||
->DataElement(Edit::UIHandlers::Slider, &AreaLightComponentConfig::m_boundaryWidthInDegrees, "Softening boundary width",
|
||||
"Width of the boundary between shadowed area and lit one. "
|
||||
"Units are in degrees. "
|
||||
"If this is 0, softening edge is disabled.")
|
||||
->Attribute(Edit::Attributes::Min, 0.f)
|
||||
->Attribute(Edit::Attributes::Max, 1.f)
|
||||
->Attribute(Edit::Attributes::Suffix, " deg")
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::IsEsmDisabled)
|
||||
->DataElement(Edit::UIHandlers::Slider, &AreaLightComponentConfig::m_filteringSampleCount, "Filtering sample count",
|
||||
"This is only used when the pixel is predicted to be on the boundary. Specific to PCF and ESM+PCF.")
|
||||
->Attribute(Edit::Attributes::Min, 4)
|
||||
@@ -180,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)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+26
-15
@@ -44,7 +44,7 @@ namespace AZ
|
||||
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/Component_Placeholder.svg") // [GFX TODO][ATOM-1998] create icons.
|
||||
->Attribute(Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game", 0x232b318c))
|
||||
->Attribute(Edit::Attributes::AutoExpand, true)
|
||||
->Attribute(Edit::Attributes::HelpPageURL, "https://") // [GFX TODO][ATOM-1998] create page
|
||||
->Attribute(Edit::Attributes::HelpPageURL, "https://o3de.org/docs/user-guide/components/reference/atom/directional-light/") // [GFX TODO][ATOM-1998] create page
|
||||
;
|
||||
|
||||
editContext->Class<DirectionalLightComponentController>(
|
||||
@@ -59,7 +59,7 @@ namespace AZ
|
||||
->ClassElement(Edit::ClassElements::EditorData, "")
|
||||
->DataElement(Edit::UIHandlers::Color, &DirectionalLightComponentConfig::m_color, "Color", "Color of the light")
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->Attribute("ColorEditorConfiguration", AZ::RPI::ColorUtils::GetLinearRgbEditorConfig())
|
||||
->Attribute("ColorEditorConfiguration", AZ::RPI::ColorUtils::GetRgbEditorConfig())
|
||||
->DataElement(Edit::UIHandlers::ComboBox, &DirectionalLightComponentConfig::m_intensityMode, "Intensity mode", "Allows specifying light values in lux or Ev100")
|
||||
->EnumAttribute(PhotometricUnit::Lux, "Lux")
|
||||
->EnumAttribute(PhotometricUnit::Ev100Illuminance, "Ev100")
|
||||
@@ -133,17 +133,8 @@ namespace AZ
|
||||
->EnumAttribute(ShadowFilterMethod::Esm, "ESM")
|
||||
->EnumAttribute(ShadowFilterMethod::EsmPcf, "ESM+PCF")
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_boundaryWidth, "Softening boundary width",
|
||||
"Width of the boundary between shadowed area and lit one. "
|
||||
"Units are in meters. "
|
||||
"If this is 0, softening edge is disabled.")
|
||||
->Attribute(Edit::Attributes::Min, 0.f)
|
||||
->Attribute(Edit::Attributes::Max, 0.1f)
|
||||
->Attribute(Edit::Attributes::Suffix, " m")
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsEsmDisabled)
|
||||
->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_filteringSampleCount, "Filtering sample count",
|
||||
"This is used only when the pixel is predicted as on the boundary. "
|
||||
->DataElement(Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_filteringSampleCount, "Filtering sample count\n",
|
||||
"This is used only when the pixel is predicted to be on the boundary.\n"
|
||||
"Specific to PCF and ESM+PCF.")
|
||||
->Attribute(Edit::Attributes::Min, 4)
|
||||
->Attribute(Edit::Attributes::Max, 64)
|
||||
@@ -151,10 +142,30 @@ namespace AZ
|
||||
->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsShadowPcfDisabled)
|
||||
->DataElement(
|
||||
Edit::UIHandlers::CheckBox, &DirectionalLightComponentConfig::m_receiverPlaneBiasEnabled,
|
||||
"Shadow Receiver Plane Bias Enable",
|
||||
"Shadow Receiver Plane Bias Enable\n",
|
||||
"This reduces shadow acne when using large pcf kernels.")
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsShadowPcfDisabled);
|
||||
->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsShadowPcfDisabled)
|
||||
->DataElement(
|
||||
Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::m_shadowBias,
|
||||
"Shadow Bias\n",
|
||||
"Reduces acne by applying a fixed bias along z in shadow-space.\n"
|
||||
"If this is 0, no biasing is applied.")
|
||||
->Attribute(Edit::Attributes::Min, 0.f)
|
||||
->Attribute(Edit::Attributes::Max, 0.2)
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->DataElement(
|
||||
Edit::UIHandlers::Slider, &DirectionalLightComponentConfig::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)
|
||||
->DataElement(
|
||||
Edit::UIHandlers::CheckBox, &DirectionalLightComponentConfig::m_cascadeBlendingEnabled,
|
||||
"Blend between cascades\n", "Enables smooth blending between shadow map cascades.")
|
||||
->Attribute(Edit::Attributes::ReadOnly, &DirectionalLightComponentConfig::IsShadowPcfDisabled)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,10 +56,10 @@ namespace AZ
|
||||
void SetShadowBias([[maybe_unused]] float bias) override {};
|
||||
void SetShadowmapMaxSize([[maybe_unused]] ShadowmapSize size) override {};
|
||||
void SetShadowFilterMethod([[maybe_unused]] ShadowFilterMethod method) override {};
|
||||
void SetSofteningBoundaryWidthAngle([[maybe_unused]] float widthInDegrees) 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);
|
||||
|
||||
|
||||
+2
-2
@@ -75,12 +75,12 @@ namespace AZ
|
||||
virtual void SetShadowmapMaxSize(ShadowmapSize size) = 0;
|
||||
//! Sets the filter method for the shadow
|
||||
virtual void SetShadowFilterMethod(ShadowFilterMethod method) = 0;
|
||||
//! Sets the width of boundary between shadowed area and lit area in degrees.
|
||||
virtual void SetSofteningBoundaryWidthAngle(float widthInDegrees) = 0;
|
||||
//! Sets the sample count for filtering of the shadow boundary, max 64.
|
||||
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
|
||||
|
||||
+9
-8
@@ -92,14 +92,6 @@ namespace AZ::Render
|
||||
}
|
||||
}
|
||||
|
||||
void SphereLightDelegate::SetSofteningBoundaryWidthAngle(float widthInDegrees)
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
{
|
||||
GetFeatureProcessor()->SetSofteningBoundaryWidthAngle(GetLightHandle(), DegToRad(widthInDegrees));
|
||||
}
|
||||
}
|
||||
|
||||
void SphereLightDelegate::SetFilteringSampleCount(uint32_t count)
|
||||
{
|
||||
if (GetShadowsEnabled() && GetLightHandle().IsValid())
|
||||
@@ -115,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
|
||||
|
||||
@@ -34,9 +34,9 @@ namespace AZ
|
||||
void SetShadowBias(float bias) override;
|
||||
void SetShadowmapMaxSize(ShadowmapSize size) override;
|
||||
void SetShadowFilterMethod(ShadowFilterMethod method) override;
|
||||
void SetSofteningBoundaryWidthAngle(float widthInDegrees) override;
|
||||
void SetFilteringSampleCount(uint32_t count) override;
|
||||
void SetEsmExponent(float esmExponent) override;
|
||||
void SetNormalShadowBias(float bias) override;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
+2
-1
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <Decals/DecalComponentController.h>
|
||||
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
@@ -229,7 +230,7 @@ namespace AZ
|
||||
{
|
||||
DecalNotificationBus::Event(m_entityId, &DecalNotifications::OnMaterialChanged, m_configuration.m_materialAsset);
|
||||
|
||||
if (m_featureProcessor && m_configuration.m_materialAsset.GetId().IsValid())
|
||||
if (m_featureProcessor)
|
||||
{
|
||||
m_featureProcessor->SetDecalMaterial(m_handle, m_configuration.m_materialAsset.GetId());
|
||||
}
|
||||
|
||||
@@ -192,7 +192,7 @@ namespace AZ
|
||||
|
||||
u32 EditorDecalComponent::OnConfigurationChanged()
|
||||
{
|
||||
BaseClass::OnConfigurationChanged();
|
||||
m_controller.ConfigurationChanged();
|
||||
return Edit::PropertyRefreshLevels::AttributesAndValues;
|
||||
}
|
||||
|
||||
|
||||
+1
-5
@@ -48,11 +48,7 @@ namespace AZ
|
||||
|
||||
void DiffuseGlobalIlluminationComponentController::Activate(EntityId entityId)
|
||||
{
|
||||
AZ_UNUSED(entityId);
|
||||
|
||||
const RPI::Scene* scene = AZ::RPI::RPISystemInterface::Get()->GetDefaultScene().get();
|
||||
m_featureProcessor = scene->GetFeatureProcessor<DiffuseGlobalIlluminationFeatureProcessorInterface>();
|
||||
|
||||
m_featureProcessor = AZ::RPI::Scene::GetFeatureProcessorForEntity<DiffuseGlobalIlluminationFeatureProcessorInterface>(entityId);
|
||||
OnConfigChanged();
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -19,5 +19,6 @@ namespace AZ
|
||||
static constexpr float DefaultDiffuseProbeGridAmbientMultiplier = 1.0f;
|
||||
static constexpr float DefaultDiffuseProbeGridViewBias = 0.2f;
|
||||
static constexpr float DefaultDiffuseProbeGridNormalBias = 0.1f;
|
||||
static constexpr DiffuseProbeGridNumRaysPerProbe DefaultDiffuseProbeGridNumRaysPerProbe = DiffuseProbeGridNumRaysPerProbe::NumRaysPerProbe_288;
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
+29
-31
@@ -15,7 +15,7 @@
|
||||
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Asset/AssetManagerBus.h>
|
||||
#include <AzCore/Debug/EventTrace.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
#include <AzFramework/Entity/EntityContextBus.h>
|
||||
@@ -34,22 +34,21 @@ namespace AZ
|
||||
if (auto* serializeContext = azrtti_cast<SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<DiffuseProbeGridComponentConfig>()
|
||||
->Version(0)
|
||||
->Version(2) // Added NumRaysPerProbe setting
|
||||
->Field("ProbeSpacing", &DiffuseProbeGridComponentConfig::m_probeSpacing)
|
||||
->Field("Extents", &DiffuseProbeGridComponentConfig::m_extents)
|
||||
->Field("AmbientMultiplier", &DiffuseProbeGridComponentConfig::m_ambientMultiplier)
|
||||
->Field("ViewBias", &DiffuseProbeGridComponentConfig::m_viewBias)
|
||||
->Field("NormalBias", &DiffuseProbeGridComponentConfig::m_normalBias)
|
||||
->Field("NumRaysPerProbe", &DiffuseProbeGridComponentConfig::m_numRaysPerProbe)
|
||||
->Field("EditorMode", &DiffuseProbeGridComponentConfig::m_editorMode)
|
||||
->Field("RuntimeMode", &DiffuseProbeGridComponentConfig::m_runtimeMode)
|
||||
->Field("BakedIrradianceTextureRelativePath", &DiffuseProbeGridComponentConfig::m_bakedIrradianceTextureRelativePath)
|
||||
->Field("BakedDistanceTextureRelativePath", &DiffuseProbeGridComponentConfig::m_bakedDistanceTextureRelativePath)
|
||||
->Field("BakedRelocationTextureRelativePath", &DiffuseProbeGridComponentConfig::m_bakedRelocationTextureRelativePath)
|
||||
->Field("BakedClassificationTextureRelativePath", &DiffuseProbeGridComponentConfig::m_bakedClassificationTextureRelativePath)
|
||||
->Field("BakedProbeDataTextureRelativePath", &DiffuseProbeGridComponentConfig::m_bakedProbeDataTextureRelativePath)
|
||||
->Field("BakedIrradianceTextureAsset", &DiffuseProbeGridComponentConfig::m_bakedIrradianceTextureAsset)
|
||||
->Field("BakedDistanceTextureAsset", &DiffuseProbeGridComponentConfig::m_bakedDistanceTextureAsset)
|
||||
->Field("BakedRelocationTextureAsset", &DiffuseProbeGridComponentConfig::m_bakedRelocationTextureAsset)
|
||||
->Field("BakedClassificationTextureAsset", &DiffuseProbeGridComponentConfig::m_bakedClassificationTextureAsset)
|
||||
->Field("BakedProbeDataTextureAsset", &DiffuseProbeGridComponentConfig::m_bakedProbeDataTextureAsset)
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -121,19 +120,16 @@ namespace AZ
|
||||
if (m_featureProcessor->AreBakedTexturesReferenced(
|
||||
m_configuration.m_bakedIrradianceTextureRelativePath,
|
||||
m_configuration.m_bakedDistanceTextureRelativePath,
|
||||
m_configuration.m_bakedRelocationTextureRelativePath,
|
||||
m_configuration.m_bakedClassificationTextureRelativePath))
|
||||
m_configuration.m_bakedProbeDataTextureRelativePath))
|
||||
{
|
||||
// clear the baked texture paths and assets, since they belong to the original entity (not the clone)
|
||||
m_configuration.m_bakedIrradianceTextureRelativePath.clear();
|
||||
m_configuration.m_bakedDistanceTextureRelativePath.clear();
|
||||
m_configuration.m_bakedRelocationTextureRelativePath.clear();
|
||||
m_configuration.m_bakedClassificationTextureRelativePath.clear();
|
||||
m_configuration.m_bakedProbeDataTextureRelativePath.clear();
|
||||
|
||||
m_configuration.m_bakedIrradianceTextureAsset.Reset();
|
||||
m_configuration.m_bakedDistanceTextureAsset.Reset();
|
||||
m_configuration.m_bakedRelocationTextureAsset.Reset();
|
||||
m_configuration.m_bakedClassificationTextureAsset.Reset();
|
||||
m_configuration.m_bakedProbeDataTextureAsset.Reset();
|
||||
}
|
||||
|
||||
// add this diffuse probe grid to the feature processor
|
||||
@@ -143,29 +139,27 @@ namespace AZ
|
||||
m_featureProcessor->SetAmbientMultiplier(m_handle, m_configuration.m_ambientMultiplier);
|
||||
m_featureProcessor->SetViewBias(m_handle, m_configuration.m_viewBias);
|
||||
m_featureProcessor->SetNormalBias(m_handle, m_configuration.m_normalBias);
|
||||
m_featureProcessor->SetNumRaysPerProbe(m_handle, m_configuration.m_numRaysPerProbe);
|
||||
|
||||
// load the baked texture assets, but only if they are all valid
|
||||
if (m_configuration.m_bakedIrradianceTextureAsset.GetId().IsValid() &&
|
||||
m_configuration.m_bakedDistanceTextureAsset.GetId().IsValid() &&
|
||||
m_configuration.m_bakedRelocationTextureAsset.GetId().IsValid() &&
|
||||
m_configuration.m_bakedClassificationTextureAsset.GetId().IsValid())
|
||||
m_configuration.m_bakedProbeDataTextureAsset.GetId().IsValid())
|
||||
{
|
||||
Data::AssetBus::MultiHandler::BusConnect(m_configuration.m_bakedIrradianceTextureAsset.GetId());
|
||||
Data::AssetBus::MultiHandler::BusConnect(m_configuration.m_bakedDistanceTextureAsset.GetId());
|
||||
Data::AssetBus::MultiHandler::BusConnect(m_configuration.m_bakedRelocationTextureAsset.GetId());
|
||||
Data::AssetBus::MultiHandler::BusConnect(m_configuration.m_bakedClassificationTextureAsset.GetId());
|
||||
Data::AssetBus::MultiHandler::BusConnect(m_configuration.m_bakedProbeDataTextureAsset.GetId());
|
||||
|
||||
m_configuration.m_bakedIrradianceTextureAsset.QueueLoad();
|
||||
m_configuration.m_bakedDistanceTextureAsset.QueueLoad();
|
||||
m_configuration.m_bakedRelocationTextureAsset.QueueLoad();
|
||||
m_configuration.m_bakedClassificationTextureAsset.QueueLoad();
|
||||
m_configuration.m_bakedProbeDataTextureAsset.QueueLoad();
|
||||
}
|
||||
else if (m_configuration.m_runtimeMode == DiffuseProbeGridMode::Baked ||
|
||||
m_configuration.m_runtimeMode == DiffuseProbeGridMode::AutoSelect ||
|
||||
m_configuration.m_editorMode == DiffuseProbeGridMode::Baked ||
|
||||
m_configuration.m_editorMode == DiffuseProbeGridMode::AutoSelect)
|
||||
{
|
||||
AZ_Error("DiffuseProbeGrid", false, "DiffuseProbeGrid mdoe is set to Baked or Auto-Select, but it does not have baked texture assets. Please re-bake this DiffuseProbeGrid.");
|
||||
AZ_Error("DiffuseProbeGrid", false, "DiffuseProbeGrid mode is set to Baked or Auto-Select, but it does not have baked texture assets. Please re-bake this DiffuseProbeGrid.");
|
||||
}
|
||||
|
||||
m_featureProcessor->SetMode(m_handle, m_configuration.m_runtimeMode);
|
||||
@@ -191,13 +185,11 @@ namespace AZ
|
||||
// if all assets are ready we can set the baked texture images
|
||||
if (m_configuration.m_bakedIrradianceTextureAsset.IsReady() &&
|
||||
m_configuration.m_bakedDistanceTextureAsset.IsReady() &&
|
||||
m_configuration.m_bakedRelocationTextureAsset.IsReady() &&
|
||||
m_configuration.m_bakedClassificationTextureAsset.IsReady())
|
||||
m_configuration.m_bakedProbeDataTextureAsset.IsReady())
|
||||
{
|
||||
Data::AssetBus::MultiHandler::BusDisconnect(m_configuration.m_bakedIrradianceTextureAsset.GetId());
|
||||
Data::AssetBus::MultiHandler::BusDisconnect(m_configuration.m_bakedDistanceTextureAsset.GetId());
|
||||
Data::AssetBus::MultiHandler::BusDisconnect(m_configuration.m_bakedRelocationTextureAsset.GetId());
|
||||
Data::AssetBus::MultiHandler::BusDisconnect(m_configuration.m_bakedClassificationTextureAsset.GetId());
|
||||
Data::AssetBus::MultiHandler::BusDisconnect(m_configuration.m_bakedProbeDataTextureAsset.GetId());
|
||||
|
||||
UpdateBakedTextures();
|
||||
}
|
||||
@@ -330,6 +322,17 @@ namespace AZ
|
||||
m_featureProcessor->SetNormalBias(m_handle, m_configuration.m_normalBias);
|
||||
}
|
||||
|
||||
void DiffuseProbeGridComponentController::SetNumRaysPerProbe(const DiffuseProbeGridNumRaysPerProbe& numRaysPerProbe)
|
||||
{
|
||||
if (!m_featureProcessor)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_configuration.m_numRaysPerProbe = numRaysPerProbe;
|
||||
m_featureProcessor->SetNumRaysPerProbe(m_handle, m_configuration.m_numRaysPerProbe);
|
||||
}
|
||||
|
||||
void DiffuseProbeGridComponentController::SetEditorMode(DiffuseProbeGridMode editorMode)
|
||||
{
|
||||
if (!m_featureProcessor)
|
||||
@@ -365,8 +368,7 @@ namespace AZ
|
||||
callback,
|
||||
m_configuration.m_bakedIrradianceTextureRelativePath,
|
||||
m_configuration.m_bakedDistanceTextureRelativePath,
|
||||
m_configuration.m_bakedRelocationTextureRelativePath,
|
||||
m_configuration.m_bakedClassificationTextureRelativePath);
|
||||
m_configuration.m_bakedProbeDataTextureRelativePath);
|
||||
}
|
||||
|
||||
void DiffuseProbeGridComponentController::UpdateBakedTextures()
|
||||
@@ -381,12 +383,8 @@ namespace AZ
|
||||
bakedTextures.m_irradianceImageRelativePath = m_configuration.m_bakedIrradianceTextureRelativePath;
|
||||
bakedTextures.m_distanceImage = RPI::StreamingImage::FindOrCreate(m_configuration.m_bakedDistanceTextureAsset);
|
||||
bakedTextures.m_distanceImageRelativePath = m_configuration.m_bakedDistanceTextureRelativePath;
|
||||
bakedTextures.m_relocationImageDescriptor = m_configuration.m_bakedRelocationTextureAsset->GetImageDescriptor();
|
||||
bakedTextures.m_relocationImageData = m_configuration.m_bakedRelocationTextureAsset->GetSubImageData(0, 0);
|
||||
bakedTextures.m_relocationImageRelativePath = m_configuration.m_bakedRelocationTextureRelativePath;
|
||||
bakedTextures.m_classificationImageDescriptor = m_configuration.m_bakedClassificationTextureAsset->GetImageDescriptor();
|
||||
bakedTextures.m_classificationImageData = m_configuration.m_bakedClassificationTextureAsset->GetSubImageData(0, 0);
|
||||
bakedTextures.m_classificationImageRelativePath = m_configuration.m_bakedClassificationTextureRelativePath;
|
||||
bakedTextures.m_probeDataImage = RPI::StreamingImage::FindOrCreate(m_configuration.m_bakedProbeDataTextureAsset);
|
||||
bakedTextures.m_probeDataImageRelativePath = m_configuration.m_bakedProbeDataTextureRelativePath;
|
||||
|
||||
m_featureProcessor->SetBakedTextures(m_handle, bakedTextures);
|
||||
}
|
||||
|
||||
+4
-4
@@ -35,19 +35,18 @@ namespace AZ
|
||||
float m_ambientMultiplier = DefaultDiffuseProbeGridAmbientMultiplier;
|
||||
float m_viewBias = DefaultDiffuseProbeGridViewBias;
|
||||
float m_normalBias = DefaultDiffuseProbeGridNormalBias;
|
||||
DiffuseProbeGridNumRaysPerProbe m_numRaysPerProbe = DefaultDiffuseProbeGridNumRaysPerProbe;
|
||||
|
||||
DiffuseProbeGridMode m_editorMode = DiffuseProbeGridMode::RealTime;
|
||||
DiffuseProbeGridMode m_runtimeMode = DiffuseProbeGridMode::RealTime;
|
||||
|
||||
AZStd::string m_bakedIrradianceTextureRelativePath;
|
||||
AZStd::string m_bakedDistanceTextureRelativePath;
|
||||
AZStd::string m_bakedRelocationTextureRelativePath;
|
||||
AZStd::string m_bakedClassificationTextureRelativePath;
|
||||
AZStd::string m_bakedProbeDataTextureRelativePath;
|
||||
|
||||
Data::Asset<RPI::StreamingImageAsset> m_bakedIrradianceTextureAsset;
|
||||
Data::Asset<RPI::StreamingImageAsset> m_bakedDistanceTextureAsset;
|
||||
Data::Asset<RPI::StreamingImageAsset> m_bakedRelocationTextureAsset;
|
||||
Data::Asset<RPI::StreamingImageAsset> m_bakedClassificationTextureAsset;
|
||||
Data::Asset<RPI::StreamingImageAsset> m_bakedProbeDataTextureAsset;
|
||||
|
||||
AZ::u64 m_entityId{ EntityId::InvalidEntityId };
|
||||
};
|
||||
@@ -100,6 +99,7 @@ namespace AZ
|
||||
void SetAmbientMultiplier(float ambientMultiplier);
|
||||
void SetViewBias(float viewBias);
|
||||
void SetNormalBias(float normalBias);
|
||||
void SetNumRaysPerProbe(const DiffuseProbeGridNumRaysPerProbe& numRaysPerProbe);
|
||||
void SetEditorMode(DiffuseProbeGridMode editorMode);
|
||||
void SetRuntimeMode(DiffuseProbeGridMode runtimeMode);
|
||||
|
||||
|
||||
+41
-32
@@ -14,6 +14,7 @@
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
#include <Atom/RPI.Reflect/Image/StreamingImagePoolAsset.h>
|
||||
#include <Atom/RPI.Reflect/Model/ModelAsset.h>
|
||||
#include <Atom/Utils/DdsFile.h>
|
||||
|
||||
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT
|
||||
@@ -39,6 +40,7 @@ namespace AZ
|
||||
->Field("ambientMultiplier", &EditorDiffuseProbeGridComponent::m_ambientMultiplier)
|
||||
->Field("viewBias", &EditorDiffuseProbeGridComponent::m_viewBias)
|
||||
->Field("normalBias", &EditorDiffuseProbeGridComponent::m_normalBias)
|
||||
->Field("numRaysPerProbe", &EditorDiffuseProbeGridComponent::m_numRaysPerProbe)
|
||||
->Field("editorMode", &EditorDiffuseProbeGridComponent::m_editorMode)
|
||||
->Field("runtimeMode", &EditorDiffuseProbeGridComponent::m_runtimeMode)
|
||||
;
|
||||
@@ -53,6 +55,7 @@ namespace AZ
|
||||
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/Component_Placeholder.svg")
|
||||
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game", 0x232b318c))
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->Attribute(Edit::Attributes::HelpPageURL, "https://o3de.org/docs/user-guide/components/reference/atom/diffuse-probe-grid/")
|
||||
->Attribute(AZ::Edit::Attributes::PrimaryAssetType, AZ::AzTypeInfo<RPI::ModelAsset>::Uuid())
|
||||
->ClassElement(AZ::Edit::ClassElements::Group, "Probe Spacing")
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
@@ -91,6 +94,9 @@ namespace AZ
|
||||
->Attribute(Edit::Attributes::Step, 0.1f)
|
||||
->Attribute(Edit::Attributes::Min, 0.0f)
|
||||
->Attribute(Edit::Attributes::Max, 1.0f)
|
||||
->DataElement(AZ::Edit::UIHandlers::ComboBox, &EditorDiffuseProbeGridComponent::m_numRaysPerProbe, "Number of Rays Per Probe", "Number of rays cast by each probe to detect lighting in its surroundings")
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorDiffuseProbeGridComponent::OnNumRaysPerProbeChanged)
|
||||
->Attribute(AZ::Edit::Attributes::EnumValues, &EditorDiffuseProbeGridComponent::GetNumRaysPerProbeEnumList)
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "Grid mode")
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->DataElement(Edit::UIHandlers::ComboBox, &EditorDiffuseProbeGridComponent::m_editorMode, "Editor Mode", "Controls whether the editor uses RealTime or Baked diffuse GI. RealTime requires a ray-tracing capable GPU. Auto-Select will fallback to Baked if ray-tracing is not available")
|
||||
@@ -180,8 +186,7 @@ namespace AZ
|
||||
|
||||
CheckTextureAssetNotification(configuration.m_bakedIrradianceTextureRelativePath, configuration.m_bakedIrradianceTextureAsset);
|
||||
CheckTextureAssetNotification(configuration.m_bakedDistanceTextureRelativePath, configuration.m_bakedDistanceTextureAsset);
|
||||
CheckTextureAssetNotification(configuration.m_bakedRelocationTextureRelativePath, configuration.m_bakedRelocationTextureAsset);
|
||||
CheckTextureAssetNotification(configuration.m_bakedClassificationTextureRelativePath, configuration.m_bakedClassificationTextureAsset);
|
||||
CheckTextureAssetNotification(configuration.m_bakedProbeDataTextureRelativePath, configuration.m_bakedProbeDataTextureAsset);
|
||||
}
|
||||
|
||||
void EditorDiffuseProbeGridComponent::CheckTextureAssetNotification(const AZStd::string& relativePath, Data::Asset<RPI::StreamingImageAsset>& configurationAsset)
|
||||
@@ -194,13 +199,12 @@ namespace AZ
|
||||
{
|
||||
// bake is complete, update configuration with the new baked texture asset
|
||||
AzToolsFramework::ScopedUndoBatch undoBatch("DiffuseProbeGrid Texture Bake");
|
||||
configurationAsset = { textureAsset.GetAs<RPI::StreamingImageAsset>(), AZ::Data::AssetLoadBehavior::PreLoad };
|
||||
configurationAsset = textureAsset;
|
||||
SetDirty();
|
||||
|
||||
if (m_controller.m_configuration.m_bakedIrradianceTextureAsset.IsReady() &&
|
||||
m_controller.m_configuration.m_bakedDistanceTextureAsset.IsReady() &&
|
||||
m_controller.m_configuration.m_bakedClassificationTextureAsset.IsReady() &&
|
||||
m_controller.m_configuration.m_bakedRelocationTextureAsset.IsReady())
|
||||
m_controller.m_configuration.m_bakedProbeDataTextureAsset.IsReady())
|
||||
{
|
||||
m_controller.UpdateBakedTextures();
|
||||
}
|
||||
@@ -216,6 +220,19 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
AZStd::vector<Edit::EnumConstant<DiffuseProbeGridNumRaysPerProbe>> EditorDiffuseProbeGridComponent::GetNumRaysPerProbeEnumList() const
|
||||
{
|
||||
AZStd::vector<Edit::EnumConstant<DiffuseProbeGridNumRaysPerProbe>> enumList;
|
||||
|
||||
for (uint32_t index = 0; index < DiffuseProbeGridNumRaysPerProbeArraySize; ++index)
|
||||
{
|
||||
const DiffuseProbeGridNumRaysPerProbeEntry& entry = DiffuseProbeGridNumRaysPerProbeArray[index];
|
||||
enumList.push_back(Edit::EnumConstant<DiffuseProbeGridNumRaysPerProbe>(entry.m_enum, AZStd::to_string(entry.m_rayCount).c_str()));
|
||||
}
|
||||
|
||||
return enumList;
|
||||
}
|
||||
|
||||
AZ::Aabb EditorDiffuseProbeGridComponent::GetEditorSelectionBoundsViewport([[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo)
|
||||
{
|
||||
return m_controller.GetAabb();
|
||||
@@ -313,6 +330,12 @@ namespace AZ
|
||||
return AZ::Edit::PropertyRefreshLevels::None;
|
||||
}
|
||||
|
||||
AZ::u32 EditorDiffuseProbeGridComponent::OnNumRaysPerProbeChanged()
|
||||
{
|
||||
m_controller.SetNumRaysPerProbe(m_numRaysPerProbe);
|
||||
return AZ::Edit::PropertyRefreshLevels::None;
|
||||
}
|
||||
|
||||
AZ::u32 EditorDiffuseProbeGridComponent::OnEditorModeChanged()
|
||||
{
|
||||
// this will update the configuration and also change the DiffuseProbeGrid mode
|
||||
@@ -335,8 +358,7 @@ namespace AZ
|
||||
{
|
||||
if (!m_controller.m_configuration.m_bakedIrradianceTextureAsset.GetId().IsValid() ||
|
||||
!m_controller.m_configuration.m_bakedDistanceTextureAsset.GetId().IsValid() ||
|
||||
!m_controller.m_configuration.m_bakedRelocationTextureAsset.GetId().IsValid() ||
|
||||
!m_controller.m_configuration.m_bakedClassificationTextureAsset.GetId().IsValid())
|
||||
!m_controller.m_configuration.m_bakedProbeDataTextureAsset.GetId().IsValid())
|
||||
{
|
||||
return AZ::Failure(AZStd::string("Please bake textures before changing the Diffuse Probe Grid to Baked or Auto-Select mode."));
|
||||
}
|
||||
@@ -383,21 +405,18 @@ namespace AZ
|
||||
// Note: we need to make sure to use the same source image for each bake
|
||||
AZStd::string irradianceTextureRelativePath = ValidateOrCreateNewTexturePath(configuration.m_bakedIrradianceTextureRelativePath, DiffuseProbeGridIrradianceFileName);
|
||||
AZStd::string distanceTextureRelativePath = ValidateOrCreateNewTexturePath(configuration.m_bakedDistanceTextureRelativePath, DiffuseProbeGridDistanceFileName);
|
||||
AZStd::string relocationTextureRelativePath = ValidateOrCreateNewTexturePath(configuration.m_bakedRelocationTextureRelativePath, DiffuseProbeGridRelocationFileName);
|
||||
AZStd::string classificationTextureRelativePath = ValidateOrCreateNewTexturePath(configuration.m_bakedClassificationTextureRelativePath, DiffuseProbeGridClassificationFileName);
|
||||
AZStd::string probeDataTextureRelativePath = ValidateOrCreateNewTexturePath(configuration.m_bakedProbeDataTextureRelativePath, DiffuseProbeGridProbeDataFileName);
|
||||
|
||||
// create the full paths
|
||||
char projectPath[AZ_MAX_PATH_LEN];
|
||||
AZ::IO::FileIOBase::GetInstance()->ResolvePath("@devassets@", projectPath, AZ_MAX_PATH_LEN);
|
||||
AZ::IO::FileIOBase::GetInstance()->ResolvePath("@projectroot@", projectPath, AZ_MAX_PATH_LEN);
|
||||
|
||||
AZStd::string irradianceTextureFullPath;
|
||||
AzFramework::StringFunc::Path::Join(projectPath, irradianceTextureRelativePath.c_str(), irradianceTextureFullPath, true, true);
|
||||
AZStd::string distanceTextureFullPath;
|
||||
AzFramework::StringFunc::Path::Join(projectPath, distanceTextureRelativePath.c_str(), distanceTextureFullPath, true, true);
|
||||
AZStd::string relocationTextureFullPath;
|
||||
AzFramework::StringFunc::Path::Join(projectPath, relocationTextureRelativePath.c_str(), relocationTextureFullPath, true, true);
|
||||
AZStd::string classificationTextureFullPath;
|
||||
AzFramework::StringFunc::Path::Join(projectPath, classificationTextureRelativePath.c_str(), classificationTextureFullPath, true, true);
|
||||
AZStd::string probeDataTextureFullPath;
|
||||
AzFramework::StringFunc::Path::Join(projectPath, probeDataTextureRelativePath.c_str(), probeDataTextureFullPath, true, true);
|
||||
|
||||
// make sure the folder is created
|
||||
AZStd::string diffuseProbeGridFolder;
|
||||
@@ -407,23 +426,20 @@ namespace AZ
|
||||
// check out the files in source control
|
||||
CheckoutSourceTextureFile(irradianceTextureFullPath);
|
||||
CheckoutSourceTextureFile(distanceTextureFullPath);
|
||||
CheckoutSourceTextureFile(relocationTextureFullPath);
|
||||
CheckoutSourceTextureFile(classificationTextureFullPath);
|
||||
CheckoutSourceTextureFile(probeDataTextureFullPath);
|
||||
|
||||
// update the configuration
|
||||
AzToolsFramework::ScopedUndoBatch undoBatch("DiffuseProbeGrid bake");
|
||||
configuration.m_bakedIrradianceTextureRelativePath = irradianceTextureRelativePath;
|
||||
configuration.m_bakedDistanceTextureRelativePath = distanceTextureRelativePath;
|
||||
configuration.m_bakedRelocationTextureRelativePath = relocationTextureRelativePath;
|
||||
configuration.m_bakedClassificationTextureRelativePath = classificationTextureRelativePath;
|
||||
configuration.m_bakedProbeDataTextureRelativePath = probeDataTextureRelativePath;
|
||||
SetDirty();
|
||||
|
||||
// callback for the texture readback
|
||||
DiffuseProbeGridBakeTexturesCallback bakeTexturesCallback = [=](
|
||||
DiffuseProbeGridTexture irradianceTexture,
|
||||
DiffuseProbeGridTexture distanceTexture,
|
||||
DiffuseProbeGridTexture relocationTexture,
|
||||
DiffuseProbeGridTexture classificationTexture)
|
||||
DiffuseProbeGridTexture probeDataTexture)
|
||||
{
|
||||
// irradiance
|
||||
{
|
||||
@@ -439,18 +455,11 @@ namespace AZ
|
||||
AZ_Assert(outcome.IsSuccess(), "Failed to write Distance texture .dds file [%s]", distanceTextureFullPath.c_str());
|
||||
}
|
||||
|
||||
// relocation
|
||||
// probe data
|
||||
{
|
||||
AZ::DdsFile::DdsFileData fileData = { relocationTexture.m_size, relocationTexture.m_format, relocationTexture.m_data.get() };
|
||||
[[maybe_unused]] const auto outcome = AZ::DdsFile::WriteFile(relocationTextureFullPath, fileData);
|
||||
AZ_Assert(outcome.IsSuccess(), "Failed to write Relocation texture .dds file [%s]", relocationTextureFullPath.c_str());
|
||||
}
|
||||
|
||||
// classification
|
||||
{
|
||||
AZ::DdsFile::DdsFileData fileData = { classificationTexture.m_size, classificationTexture.m_format, classificationTexture.m_data.get() };
|
||||
[[maybe_unused]] const auto outcome = AZ::DdsFile::WriteFile(classificationTextureFullPath, fileData);
|
||||
AZ_Assert(outcome.IsSuccess(), "Failed to write Classification texture .dds file [%s]", classificationTextureFullPath.c_str());
|
||||
AZ::DdsFile::DdsFileData fileData = { probeDataTexture.m_size, probeDataTexture.m_format, probeDataTexture.m_data.get() };
|
||||
[[maybe_unused]] const auto outcome = AZ::DdsFile::WriteFile(probeDataTextureFullPath, fileData);
|
||||
AZ_Assert(outcome.IsSuccess(), "Failed to write ProbeData texture .dds file [%s]", probeDataTextureFullPath.c_str());
|
||||
}
|
||||
|
||||
m_bakeInProgress = false;
|
||||
@@ -480,7 +489,7 @@ namespace AZ
|
||||
AZStd::string fullPath;
|
||||
|
||||
char projectPath[AZ_MAX_PATH_LEN];
|
||||
AZ::IO::FileIOBase::GetInstance()->ResolvePath("@devassets@", projectPath, AZ_MAX_PATH_LEN);
|
||||
AZ::IO::FileIOBase::GetInstance()->ResolvePath("@projectroot@", projectPath, AZ_MAX_PATH_LEN);
|
||||
|
||||
if (!relativePath.empty())
|
||||
{
|
||||
|
||||
+3
@@ -56,6 +56,7 @@ namespace AZ
|
||||
AZStd::string ValidateOrCreateNewTexturePath(const AZStd::string& relativePath, const char* fileSuffix);
|
||||
void CheckoutSourceTextureFile(const AZStd::string& fullPath);
|
||||
void CheckTextureAssetNotification(const AZStd::string& relativePath, Data::Asset<RPI::StreamingImageAsset>& configurationAsset);
|
||||
AZStd::vector<Edit::EnumConstant<DiffuseProbeGridNumRaysPerProbe>> GetNumRaysPerProbeEnumList() const;
|
||||
|
||||
// property change notifications
|
||||
AZ::Outcome<void, AZStd::string> OnProbeSpacingValidateX(void* newValue, const AZ::Uuid& valueType);
|
||||
@@ -65,6 +66,7 @@ namespace AZ
|
||||
AZ::u32 OnAmbientMultiplierChanged();
|
||||
AZ::u32 OnViewBiasChanged();
|
||||
AZ::u32 OnNormalBiasChanged();
|
||||
AZ::u32 OnNumRaysPerProbeChanged();
|
||||
AZ::u32 OnEditorModeChanged();
|
||||
AZ::u32 OnRuntimeModeChanged();
|
||||
AZ::Outcome<void, AZStd::string> OnModeChangeValidate(void* newValue, const AZ::Uuid& valueType);
|
||||
@@ -80,6 +82,7 @@ namespace AZ
|
||||
float m_ambientMultiplier = DefaultDiffuseProbeGridAmbientMultiplier;
|
||||
float m_viewBias = DefaultDiffuseProbeGridViewBias;
|
||||
float m_normalBias = DefaultDiffuseProbeGridNormalBias;
|
||||
DiffuseProbeGridNumRaysPerProbe m_numRaysPerProbe = DefaultDiffuseProbeGridNumRaysPerProbe;
|
||||
DiffuseProbeGridMode m_editorMode = DiffuseProbeGridMode::RealTime;
|
||||
DiffuseProbeGridMode m_runtimeMode = DiffuseProbeGridMode::RealTime;
|
||||
|
||||
|
||||
+53
-11
@@ -6,15 +6,18 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <EditorCommonFeaturesSystemComponent.h>
|
||||
#include <SkinnedMesh/SkinnedMeshDebugDisplay.h>
|
||||
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Component/ComponentApplicationLifecycle.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/EditContextConstants.inl>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <AzFramework/API/ApplicationAPI.h>
|
||||
#include <AzToolsFramework/API/EditorCameraBus.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailContext.h>
|
||||
#include <EditorCommonFeaturesSystemComponent.h>
|
||||
#include <SharedPreview/SharedThumbnail.h>
|
||||
#include <SkinnedMesh/SkinnedMeshDebugDisplay.h>
|
||||
|
||||
#include <IEditor.h>
|
||||
|
||||
@@ -68,7 +71,7 @@ namespace AZ
|
||||
|
||||
void EditorCommonFeaturesSystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
|
||||
{
|
||||
AZ_UNUSED(required);
|
||||
required.push_back(AZ_CRC_CE("ThumbnailerService"));
|
||||
}
|
||||
|
||||
void EditorCommonFeaturesSystemComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
|
||||
@@ -82,24 +85,31 @@ namespace AZ
|
||||
|
||||
void EditorCommonFeaturesSystemComponent::Activate()
|
||||
{
|
||||
m_renderer = AZStd::make_unique<AZ::LyIntegration::Thumbnails::CommonThumbnailRenderer>();
|
||||
m_previewerFactory = AZStd::make_unique <LyIntegration::CommonPreviewerFactory>();
|
||||
m_skinnedMeshDebugDisplay = AZStd::make_unique<SkinnedMeshDebugDisplay>();
|
||||
|
||||
AzToolsFramework::EditorLevelNotificationBus::Handler::BusConnect();
|
||||
AzToolsFramework::AssetBrowser::PreviewerRequestBus::Handler::BusConnect();
|
||||
if (auto settingsRegistry{ AZ::SettingsRegistry::Get() }; settingsRegistry != nullptr)
|
||||
{
|
||||
auto LifecycleCallback = [this](AZStd::string_view, AZ::SettingsRegistryInterface::Type)
|
||||
{
|
||||
SetupThumbnails();
|
||||
};
|
||||
AZ::ComponentApplicationLifecycle::RegisterHandler(*settingsRegistry, m_criticalAssetsHandler,
|
||||
AZStd::move(LifecycleCallback), "CriticalAssetsCompiled");
|
||||
}
|
||||
AzFramework::ApplicationLifecycleEvents::Bus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
void EditorCommonFeaturesSystemComponent::Deactivate()
|
||||
{
|
||||
AzToolsFramework::EditorLevelNotificationBus::Handler::BusDisconnect();
|
||||
AzFramework::ApplicationLifecycleEvents::Bus::Handler::BusDisconnect();
|
||||
m_criticalAssetsHandler = {};
|
||||
AzToolsFramework::EditorLevelNotificationBus::Handler::BusDisconnect();
|
||||
AzToolsFramework::AssetBrowser::PreviewerRequestBus::Handler::BusDisconnect();
|
||||
|
||||
m_skinnedMeshDebugDisplay.reset();
|
||||
m_previewerFactory.reset();
|
||||
m_renderer.reset();
|
||||
TeardownThumbnails();
|
||||
}
|
||||
|
||||
void EditorCommonFeaturesSystemComponent::OnNewLevelCreated()
|
||||
@@ -199,7 +209,39 @@ namespace AZ
|
||||
|
||||
void EditorCommonFeaturesSystemComponent::OnApplicationAboutToStop()
|
||||
{
|
||||
m_renderer.reset();
|
||||
TeardownThumbnails();
|
||||
}
|
||||
|
||||
void EditorCommonFeaturesSystemComponent::SetupThumbnails()
|
||||
{
|
||||
using namespace AzToolsFramework::Thumbnailer;
|
||||
using namespace LyIntegration;
|
||||
|
||||
ThumbnailerRequestsBus::Broadcast(
|
||||
&ThumbnailerRequests::RegisterThumbnailProvider, MAKE_TCACHE(SharedThumbnailCache), ThumbnailContext::DefaultContext);
|
||||
|
||||
if (!m_thumbnailRenderer)
|
||||
{
|
||||
m_thumbnailRenderer = AZStd::make_unique<AZ::LyIntegration::SharedThumbnailRenderer>();
|
||||
}
|
||||
|
||||
if (!m_previewerFactory)
|
||||
{
|
||||
m_previewerFactory = AZStd::make_unique<LyIntegration::SharedPreviewerFactory>();
|
||||
}
|
||||
}
|
||||
|
||||
void EditorCommonFeaturesSystemComponent::TeardownThumbnails()
|
||||
{
|
||||
using namespace AzToolsFramework::Thumbnailer;
|
||||
using namespace LyIntegration;
|
||||
|
||||
ThumbnailerRequestsBus::Broadcast(
|
||||
&ThumbnailerRequests::UnregisterThumbnailProvider, SharedThumbnailCache::ProviderName,
|
||||
ThumbnailContext::DefaultContext);
|
||||
|
||||
m_thumbnailRenderer.reset();
|
||||
m_previewerFactory.reset();
|
||||
}
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
+13
-7
@@ -11,10 +11,10 @@
|
||||
#include <AzCore/Component/Component.h>
|
||||
#include <AzFramework/Application/Application.h>
|
||||
#include <AzToolsFramework/API/EditorLevelNotificationBus.h>
|
||||
#include <AzToolsFramework/Entity/SliceEditorEntityOwnershipServiceBus.h>
|
||||
#include <AzToolsFramework/AssetBrowser/Previewer/PreviewerBus.h>
|
||||
#include <Thumbnails/Rendering/CommonThumbnailRenderer.h>
|
||||
#include <Source/Thumbnails/Preview/CommonPreviewerFactory.h>
|
||||
#include <AzToolsFramework/Entity/SliceEditorEntityOwnershipServiceBus.h>
|
||||
#include <SharedPreview/SharedPreviewerFactory.h>
|
||||
#include <SharedPreview/SharedThumbnailRenderer.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -53,15 +53,20 @@ namespace AZ
|
||||
void OnNewLevelCreated() override;
|
||||
|
||||
// SliceEditorEntityOwnershipServiceBus overrides ...
|
||||
void OnSliceInstantiated(const AZ::Data::AssetId&, AZ::SliceComponent::SliceInstanceAddress&, const AzFramework::SliceInstantiationTicket&) override;
|
||||
void OnSliceInstantiated(
|
||||
const AZ::Data::AssetId&, AZ::SliceComponent::SliceInstanceAddress&, const AzFramework::SliceInstantiationTicket&) override;
|
||||
void OnSliceInstantiationFailed(const AZ::Data::AssetId&, const AzFramework::SliceInstantiationTicket&) override;
|
||||
|
||||
// AzToolsFramework::AssetBrowser::PreviewerRequestBus::Handler overrides...
|
||||
const AzToolsFramework::AssetBrowser::PreviewerFactory* GetPreviewerFactory(const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry) const override;
|
||||
const AzToolsFramework::AssetBrowser::PreviewerFactory* GetPreviewerFactory(
|
||||
const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry) const override;
|
||||
|
||||
// AzFramework::ApplicationLifecycleEvents overrides...
|
||||
void OnApplicationAboutToStop() override;
|
||||
|
||||
void SetupThumbnails();
|
||||
void TeardownThumbnails();
|
||||
|
||||
private:
|
||||
AZStd::unique_ptr<SkinnedMeshDebugDisplay> m_skinnedMeshDebugDisplay;
|
||||
|
||||
@@ -69,8 +74,9 @@ namespace AZ
|
||||
AZStd::string m_atomLevelDefaultAssetPath{ "LevelAssets/default.slice" };
|
||||
float m_envProbeHeight{ 200.0f };
|
||||
|
||||
AZStd::unique_ptr<AZ::LyIntegration::Thumbnails::CommonThumbnailRenderer> m_renderer;
|
||||
AZStd::unique_ptr<LyIntegration::CommonPreviewerFactory> m_previewerFactory;
|
||||
AZStd::unique_ptr<AZ::LyIntegration::SharedThumbnailRenderer> m_thumbnailRenderer;
|
||||
AZStd::unique_ptr<LyIntegration::SharedPreviewerFactory> m_previewerFactory;
|
||||
AZ::SettingsRegistryInterface::NotifyEventHandler m_criticalAssetsHandler;
|
||||
};
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace AZ
|
||||
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/Component_Placeholder.svg")
|
||||
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game", 0x232b318c))
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->Attribute(AZ::Edit::Attributes::HelpPageURL, "https://o3de.org/docs/user-guide/components/reference/atom/")
|
||||
->Attribute(AZ::Edit::Attributes::HelpPageURL, "https://o3de.org/docs/user-guide/components/reference/atom/grid/")
|
||||
;
|
||||
|
||||
editContext->Class<GridComponentController>(
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace AZ
|
||||
m_entityId = entityId;
|
||||
m_dirty = true;
|
||||
|
||||
RPI::ScenePtr scene = RPI::RPISystemInterface::Get()->GetDefaultScene();
|
||||
RPI::Scene* scene = RPI::Scene::GetSceneForEntityId(m_entityId);
|
||||
if (scene)
|
||||
{
|
||||
AZ::RPI::SceneNotificationBus::Handler::BusConnect(scene->GetId());
|
||||
@@ -175,6 +175,10 @@ namespace AZ
|
||||
void GridComponentController::OnBeginPrepareRender()
|
||||
{
|
||||
auto* auxGeomFP = AZ::RPI::Scene::GetFeatureProcessorForEntity<AZ::RPI::AuxGeomFeatureProcessorInterface>(m_entityId);
|
||||
if (!auxGeomFP)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (auto auxGeom = auxGeomFP->GetDrawQueue())
|
||||
{
|
||||
BuildGrid();
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ namespace AZ
|
||||
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/Component_Placeholder.svg")
|
||||
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game", 0x232b318c))
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->Attribute(AZ::Edit::Attributes::HelpPageURL, "https://o3de.org/docs/user-guide/components/reference/atom/")
|
||||
->Attribute(AZ::Edit::Attributes::HelpPageURL, "https://o3de.org/docs/user-guide/components/reference/atom/global-skylight-ibl/")
|
||||
;
|
||||
|
||||
editContext->Class<ImageBasedLightComponentController>(
|
||||
|
||||
+1
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <AtomLyIntegration/CommonFeatures/ImageBasedLights/ImageBasedLightComponentConfig.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
namespace AZ
|
||||
|
||||
-2
@@ -163,8 +163,6 @@ namespace AZ
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// If this asset didn't load or isn't a cubemap, release it.
|
||||
configAsset.Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+44
-11
@@ -6,23 +6,24 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Material/EditorMaterialComponent.h>
|
||||
#include <Material/EditorMaterialComponentExporter.h>
|
||||
|
||||
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <Atom/RPI.Edit/Common/AssetUtils.h>
|
||||
#include <Atom/RPI.Edit/Material/MaterialPropertyId.h>
|
||||
#include <Atom/RPI.Public/Image/StreamingImage.h>
|
||||
#include <Atom/RPI.Reflect/Material/MaterialAsset.h>
|
||||
#include <Atom/RPI.Reflect/Material/MaterialTypeAsset.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/Mesh/MeshComponentBus.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/Json/RegistrationContext.h>
|
||||
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <Material/EditorMaterialComponent.h>
|
||||
#include <Material/EditorMaterialComponentExporter.h>
|
||||
#include <Material/EditorMaterialComponentSerializer.h>
|
||||
|
||||
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT
|
||||
#include <QMenu>
|
||||
#include <QAction>
|
||||
#include <QCursor>
|
||||
#include <QMenu>
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
namespace AZ
|
||||
@@ -59,7 +60,12 @@ namespace AZ
|
||||
BaseClass::Reflect(context);
|
||||
EditorMaterialComponentSlot::Reflect(context);
|
||||
|
||||
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
if (auto jsonContext = azrtti_cast<JsonRegistrationContext*>(context))
|
||||
{
|
||||
jsonContext->Serializer<JsonEditorMaterialComponentSerializer>()->HandlesType<EditorMaterialComponent>();
|
||||
}
|
||||
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->RegisterGenericType<EditorMaterialComponentSlotContainer>();
|
||||
serializeContext->RegisterGenericType<EditorMaterialComponentSlotsByLodContainer>();
|
||||
@@ -76,7 +82,7 @@ namespace AZ
|
||||
serializeContext->RegisterGenericType<AZStd::unordered_map<MaterialAssignmentId, Data::AssetId, AZStd::hash<MaterialAssignmentId>, AZStd::equal_to<MaterialAssignmentId>, AZStd::allocator>>();
|
||||
serializeContext->RegisterGenericType<AZStd::unordered_map<MaterialAssignmentId, MaterialPropertyOverrideMap, AZStd::hash<MaterialAssignmentId>, AZStd::equal_to<MaterialAssignmentId>, AZStd::allocator>>();
|
||||
|
||||
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
|
||||
if (auto editContext = serializeContext->GetEditContext())
|
||||
{
|
||||
editContext->Class<EditorMaterialComponent>(
|
||||
"Material", "The material component specifies the material to use for this entity")
|
||||
@@ -86,7 +92,7 @@ namespace AZ
|
||||
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/Component_Placeholder.svg")
|
||||
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game", 0x232b318c))
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->Attribute(AZ::Edit::Attributes::HelpPageURL, "https://o3de.org/docs/user-guide/components/reference/atom/")
|
||||
->Attribute(AZ::Edit::Attributes::HelpPageURL, "https://o3de.org/docs/user-guide/components/reference/atom/material/")
|
||||
->Attribute(AZ::Edit::Attributes::PrimaryAssetType, AZ::AzTypeInfo<RPI::MaterialAsset>::Uuid())
|
||||
->DataElement(AZ::Edit::UIHandlers::MultiLineEdit, &EditorMaterialComponent::m_message, "Message", "")
|
||||
->Attribute(AZ_CRC("PlaceholderText", 0xa23ec278), "Component cannot be edited with multiple entities selected")
|
||||
@@ -129,7 +135,7 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->ConstantProperty("EditorMaterialComponentTypeId", BehaviorConstant(Uuid(EditorMaterialComponentTypeId)))
|
||||
->Attribute(AZ::Script::Attributes::Module, "render")
|
||||
@@ -148,11 +154,13 @@ namespace AZ
|
||||
BaseClass::Activate();
|
||||
MaterialReceiverNotificationBus::Handler::BusConnect(GetEntityId());
|
||||
MaterialComponentNotificationBus::Handler::BusConnect(GetEntityId());
|
||||
EditorMaterialSystemComponentNotificationBus::Handler::BusConnect();
|
||||
UpdateMaterialSlots();
|
||||
}
|
||||
|
||||
void EditorMaterialComponent::Deactivate()
|
||||
{
|
||||
EditorMaterialSystemComponentNotificationBus::Handler::BusDisconnect();
|
||||
MaterialReceiverNotificationBus::Handler::BusDisconnect();
|
||||
MaterialComponentNotificationBus::Handler::BusDisconnect();
|
||||
BaseClass::Deactivate();
|
||||
@@ -238,6 +246,19 @@ namespace AZ
|
||||
UpdateMaterialSlots();
|
||||
});
|
||||
action->setToolTip("Repair materials that reference missing assets by assigning the default asset.");
|
||||
|
||||
action = menu->addAction("Apply Automatic Property Updates", [this]() {
|
||||
AzToolsFramework::ScopedUndoBatch undoBatch("Applying automatic property updates.");
|
||||
SetDirty();
|
||||
|
||||
uint32_t propertiesUpdated = 0;
|
||||
MaterialComponentRequestBus::EventResult(propertiesUpdated, GetEntityId(), &MaterialComponentRequestBus::Events::ApplyAutomaticPropertyUpdates);
|
||||
|
||||
AZ_Printf("EditorMaterialComponent", "Updated %u property(s).", propertiesUpdated);
|
||||
|
||||
UpdateMaterialSlots();
|
||||
});
|
||||
action->setToolTip("Repair material property overrides that reference missing properties by auto-renaming them where possible.");
|
||||
}
|
||||
|
||||
void EditorMaterialComponent::SetPrimaryAsset(const AZ::Data::AssetId& assetId)
|
||||
@@ -260,6 +281,18 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
void EditorMaterialComponent::OnRenderMaterialPreviewComplete(
|
||||
[[maybe_unused]] const AZ::EntityId& entityId,
|
||||
[[maybe_unused]] const AZ::Render::MaterialAssignmentId& materialAssignmentId,
|
||||
[[maybe_unused]] const QPixmap& pixmap)
|
||||
{
|
||||
if (entityId == GetEntityId())
|
||||
{
|
||||
AzToolsFramework::ToolsApplicationEvents::Bus::Broadcast(
|
||||
&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_AttributesAndValues);
|
||||
}
|
||||
}
|
||||
|
||||
AZ::u32 EditorMaterialComponent::OnConfigurationChanged()
|
||||
{
|
||||
return AZ::Edit::PropertyRefreshLevels::AttributesAndValues;
|
||||
|
||||
+10
-2
@@ -9,6 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <Atom/Feature/Utils/EditorRenderComponentAdapter.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/Material/EditorMaterialSystemComponentNotificationBus.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/Material/MaterialComponentBus.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/Material/MaterialComponentConstants.h>
|
||||
#include <Material/EditorMaterialComponentSlot.h>
|
||||
@@ -21,10 +22,13 @@ namespace AZ
|
||||
//! In-editor material component for displaying and editing material assignments.
|
||||
class EditorMaterialComponent final
|
||||
: public EditorRenderComponentAdapter<MaterialComponentController, MaterialComponent, MaterialComponentConfig>
|
||||
, private MaterialReceiverNotificationBus::Handler
|
||||
, private MaterialComponentNotificationBus::Handler
|
||||
, public MaterialReceiverNotificationBus::Handler
|
||||
, public MaterialComponentNotificationBus::Handler
|
||||
, public EditorMaterialSystemComponentNotificationBus::Handler
|
||||
{
|
||||
public:
|
||||
friend class JsonEditorMaterialComponentSerializer;
|
||||
|
||||
using BaseClass = EditorRenderComponentAdapter<MaterialComponentController, MaterialComponent, MaterialComponentConfig>;
|
||||
AZ_EDITOR_COMPONENT(EditorMaterialComponent, EditorMaterialComponentTypeId, BaseClass);
|
||||
|
||||
@@ -52,6 +56,10 @@ namespace AZ
|
||||
//! MaterialComponentNotificationBus::Handler overrides...
|
||||
void OnMaterialInstanceCreated(const MaterialAssignment& materialAssignment) override;
|
||||
|
||||
//! EditorMaterialSystemComponentNotificationBus::Handler overrides...
|
||||
void OnRenderMaterialPreviewComplete(
|
||||
const AZ::EntityId& entityId, const AZ::Render::MaterialAssignmentId& materialAssignmentId, const QPixmap& pixmap) override;
|
||||
|
||||
// Regenerates the editor component material slots based on the material and
|
||||
// LOD mapping from the model or other consumer of materials.
|
||||
// If any corresponding material assignments are found in the component
|
||||
|
||||
+163
-102
@@ -23,10 +23,6 @@
|
||||
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
|
||||
#include <AzToolsFramework/API/EditorWindowRequestBus.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/AssetBrowser/Thumbnails/ProductThumbnail.h>
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailContext.h>
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailWidget.h>
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailerBus.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/Material/EditorMaterialSystemComponentRequestBus.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/Material/MaterialComponentBus.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/Material/MaterialComponentConfig.h>
|
||||
@@ -49,29 +45,18 @@ namespace AZ
|
||||
MaterialPropertyInspector::MaterialPropertyInspector(QWidget* parent)
|
||||
: AtomToolsFramework::InspectorWidget(parent)
|
||||
{
|
||||
// Create the menu button
|
||||
QToolButton* menuButton = new QToolButton(this);
|
||||
menuButton->setAutoRaise(true);
|
||||
menuButton->setIcon(QIcon(":/Cards/img/UI20/Cards/menu_ico.svg"));
|
||||
menuButton->setVisible(true);
|
||||
QObject::connect(menuButton, &QToolButton::clicked, this, [this]() { OpenMenu(); });
|
||||
AddHeading(menuButton);
|
||||
|
||||
m_messageLabel = new QLabel(this);
|
||||
m_messageLabel->setWordWrap(true);
|
||||
m_messageLabel->setVisible(true);
|
||||
m_messageLabel->setAlignment(Qt::AlignCenter);
|
||||
m_messageLabel->setText(tr("Material not available"));
|
||||
AddHeading(m_messageLabel);
|
||||
|
||||
CreateHeading();
|
||||
AZ::TickBus::Handler::BusConnect();
|
||||
AZ::EntitySystemBus::Handler::BusConnect();
|
||||
EditorMaterialSystemComponentNotificationBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
MaterialPropertyInspector::~MaterialPropertyInspector()
|
||||
{
|
||||
AtomToolsFramework::InspectorRequestBus::Handler::BusDisconnect();
|
||||
AZ::EntitySystemBus::Handler::BusDisconnect();
|
||||
AZ::TickBus::Handler::BusDisconnect();
|
||||
AZ::EntitySystemBus::Handler::BusDisconnect();
|
||||
EditorMaterialSystemComponentNotificationBus::Handler::BusDisconnect();
|
||||
MaterialComponentNotificationBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
@@ -88,6 +73,12 @@ namespace AZ
|
||||
AZ::Data::AssetId materialAssetId = {};
|
||||
MaterialComponentRequestBus::EventResult(
|
||||
materialAssetId, m_entityId, &MaterialComponentRequestBus::Events::GetMaterialOverride, m_materialAssignmentId);
|
||||
if (!materialAssetId.IsValid())
|
||||
{
|
||||
MaterialComponentRequestBus::EventResult(
|
||||
materialAssetId, m_entityId, &MaterialComponentRequestBus::Events::GetDefaultMaterialAssetId,
|
||||
m_materialAssignmentId);
|
||||
}
|
||||
|
||||
if (!materialAssetId.IsValid())
|
||||
{
|
||||
@@ -134,7 +125,7 @@ namespace AZ
|
||||
}
|
||||
|
||||
Populate();
|
||||
m_messageLabel->setVisible(false);
|
||||
LoadOverridesFromEntity();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -146,8 +137,9 @@ namespace AZ
|
||||
m_dirtyPropertyFlags.set();
|
||||
m_editorFunctors = {};
|
||||
m_internalEditNotification = {};
|
||||
m_messageLabel->setVisible(true);
|
||||
m_messageLabel->setText(tr("Material not available"));
|
||||
m_updateUI = {};
|
||||
m_updatePreview = {};
|
||||
UpdateHeading();
|
||||
}
|
||||
|
||||
bool MaterialPropertyInspector::IsLoaded() const
|
||||
@@ -162,49 +154,63 @@ namespace AZ
|
||||
m_dirtyPropertyFlags.set();
|
||||
m_internalEditNotification = {};
|
||||
|
||||
AZ::TickBus::Handler::BusDisconnect();
|
||||
AtomToolsFramework::InspectorRequestBus::Handler::BusDisconnect();
|
||||
AtomToolsFramework::InspectorWidget::Reset();
|
||||
}
|
||||
|
||||
void MaterialPropertyInspector::AddDetailsGroup()
|
||||
void MaterialPropertyInspector::CreateHeading()
|
||||
{
|
||||
const AZStd::string& groupName = "Details";
|
||||
const AZStd::string& groupDisplayName = "Details";
|
||||
const AZStd::string& groupDescription = "";
|
||||
// Create the menu button
|
||||
QToolButton* menuButton = new QToolButton(this);
|
||||
menuButton->setAutoRaise(true);
|
||||
menuButton->setIcon(QIcon(":/Cards/img/UI20/Cards/menu_ico.svg"));
|
||||
menuButton->setVisible(true);
|
||||
QObject::connect(menuButton, &QToolButton::clicked, this, [this]() { OpenMenu(); });
|
||||
AddHeading(menuButton);
|
||||
|
||||
auto propertyGroupContainer = new QWidget(this);
|
||||
propertyGroupContainer->setLayout(new QHBoxLayout());
|
||||
m_overviewImage = new QLabel(this);
|
||||
m_overviewImage->setFixedSize(QSize(120, 120));
|
||||
m_overviewImage->setScaledContents(true);
|
||||
m_overviewImage->setVisible(false);
|
||||
|
||||
AzToolsFramework::Thumbnailer::SharedThumbnailKey thumbnailKey =
|
||||
MAKE_TKEY(AzToolsFramework::AssetBrowser::ProductThumbnailKey, m_editData.m_materialAssetId);
|
||||
auto thumbnailWidget = new AzToolsFramework::Thumbnailer::ThumbnailWidget(this);
|
||||
thumbnailWidget->setFixedSize(QSize(120, 120));
|
||||
thumbnailWidget->setVisible(true);
|
||||
thumbnailWidget->SetThumbnailKey(thumbnailKey, AzToolsFramework::Thumbnailer::ThumbnailContext::DefaultContext);
|
||||
propertyGroupContainer->layout()->addWidget(thumbnailWidget);
|
||||
|
||||
auto materialInfoWidget = new QLabel(this);
|
||||
m_overviewText = new QLabel(this);
|
||||
QSizePolicy sizePolicy1(QSizePolicy::Ignored, QSizePolicy::Preferred);
|
||||
sizePolicy1.setHorizontalStretch(0);
|
||||
sizePolicy1.setVerticalStretch(0);
|
||||
sizePolicy1.setHeightForWidth(materialInfoWidget->sizePolicy().hasHeightForWidth());
|
||||
materialInfoWidget->setSizePolicy(sizePolicy1);
|
||||
materialInfoWidget->setMinimumSize(QSize(0, 0));
|
||||
materialInfoWidget->setMaximumSize(QSize(16777215, 16777215));
|
||||
materialInfoWidget->setTextFormat(Qt::AutoText);
|
||||
materialInfoWidget->setScaledContents(false);
|
||||
materialInfoWidget->setAlignment(Qt::AlignLeading | Qt::AlignLeft | Qt::AlignTop);
|
||||
materialInfoWidget->setWordWrap(true);
|
||||
sizePolicy1.setHeightForWidth(m_overviewText->sizePolicy().hasHeightForWidth());
|
||||
m_overviewText->setSizePolicy(sizePolicy1);
|
||||
m_overviewText->setMinimumSize(QSize(0, 0));
|
||||
m_overviewText->setMaximumSize(QSize(16777215, 16777215));
|
||||
m_overviewText->setTextFormat(Qt::AutoText);
|
||||
m_overviewText->setScaledContents(false);
|
||||
m_overviewText->setWordWrap(true);
|
||||
m_overviewText->setVisible(true);
|
||||
|
||||
auto overviewContainer = new QWidget(this);
|
||||
overviewContainer->setLayout(new QHBoxLayout());
|
||||
overviewContainer->layout()->addWidget(m_overviewImage);
|
||||
overviewContainer->layout()->addWidget(m_overviewText);
|
||||
AddHeading(overviewContainer);
|
||||
}
|
||||
|
||||
void MaterialPropertyInspector::UpdateHeading()
|
||||
{
|
||||
if (!IsLoaded())
|
||||
{
|
||||
m_overviewText->setText(tr("Material not available"));
|
||||
m_overviewText->setAlignment(Qt::AlignCenter);
|
||||
m_overviewImage->setVisible(false);
|
||||
return;
|
||||
}
|
||||
|
||||
QFileInfo materialFileInfo(AZ::RPI::AssetUtils::GetProductPathByAssetId(m_editData.m_materialAsset.GetId()).c_str());
|
||||
QFileInfo materialSourceFileInfo(m_editData.m_materialSourcePath.c_str());
|
||||
QFileInfo materialTypeSourceFileInfo(m_editData.m_materialTypeSourcePath.c_str());
|
||||
QFileInfo materialParentSourceFileInfo(AZ::RPI::AssetUtils::GetSourcePathByAssetId(m_editData.m_materialParentAsset.GetId()).c_str());
|
||||
QFileInfo materialParentSourceFileInfo(
|
||||
AZ::RPI::AssetUtils::GetSourcePathByAssetId(m_editData.m_materialParentAsset.GetId()).c_str());
|
||||
|
||||
AZStd::string entityName;
|
||||
AZ::ComponentApplicationBus::BroadcastResult(
|
||||
entityName, &AZ::ComponentApplicationBus::Events::GetEntityName, m_entityId);
|
||||
AZ::ComponentApplicationBus::BroadcastResult(entityName, &AZ::ComponentApplicationBus::Events::GetEntityName, m_entityId);
|
||||
|
||||
AZStd::string slotName;
|
||||
MaterialComponentRequestBus::EventResult(
|
||||
@@ -220,7 +226,8 @@ namespace AZ
|
||||
}
|
||||
if (!materialTypeSourceFileInfo.fileName().isEmpty())
|
||||
{
|
||||
materialInfo += tr("<tr><td><b>Material Type </b></td><td>%1</td></tr>").arg(materialTypeSourceFileInfo.fileName());
|
||||
materialInfo +=
|
||||
tr("<tr><td><b>Material Type </b></td><td>%1</td></tr>").arg(materialTypeSourceFileInfo.fileName());
|
||||
}
|
||||
if (!materialSourceFileInfo.fileName().isEmpty())
|
||||
{
|
||||
@@ -228,14 +235,21 @@ namespace AZ
|
||||
}
|
||||
if (!materialParentSourceFileInfo.fileName().isEmpty())
|
||||
{
|
||||
materialInfo += tr("<tr><td><b>Material Parent </b></td><td>%1</td></tr>").arg(materialParentSourceFileInfo.fileName());
|
||||
materialInfo +=
|
||||
tr("<tr><td><b>Material Parent </b></td><td>%1</td></tr>").arg(materialParentSourceFileInfo.fileName());
|
||||
}
|
||||
materialInfo += tr("</table>");
|
||||
materialInfoWidget->setText(materialInfo);
|
||||
|
||||
propertyGroupContainer->layout()->addWidget(materialInfoWidget);
|
||||
m_overviewText->setText(materialInfo);
|
||||
m_overviewText->setAlignment(Qt::AlignLeading | Qt::AlignLeft | Qt::AlignTop);
|
||||
|
||||
AddGroup(groupName, groupDisplayName, groupDescription, propertyGroupContainer);
|
||||
QPixmap pixmap;
|
||||
EditorMaterialSystemComponentRequestBus::BroadcastResult(
|
||||
pixmap, &EditorMaterialSystemComponentRequestBus::Events::GetRenderedMaterialPreview, m_entityId,
|
||||
m_materialAssignmentId);
|
||||
m_overviewImage->setPixmap(pixmap);
|
||||
m_overviewImage->setVisible(true);
|
||||
m_updatePreview |= pixmap.isNull();
|
||||
}
|
||||
|
||||
void MaterialPropertyInspector::AddUvNamesGroup()
|
||||
@@ -271,17 +285,13 @@ namespace AZ
|
||||
|
||||
// Passing in same group as main and comparison instance to enable custom value comparison for highlighting modified properties
|
||||
auto propertyGroupWidget = new AtomToolsFramework::InspectorPropertyGroupWidget(
|
||||
&group, nullptr, group.TYPEINFO_Uuid(), this, this, GetSaveStateKeyForGroup(groupName));
|
||||
&group, &group, group.TYPEINFO_Uuid(), this, this, GetGroupSaveStateKey(groupName), {},
|
||||
[this](const auto node) { return GetInstanceNodePropertyIndicator(node); }, 0);
|
||||
AddGroup(groupName, groupDisplayName, groupDescription, propertyGroupWidget);
|
||||
}
|
||||
|
||||
void MaterialPropertyInspector::Populate()
|
||||
void MaterialPropertyInspector::AddPropertiesGroup()
|
||||
{
|
||||
AddGroupsBegin();
|
||||
|
||||
AddDetailsGroup();
|
||||
AddUvNamesGroup();
|
||||
|
||||
// Copy all of the properties from the material asset to the source data that will be exported
|
||||
// TODO: Support populating the Material Editor with nested property sets, not just the top level.
|
||||
for (const AZStd::unique_ptr<AZ::RPI::MaterialTypeSourceData::PropertySet>& propertySet : m_editData.m_materialTypeSourceData.GetPropertyLayout().m_propertySets)
|
||||
@@ -301,24 +311,38 @@ namespace AZ
|
||||
|
||||
AtomToolsFramework::ConvertToPropertyConfig(propertyConfig, *propertyDefinition.get());
|
||||
|
||||
const auto& propertyIndex =
|
||||
m_editData.m_materialAsset->GetMaterialPropertiesLayout()->FindPropertyIndex(propertyConfig.m_id);
|
||||
|
||||
propertyConfig.m_groupName = groupDisplayName;
|
||||
const auto& propertyIndex = m_editData.m_materialAsset->GetMaterialPropertiesLayout()->FindPropertyIndex(propertyConfig.m_id);
|
||||
propertyConfig.m_showThumbnail = true;
|
||||
propertyConfig.m_defaultValue = AtomToolsFramework::ConvertToEditableType(m_editData.m_materialTypeAsset->GetDefaultPropertyValues()[propertyIndex.GetIndex()]);
|
||||
propertyConfig.m_parentValue = AtomToolsFramework::ConvertToEditableType(m_editData.m_materialTypeAsset->GetDefaultPropertyValues()[propertyIndex.GetIndex()]);
|
||||
propertyConfig.m_originalValue = AtomToolsFramework::ConvertToEditableType(m_editData.m_materialAsset->GetPropertyValues()[propertyIndex.GetIndex()]);
|
||||
propertyConfig.m_defaultValue = AtomToolsFramework::ConvertToEditableType(
|
||||
m_editData.m_materialTypeAsset->GetDefaultPropertyValues()[propertyIndex.GetIndex()]);
|
||||
|
||||
// There is no explicit parent material here. Material instance property overrides replace the values from the
|
||||
// assigned material asset. Its values should be treated as parent, for comparison, in this case.
|
||||
propertyConfig.m_parentValue = AtomToolsFramework::ConvertToEditableType(
|
||||
m_editData.m_materialTypeAsset->GetDefaultPropertyValues()[propertyIndex.GetIndex()]);
|
||||
|
||||
propertyConfig.m_originalValue = AtomToolsFramework::ConvertToEditableType(
|
||||
m_editData.m_materialAsset->GetPropertyValues()[propertyIndex.GetIndex()]);
|
||||
group.m_properties.emplace_back(propertyConfig);
|
||||
}
|
||||
|
||||
// Passing in same group as main and comparison instance to enable custom value comparison for highlighting modified properties
|
||||
auto propertyGroupWidget = new AtomToolsFramework::InspectorPropertyGroupWidget(
|
||||
&group, nullptr, group.TYPEINFO_Uuid(), this, this, GetSaveStateKeyForGroup(groupName));
|
||||
&group, &group, group.TYPEINFO_Uuid(), this, this, GetGroupSaveStateKey(groupName), {},
|
||||
[this](const auto node) { return GetInstanceNodePropertyIndicator(node); }, 0);
|
||||
AddGroup(groupName, groupDisplayName, groupDescription, propertyGroupWidget);
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialPropertyInspector::Populate()
|
||||
{
|
||||
AddGroupsBegin();
|
||||
AddUvNamesGroup();
|
||||
AddPropertiesGroup();
|
||||
AddGroupsEnd();
|
||||
|
||||
LoadOverridesFromEntity();
|
||||
}
|
||||
|
||||
void MaterialPropertyInspector::LoadOverridesFromEntity()
|
||||
@@ -333,6 +357,25 @@ namespace AZ
|
||||
m_editData.m_materialPropertyOverrideMap, m_entityId, &MaterialComponentRequestBus::Events::GetPropertyOverrides,
|
||||
m_materialAssignmentId);
|
||||
|
||||
// Apply any automatic property renames so that the material inspector will be properly initialized with the right values
|
||||
// for properties that have new names.
|
||||
{
|
||||
AZStd::vector<AZStd::pair<Name, Name>> renamedProperties;
|
||||
for (auto& propertyOverridePair : m_editData.m_materialPropertyOverrideMap)
|
||||
{
|
||||
Name name = propertyOverridePair.first;
|
||||
if (m_materialInstance->GetAsset()->GetMaterialTypeAsset()->ApplyPropertyRenames(name))
|
||||
{
|
||||
renamedProperties.emplace_back(propertyOverridePair.first, name);
|
||||
}
|
||||
}
|
||||
for (const auto& [oldName, newName] : renamedProperties)
|
||||
{
|
||||
m_editData.m_materialPropertyOverrideMap[newName] = m_editData.m_materialPropertyOverrideMap[oldName];
|
||||
m_editData.m_materialPropertyOverrideMap.erase(oldName);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& group : m_groups)
|
||||
{
|
||||
for (auto& property : group.second.m_properties)
|
||||
@@ -363,6 +406,7 @@ namespace AZ
|
||||
m_dirtyPropertyFlags.set();
|
||||
RunEditorMaterialFunctors();
|
||||
RebuildAll();
|
||||
UpdateHeading();
|
||||
}
|
||||
|
||||
void MaterialPropertyInspector::SaveOverridesToEntity(bool commitChanges)
|
||||
@@ -386,6 +430,9 @@ namespace AZ
|
||||
MaterialComponentNotificationBus::Event(m_entityId, &MaterialComponentNotifications::OnMaterialsEdited);
|
||||
m_internalEditNotification = false;
|
||||
}
|
||||
|
||||
// m_updatePreview should be set to true here for continuous preview updates as slider/color properties change but needs
|
||||
// throttling
|
||||
}
|
||||
|
||||
void MaterialPropertyInspector::RunEditorMaterialFunctors()
|
||||
@@ -492,25 +539,32 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
AZ::Crc32 MaterialPropertyInspector::GetSaveStateKeyForGroup(const AZStd::string& groupName) const
|
||||
AZ::Crc32 MaterialPropertyInspector::GetGroupSaveStateKey(const AZStd::string& groupName) const
|
||||
{
|
||||
return AZ::Crc32(AZStd::string::format(
|
||||
"MaterialPropertyInspector::PropertyGroup::%s::%s", m_editData.m_materialAssetId.ToString<AZStd::string>().c_str(),
|
||||
groupName.c_str()));
|
||||
}
|
||||
|
||||
bool MaterialPropertyInspector::AreNodePropertyValuesEqual(
|
||||
const AzToolsFramework::InstanceDataNode* source, const AzToolsFramework::InstanceDataNode* target)
|
||||
bool MaterialPropertyInspector::IsInstanceNodePropertyModifed(const AzToolsFramework::InstanceDataNode* node) const
|
||||
{
|
||||
AZ_UNUSED(source);
|
||||
const AtomToolsFramework::DynamicProperty* property = AtomToolsFramework::FindDynamicPropertyForInstanceDataNode(target);
|
||||
return property && AtomToolsFramework::ArePropertyValuesEqual(property->GetValue(), property->GetConfig().m_parentValue);
|
||||
const AtomToolsFramework::DynamicProperty* property = AtomToolsFramework::FindDynamicPropertyForInstanceDataNode(node);
|
||||
return property && !AtomToolsFramework::ArePropertyValuesEqual(property->GetValue(), property->GetConfig().m_parentValue);
|
||||
}
|
||||
|
||||
const char* MaterialPropertyInspector::GetInstanceNodePropertyIndicator(const AzToolsFramework::InstanceDataNode* node) const
|
||||
{
|
||||
if (IsInstanceNodePropertyModifed(node))
|
||||
{
|
||||
return ":/Icons/changed_property.svg";
|
||||
}
|
||||
return ":/Icons/blank.png";
|
||||
}
|
||||
|
||||
bool MaterialPropertyInspector::SaveMaterial() const
|
||||
{
|
||||
const QString defaultPath = AtomToolsFramework::GetUniqueFileInfo(
|
||||
QString(AZ::IO::FileIOBase::GetInstance()->GetAlias("@devassets@")) +
|
||||
QString(AZ::IO::FileIOBase::GetInstance()->GetAlias("@projectroot@")) +
|
||||
AZ_CORRECT_FILESYSTEM_SEPARATOR + "Materials" +
|
||||
AZ_CORRECT_FILESYSTEM_SEPARATOR + "untitled." +
|
||||
AZ::RPI::MaterialSourceData::Extension).absoluteFilePath();
|
||||
@@ -588,7 +642,8 @@ namespace AZ
|
||||
MaterialComponentRequestBus::Event(
|
||||
m_entityId, &MaterialComponentRequestBus::Events::SetPropertyOverrides, m_materialAssignmentId,
|
||||
MaterialPropertyOverrideMap());
|
||||
QueueUpdateUI();
|
||||
m_updateUI = true;
|
||||
m_updatePreview = true;
|
||||
});
|
||||
action->setEnabled(IsLoaded());
|
||||
|
||||
@@ -683,10 +738,7 @@ namespace AZ
|
||||
|
||||
void MaterialPropertyInspector::OnEntityActivated(const AZ::EntityId& entityId)
|
||||
{
|
||||
if (m_entityId == entityId)
|
||||
{
|
||||
QueueUpdateUI();
|
||||
}
|
||||
m_updateUI |= (m_entityId == entityId);
|
||||
}
|
||||
|
||||
void MaterialPropertyInspector::OnEntityDeactivated(const AZ::EntityId& entityId)
|
||||
@@ -700,35 +752,54 @@ namespace AZ
|
||||
void MaterialPropertyInspector::OnEntityNameChanged(const AZ::EntityId& entityId, const AZStd::string& name)
|
||||
{
|
||||
AZ_UNUSED(name);
|
||||
if (m_entityId == entityId)
|
||||
{
|
||||
QueueUpdateUI();
|
||||
}
|
||||
m_updateUI |= (m_entityId == entityId);
|
||||
}
|
||||
|
||||
void MaterialPropertyInspector::OnTick(float deltaTime, ScriptTimePoint time)
|
||||
{
|
||||
AZ_UNUSED(time);
|
||||
AZ_UNUSED(deltaTime);
|
||||
UpdateUI();
|
||||
AZ::TickBus::Handler::BusDisconnect();
|
||||
if (m_updateUI)
|
||||
{
|
||||
m_updateUI = false;
|
||||
UpdateUI();
|
||||
}
|
||||
|
||||
if (m_updatePreview)
|
||||
{
|
||||
m_updatePreview = false;
|
||||
EditorMaterialSystemComponentRequestBus::Broadcast(
|
||||
&EditorMaterialSystemComponentRequestBus::Events::RenderMaterialPreview, m_entityId, m_materialAssignmentId);
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialPropertyInspector::OnMaterialsEdited()
|
||||
{
|
||||
if (!m_internalEditNotification)
|
||||
m_updateUI |= !m_internalEditNotification;
|
||||
m_updatePreview = true;
|
||||
}
|
||||
|
||||
void MaterialPropertyInspector::OnRenderMaterialPreviewComplete(
|
||||
const AZ::EntityId& entityId, const AZ::Render::MaterialAssignmentId& materialAssignmentId, const QPixmap& pixmap)
|
||||
{
|
||||
if (m_overviewImage && m_entityId == entityId && m_materialAssignmentId == materialAssignmentId)
|
||||
{
|
||||
QueueUpdateUI();
|
||||
m_overviewImage->setPixmap(pixmap);
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialPropertyInspector::UpdateUI()
|
||||
{
|
||||
AZ::Data::AssetId assetId;
|
||||
AZ::Data::AssetId materialAssetId = {};
|
||||
MaterialComponentRequestBus::EventResult(
|
||||
assetId, m_entityId, &MaterialComponentRequestBus::Events::GetMaterialOverride, m_materialAssignmentId);
|
||||
materialAssetId, m_entityId, &MaterialComponentRequestBus::Events::GetMaterialOverride, m_materialAssignmentId);
|
||||
if (!materialAssetId.IsValid())
|
||||
{
|
||||
MaterialComponentRequestBus::EventResult(
|
||||
materialAssetId, m_entityId, &MaterialComponentRequestBus::Events::GetDefaultMaterialAssetId, m_materialAssignmentId);
|
||||
}
|
||||
|
||||
if (IsLoaded() && m_editData.m_materialAssetId == assetId)
|
||||
if (IsLoaded() && m_editData.m_materialAssetId == materialAssetId)
|
||||
{
|
||||
LoadOverridesFromEntity();
|
||||
}
|
||||
@@ -737,16 +808,6 @@ namespace AZ
|
||||
LoadMaterial(m_entityId, m_materialAssignmentId);
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialPropertyInspector::QueueUpdateUI()
|
||||
{
|
||||
if (!AZ::TickBus::Handler::BusIsConnected())
|
||||
{
|
||||
AZ::TickBus::Handler::BusConnect();
|
||||
}
|
||||
}
|
||||
} // namespace EditorMaterialComponentInspector
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
//#include <AtomLyIntegration/CommonFeatures/moc_EditorMaterialComponentInspector.cpp>
|
||||
|
||||
+20
-9
@@ -9,6 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <AtomLyIntegration/CommonFeatures/Material/EditorMaterialSystemComponentNotificationBus.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/Material/MaterialComponentBus.h>
|
||||
#include <AtomToolsFramework/DynamicProperty/DynamicPropertyGroup.h>
|
||||
#include <AtomToolsFramework/Inspector/InspectorWidget.h>
|
||||
@@ -31,14 +32,13 @@ namespace AZ
|
||||
{
|
||||
namespace EditorMaterialComponentInspector
|
||||
{
|
||||
using PropertyChangedCallback = AZStd::function<void(const MaterialPropertyOverrideMap&)>;
|
||||
|
||||
class MaterialPropertyInspector
|
||||
: public AtomToolsFramework::InspectorWidget
|
||||
, public AzToolsFramework::IPropertyEditorNotify
|
||||
, public AZ::EntitySystemBus::Handler
|
||||
, public AZ::TickBus::Handler
|
||||
, public MaterialComponentNotificationBus::Handler
|
||||
, public EditorMaterialSystemComponentNotificationBus::Handler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
@@ -89,20 +89,28 @@ namespace AZ
|
||||
//! MaterialComponentNotificationBus::Handler overrides...
|
||||
void OnMaterialsEdited() override;
|
||||
|
||||
void UpdateUI();
|
||||
void QueueUpdateUI();
|
||||
//! EditorMaterialSystemComponentNotificationBus::Handler overrides...
|
||||
void OnRenderMaterialPreviewComplete(
|
||||
const AZ::EntityId& entityId,
|
||||
const AZ::Render::MaterialAssignmentId& materialAssignmentId,
|
||||
const QPixmap& pixmap) override;
|
||||
|
||||
void UpdateUI();
|
||||
|
||||
void CreateHeading();
|
||||
void UpdateHeading();
|
||||
|
||||
void AddDetailsGroup();
|
||||
void AddUvNamesGroup();
|
||||
void AddPropertiesGroup();
|
||||
|
||||
void LoadOverridesFromEntity();
|
||||
void SaveOverridesToEntity(bool commitChanges);
|
||||
void RunEditorMaterialFunctors();
|
||||
void UpdateMaterialInstanceProperty(const AtomToolsFramework::DynamicProperty& property);
|
||||
|
||||
AZ::Crc32 GetSaveStateKeyForGroup(const AZStd::string& groupName) const;
|
||||
static bool AreNodePropertyValuesEqual(
|
||||
const AzToolsFramework::InstanceDataNode* source, const AzToolsFramework::InstanceDataNode* target);
|
||||
AZ::Crc32 GetGroupSaveStateKey(const AZStd::string& groupName) const;
|
||||
bool IsInstanceNodePropertyModifed(const AzToolsFramework::InstanceDataNode* node) const;
|
||||
const char* GetInstanceNodePropertyIndicator(const AzToolsFramework::InstanceDataNode* node) const;
|
||||
|
||||
// Tracking the property that is actively being edited in the inspector
|
||||
const AtomToolsFramework::DynamicProperty* m_activeProperty = {};
|
||||
@@ -115,7 +123,10 @@ namespace AZ
|
||||
AZ::RPI::MaterialPropertyFlags m_dirtyPropertyFlags = {};
|
||||
AZStd::unordered_map<AZStd::string, AtomToolsFramework::DynamicPropertyGroup> m_groups = {};
|
||||
bool m_internalEditNotification = {};
|
||||
QLabel* m_messageLabel = {};
|
||||
bool m_updateUI = {};
|
||||
bool m_updatePreview = {};
|
||||
QLabel* m_overviewText = {};
|
||||
QLabel* m_overviewImage = {};
|
||||
};
|
||||
} // namespace EditorMaterialComponentInspector
|
||||
} // namespace Render
|
||||
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* 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 <AzCore/Serialization/Json/JsonSerializationResult.h>
|
||||
#include <Material/EditorMaterialComponent.h>
|
||||
#include <Material/EditorMaterialComponentSerializer.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
AZ_CLASS_ALLOCATOR_IMPL(JsonEditorMaterialComponentSerializer, AZ::SystemAllocator, 0);
|
||||
|
||||
AZ::JsonSerializationResult::Result JsonEditorMaterialComponentSerializer::Load(
|
||||
void* outputValue,
|
||||
[[maybe_unused]] const AZ::Uuid& outputValueTypeId,
|
||||
const rapidjson::Value& inputValue,
|
||||
AZ::JsonDeserializerContext& context)
|
||||
{
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
|
||||
AZ_Assert(
|
||||
azrtti_typeid<EditorMaterialComponent>() == outputValueTypeId,
|
||||
"Unable to deserialize EditorMaterialComponent from json because the provided type is %s.",
|
||||
outputValueTypeId.ToString<AZStd::string>().c_str());
|
||||
|
||||
auto componentInstance = reinterpret_cast<EditorMaterialComponent*>(outputValue);
|
||||
AZ_Assert(componentInstance, "Output value for JsonEditorMaterialComponentSerializer can't be null.");
|
||||
|
||||
JSR::ResultCode result(JSR::Tasks::ReadField);
|
||||
|
||||
result.Combine(ContinueLoadingFromJsonObjectField(
|
||||
&componentInstance->m_id, azrtti_typeid<decltype(componentInstance->m_id)>(), inputValue, "Id", context));
|
||||
|
||||
result.Combine(ContinueLoadingFromJsonObjectField(
|
||||
&componentInstance->m_controller, azrtti_typeid<decltype(componentInstance->m_controller)>(), inputValue, "Controller",
|
||||
context));
|
||||
|
||||
result.Combine(ContinueLoadingFromJsonObjectField(
|
||||
&componentInstance->m_materialSlotsByLodEnabled, azrtti_typeid<decltype(componentInstance->m_materialSlotsByLodEnabled)>(),
|
||||
inputValue, "materialSlotsByLodEnabled", context));
|
||||
|
||||
return context.Report(
|
||||
result,
|
||||
result.GetProcessing() != JSR::Processing::Halted ? "Successfully loaded EditorMaterialComponent information."
|
||||
: "Failed to load EditorMaterialComponent information.");
|
||||
}
|
||||
|
||||
AZ::JsonSerializationResult::Result JsonEditorMaterialComponentSerializer::Store(
|
||||
rapidjson::Value& outputValue,
|
||||
const void* inputValue,
|
||||
const void* defaultValue,
|
||||
[[maybe_unused]] const AZ::Uuid& valueTypeId,
|
||||
AZ::JsonSerializerContext& context)
|
||||
{
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
|
||||
AZ_Assert(
|
||||
azrtti_typeid<EditorMaterialComponent>() == valueTypeId,
|
||||
"Unable to Serialize EditorMaterialComponent because the provided type is %s.",
|
||||
valueTypeId.ToString<AZStd::string>().c_str());
|
||||
|
||||
auto componentInstance = reinterpret_cast<const EditorMaterialComponent*>(inputValue);
|
||||
AZ_Assert(componentInstance, "Input value for JsonEditorMaterialComponentSerializer can't be null.");
|
||||
auto defaultComponentInstance = reinterpret_cast<const EditorMaterialComponent*>(defaultValue);
|
||||
|
||||
JSR::ResultCode result(JSR::Tasks::WriteValue);
|
||||
{
|
||||
AZ::ScopedContextPath subPathName(context, "m_id");
|
||||
const auto componentId = &componentInstance->m_id;
|
||||
const auto defaultComponentId = defaultComponentInstance ? &defaultComponentInstance->m_id : nullptr;
|
||||
|
||||
result.Combine(ContinueStoringToJsonObjectField(
|
||||
outputValue, "Id", componentId, defaultComponentId, azrtti_typeid<decltype(componentInstance->m_id)>(), context));
|
||||
}
|
||||
|
||||
{
|
||||
AZ::ScopedContextPath subPathName(context, "Controller");
|
||||
const auto controller = &componentInstance->m_controller;
|
||||
const auto defaultController = defaultComponentInstance ? &defaultComponentInstance->m_controller : nullptr;
|
||||
|
||||
result.Combine(ContinueStoringToJsonObjectField(
|
||||
outputValue, "Controller", controller, defaultController, azrtti_typeid<decltype(componentInstance->m_controller)>(),
|
||||
context));
|
||||
}
|
||||
|
||||
{
|
||||
AZ::ScopedContextPath subPathName(context, "materialSlotsByLodEnabled");
|
||||
const auto enabled = &componentInstance->m_materialSlotsByLodEnabled;
|
||||
const auto defaultEnabled = defaultComponentInstance ? &defaultComponentInstance->m_materialSlotsByLodEnabled : nullptr;
|
||||
|
||||
result.Combine(ContinueStoringToJsonObjectField(
|
||||
outputValue, "materialSlotsByLodEnabled", enabled, defaultEnabled,
|
||||
azrtti_typeid<decltype(componentInstance->m_materialSlotsByLodEnabled)>(), context));
|
||||
}
|
||||
|
||||
return context.Report(
|
||||
result,
|
||||
result.GetProcessing() != JSR::Processing::Halted ? "Successfully stored EditorMaterialComponent information."
|
||||
: "Failed to store EditorMaterialComponent information.");
|
||||
}
|
||||
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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/Memory/Memory.h>
|
||||
#include <AzCore/Serialization/Json/BaseJsonSerializer.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
// JsonEditorMaterialComponentSerializer skips serialization of EditorMaterialComponentSlot(s) which are only needed at runtime in
|
||||
// the editor
|
||||
class JsonEditorMaterialComponentSerializer : public AZ::BaseJsonSerializer
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(JsonEditorMaterialComponentSerializer, "{D354FE3C-34D2-4E80-B3F9-49450D252336}", BaseJsonSerializer);
|
||||
AZ_CLASS_ALLOCATOR_DECL;
|
||||
|
||||
AZ::JsonSerializationResult::Result Load(
|
||||
void* outputValue,
|
||||
const AZ::Uuid& outputValueTypeId,
|
||||
const rapidjson::Value& inputValue,
|
||||
AZ::JsonDeserializerContext& context) override;
|
||||
|
||||
AZ::JsonSerializationResult::Result Store(
|
||||
rapidjson::Value& outputValue,
|
||||
const void* inputValue,
|
||||
const void* defaultValue,
|
||||
const AZ::Uuid& valueTypeId,
|
||||
AZ::JsonSerializerContext& context) override;
|
||||
};
|
||||
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
+58
-25
@@ -6,22 +6,25 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Material/EditorMaterialComponentSlot.h>
|
||||
#include <Material/EditorMaterialComponentExporter.h>
|
||||
#include <Material/EditorMaterialComponentInspector.h>
|
||||
#include <Material/EditorMaterialModelUvNameMapInspector.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <Atom/RPI.Edit/Common/AssetUtils.h>
|
||||
#include <Atom/RPI.Edit/Material/MaterialSourceData.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/Material/EditorMaterialSystemComponentRequestBus.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <Material/EditorMaterialComponentExporter.h>
|
||||
#include <Material/EditorMaterialComponentInspector.h>
|
||||
#include <Material/EditorMaterialComponentSlot.h>
|
||||
#include <Material/EditorMaterialModelUvNameMapInspector.h>
|
||||
|
||||
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT
|
||||
#include <QMenu>
|
||||
#include <QAction>
|
||||
#include <QAction>
|
||||
#include <QByteArray>
|
||||
#include <QCursor>
|
||||
#include <QDataStream>
|
||||
#include <QMenu>
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
namespace AZ
|
||||
@@ -99,6 +102,7 @@ namespace AZ
|
||||
->Attribute(AZ::Edit::Attributes::NameLabelOverride, &EditorMaterialComponentSlot::GetLabel)
|
||||
->Attribute(AZ::Edit::Attributes::ShowProductAssetFileName, true)
|
||||
->Attribute("ThumbnailCallback", &EditorMaterialComponentSlot::OpenPopupMenu)
|
||||
->Attribute("ThumbnailIcon", &EditorMaterialComponentSlot::GetPreviewPixmapData)
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -117,10 +121,43 @@ namespace AZ
|
||||
}
|
||||
};
|
||||
|
||||
AZStd::vector<char> EditorMaterialComponentSlot::GetPreviewPixmapData() const
|
||||
{
|
||||
if (!GetActiveAssetId().IsValid())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
QPixmap pixmap;
|
||||
EditorMaterialSystemComponentRequestBus::BroadcastResult(
|
||||
pixmap, &EditorMaterialSystemComponentRequestBus::Events::GetRenderedMaterialPreview, m_entityId, m_id);
|
||||
if (pixmap.isNull())
|
||||
{
|
||||
if (m_updatePreview)
|
||||
{
|
||||
EditorMaterialSystemComponentRequestBus::Broadcast(
|
||||
&EditorMaterialSystemComponentRequestBus::Events::RenderMaterialPreview, m_entityId, m_id);
|
||||
m_updatePreview = false;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
QByteArray pixmapBytes;
|
||||
QDataStream stream(&pixmapBytes, QIODevice::WriteOnly);
|
||||
stream << pixmap;
|
||||
return AZStd::vector<char>(pixmapBytes.begin(), pixmapBytes.end());
|
||||
}
|
||||
|
||||
AZ::Data::AssetId EditorMaterialComponentSlot::GetActiveAssetId() const
|
||||
{
|
||||
return m_materialAsset.GetId().IsValid() ? m_materialAsset.GetId() : GetDefaultAssetId();
|
||||
}
|
||||
|
||||
AZ::Data::AssetId EditorMaterialComponentSlot::GetDefaultAssetId() const
|
||||
{
|
||||
AZ::Data::AssetId assetId;
|
||||
MaterialComponentRequestBus::EventResult(assetId, m_entityId, &MaterialComponentRequestBus::Events::GetDefaultMaterialAssetId, m_id);
|
||||
MaterialComponentRequestBus::EventResult(
|
||||
assetId, m_entityId, &MaterialComponentRequestBus::Events::GetDefaultMaterialAssetId, m_id);
|
||||
return assetId;
|
||||
}
|
||||
|
||||
@@ -134,7 +171,7 @@ namespace AZ
|
||||
bool EditorMaterialComponentSlot::HasSourceData() const
|
||||
{
|
||||
// The slot only has valid source data if the source path is valid and the file has the correct extension
|
||||
const AZStd::string& sourcePath = AZ::RPI::AssetUtils::GetSourcePathByAssetId(m_materialAsset.GetId());
|
||||
const AZStd::string& sourcePath = AZ::RPI::AssetUtils::GetSourcePathByAssetId(GetActiveAssetId());
|
||||
return !sourcePath.empty() && AZ::StringFunc::Path::IsExtension(sourcePath.c_str(), AZ::RPI::MaterialSourceData::Extension);
|
||||
}
|
||||
|
||||
@@ -162,14 +199,6 @@ namespace AZ
|
||||
ClearOverrides();
|
||||
}
|
||||
|
||||
void EditorMaterialComponentSlot::ClearToDefaultAsset()
|
||||
{
|
||||
m_materialAsset = AZ::Data::Asset<AZ::RPI::MaterialAsset>(GetDefaultAssetId(), AZ::AzTypeInfo<AZ::RPI::MaterialAsset>::Uuid());
|
||||
MaterialComponentRequestBus::Event(
|
||||
m_entityId, &MaterialComponentRequestBus::Events::SetMaterialOverride, m_id, m_materialAsset.GetId());
|
||||
ClearOverrides();
|
||||
}
|
||||
|
||||
void EditorMaterialComponentSlot::ClearOverrides()
|
||||
{
|
||||
MaterialComponentRequestBus::Event(
|
||||
@@ -219,7 +248,7 @@ namespace AZ
|
||||
|
||||
void EditorMaterialComponentSlot::OpenMaterialEditor() const
|
||||
{
|
||||
const AZStd::string& sourcePath = AZ::RPI::AssetUtils::GetSourcePathByAssetId(m_materialAsset.GetId());
|
||||
const AZStd::string& sourcePath = AZ::RPI::AssetUtils::GetSourcePathByAssetId(GetActiveAssetId());
|
||||
if (!sourcePath.empty() && AZ::StringFunc::Path::IsExtension(sourcePath.c_str(), AZ::RPI::MaterialSourceData::Extension))
|
||||
{
|
||||
EditorMaterialSystemComponentRequestBus::Broadcast(
|
||||
@@ -235,7 +264,7 @@ namespace AZ
|
||||
|
||||
void EditorMaterialComponentSlot::OpenUvNameMapInspector()
|
||||
{
|
||||
if (m_materialAsset.GetId().IsValid())
|
||||
if (GetActiveAssetId().IsValid())
|
||||
{
|
||||
AZStd::unordered_set<AZ::Name> modelUvNames;
|
||||
MaterialReceiverRequestBus::EventResult(modelUvNames, m_entityId, &MaterialReceiverRequestBus::Events::GetModelUvNames);
|
||||
@@ -251,7 +280,7 @@ namespace AZ
|
||||
};
|
||||
|
||||
if (EditorMaterialComponentInspector::OpenInspectorDialog(
|
||||
m_materialAsset.GetId(), matModUvOverrides, modelUvNames, applyMatModUvOverrideChangedCallback))
|
||||
GetActiveAssetId(), matModUvOverrides, modelUvNames, applyMatModUvOverrideChangedCallback))
|
||||
{
|
||||
OnDataChanged();
|
||||
}
|
||||
@@ -273,10 +302,10 @@ namespace AZ
|
||||
action->setEnabled(HasSourceData());
|
||||
|
||||
action = menu.addAction("Edit Material Instance...", [this]() { OpenMaterialInspector(); });
|
||||
action->setEnabled(m_materialAsset.GetId().IsValid());
|
||||
action->setEnabled(GetActiveAssetId().IsValid());
|
||||
|
||||
action = menu.addAction("Edit Material Instance UV Map...", [this]() { OpenUvNameMapInspector(); });
|
||||
action->setEnabled(m_materialAsset.GetId().IsValid());
|
||||
action->setEnabled(GetActiveAssetId().IsValid());
|
||||
|
||||
menu.addSeparator();
|
||||
|
||||
@@ -308,6 +337,10 @@ namespace AZ
|
||||
AzToolsFramework::ToolsApplicationRequests::Bus::Broadcast(
|
||||
&AzToolsFramework::ToolsApplicationRequests::Bus::Events::AddDirtyEntity, m_entityId);
|
||||
|
||||
EditorMaterialSystemComponentRequestBus::Broadcast(
|
||||
&EditorMaterialSystemComponentRequestBus::Events::RenderMaterialPreview, m_entityId, m_id);
|
||||
m_updatePreview = false;
|
||||
|
||||
MaterialComponentNotificationBus::Event(m_entityId, &MaterialComponentNotifications::OnMaterialsEdited);
|
||||
|
||||
AzToolsFramework::ToolsApplicationEvents::Bus::Broadcast(
|
||||
|
||||
+28
-11
@@ -8,36 +8,52 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <Atom/RPI.Reflect/Material/MaterialAsset.h>
|
||||
#include <Atom/Feature/Material/MaterialAssignment.h>
|
||||
#include <Atom/RPI.Reflect/Material/MaterialAsset.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <QPixmap>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
static const size_t DefaultMaterialSlotIndex = std::numeric_limits<size_t>::max();
|
||||
|
||||
//! Details for a single editable material assignment
|
||||
struct EditorMaterialComponentSlot final
|
||||
{
|
||||
AZ_RTTI(EditorMaterialComponentSlot, "{344066EB-7C3D-4E92-B53D-3C9EBD546488}");
|
||||
AZ_CLASS_ALLOCATOR(EditorMaterialComponentSlot, SystemAllocator, 0);
|
||||
|
||||
static void Reflect(ReflectContext* context);
|
||||
static bool ConvertVersion(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement);
|
||||
static void Reflect(ReflectContext* context);
|
||||
|
||||
//! Get cached preview image as a buffer to use as an RPE attribute
|
||||
//! If a cached image isn't avalible then a request will be made to render one
|
||||
AZStd::vector<char> GetPreviewPixmapData() const;
|
||||
|
||||
//! Returns the overridden asset id if it's valid, otherwise gets the default asseet id
|
||||
AZ::Data::AssetId GetActiveAssetId() const;
|
||||
|
||||
//! Returns the default asseet id of the material provded by the model
|
||||
AZ::Data::AssetId GetDefaultAssetId() const;
|
||||
|
||||
//! Returns the display name of the material slot
|
||||
AZStd::string GetLabel() const;
|
||||
|
||||
//! Returns true if the active material asset has a source material
|
||||
bool HasSourceData() const;
|
||||
|
||||
//! Assign a new material override asset
|
||||
void SetAsset(const Data::AssetId& assetId);
|
||||
|
||||
//! Assign a new material override asset
|
||||
void SetAsset(const Data::Asset<RPI::MaterialAsset>& asset);
|
||||
|
||||
//! Remove material and prperty overrides
|
||||
void Clear();
|
||||
void ClearToDefaultAsset();
|
||||
|
||||
//! Remove prperty overrides
|
||||
void ClearOverrides();
|
||||
|
||||
void OpenMaterialExporter();
|
||||
@@ -53,6 +69,7 @@ namespace AZ
|
||||
void OpenPopupMenu(const AZ::Data::AssetId& assetId, const AZ::Data::AssetType& assetType);
|
||||
void OnMaterialChanged() const;
|
||||
void OnDataChanged() const;
|
||||
mutable bool m_updatePreview = true;
|
||||
};
|
||||
|
||||
// Vector of slots for assignable or overridable material data.
|
||||
@@ -61,8 +78,8 @@ namespace AZ
|
||||
// Table containing all editable material data that is displayed in the edit context and inspector
|
||||
// The vector represents all the LODs that can have material overrides.
|
||||
// The container will be populated with every potential material slot on an associated model, using its default values.
|
||||
// Whenever changes are made to this container, the modified values are copied into the controller configuration material assignment map
|
||||
// as overrides that will be applied to material instances
|
||||
// Whenever changes are made to this container, the modified values are copied into the controller configuration material assignment
|
||||
// map as overrides that will be applied to material instances
|
||||
using EditorMaterialComponentSlotsByLodContainer = AZStd::vector<EditorMaterialComponentSlotContainer>;
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
+18
-41
@@ -17,6 +17,7 @@
|
||||
#include <Atom/RPI.Reflect/Material/MaterialAsset.h>
|
||||
#include <Atom/RPI.Reflect/Material/MaterialPropertiesLayout.h>
|
||||
#include <Atom/RPI.Reflect/Material/MaterialTypeAsset.h>
|
||||
#include <AtomToolsFramework/Util/MaterialPropertyUtil.h>
|
||||
#include <AzFramework/API/ApplicationAPI.h>
|
||||
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
@@ -97,56 +98,31 @@ namespace AZ
|
||||
|
||||
bool SaveSourceMaterialFromEditData(const AZStd::string& path, const MaterialEditData& editData)
|
||||
{
|
||||
// Construct the material source data object that will be exported
|
||||
AZ::RPI::MaterialSourceData exportData;
|
||||
exportData.m_propertyLayoutVersion = editData.m_materialTypeSourceData.GetPropertyLayout().m_version;
|
||||
|
||||
// Converting absolute material paths to relative paths
|
||||
bool result = false;
|
||||
AZ::Data::AssetInfo info;
|
||||
AZStd::string watchFolder;
|
||||
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(
|
||||
result, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath,
|
||||
editData.m_materialTypeSourcePath.c_str(), info, watchFolder);
|
||||
if (!result)
|
||||
if (path.empty() || !editData.m_materialAsset.IsReady() || !editData.m_materialTypeAsset.IsReady() ||
|
||||
editData.m_materialTypeSourcePath.empty())
|
||||
{
|
||||
AZ_Error(
|
||||
"AZ::Render::EditorMaterialComponentUtil", false,
|
||||
"Failed to get material type source file info while attempting to export: %s", path.c_str());
|
||||
AZ_Error("AZ::Render::EditorMaterialComponentUtil", false, "Can not export: %s", path.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
exportData.m_materialType = info.m_relativePath;
|
||||
|
||||
if (!editData.m_materialParentSourcePath.empty())
|
||||
{
|
||||
result = false;
|
||||
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(
|
||||
result, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath,
|
||||
editData.m_materialParentSourcePath.c_str(), info, watchFolder);
|
||||
if (!result)
|
||||
{
|
||||
AZ_Error(
|
||||
"AZ::Render::EditorMaterialComponentUtil", false,
|
||||
"Failed to get parent material source file info while attempting to export: %s", path.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
exportData.m_parentMaterial = info.m_relativePath;
|
||||
}
|
||||
// Construct the material source data object that will be exported
|
||||
AZ::RPI::MaterialSourceData exportData;
|
||||
exportData.m_materialTypeVersion = editData.m_materialTypeAsset->GetVersion();
|
||||
exportData.m_materialType = AtomToolsFramework::GetExteralReferencePath(path, editData.m_materialTypeSourcePath);
|
||||
exportData.m_parentMaterial = AtomToolsFramework::GetExteralReferencePath(path, editData.m_materialParentSourcePath);
|
||||
|
||||
// Copy all of the properties from the material asset to the source data that will be exported
|
||||
result = true;
|
||||
bool result = true;
|
||||
editData.m_materialTypeSourceData.EnumerateProperties([&](const AZStd::string& propertyIdContext, const AZ::RPI::MaterialTypeSourceData::PropertyDefinition* propertyDefinition)
|
||||
{
|
||||
AZ::Name propertyId(propertyIdContext + propertyDefinition->m_name);
|
||||
|
||||
const AZ::RPI::MaterialPropertyIndex propertyIndex =
|
||||
editData.m_materialAsset->GetMaterialPropertiesLayout()->FindPropertyIndex(propertyId);
|
||||
|
||||
AZ::RPI::MaterialPropertyValue propertyValue = editData.m_materialAsset->GetPropertyValues()[propertyIndex.GetIndex()];
|
||||
AZ::RPI::MaterialPropertyValue propertyValue =
|
||||
editData.m_materialAsset->GetPropertyValues()[propertyIndex.GetIndex()];
|
||||
|
||||
AZ::RPI::MaterialPropertyValue propertyValueDefault = propertyDefinition->m_value;
|
||||
AZ::RPI::MaterialPropertyValue propertyValueDefault = propertyDefinition.m_value;
|
||||
if (editData.m_materialParentAsset.IsReady())
|
||||
{
|
||||
propertyValueDefault = editData.m_materialParentAsset->GetPropertyValues()[propertyIndex.GetIndex()];
|
||||
@@ -154,12 +130,12 @@ namespace AZ
|
||||
|
||||
// Check for and apply any property overrides before saving property values
|
||||
auto propertyOverrideItr = editData.m_materialPropertyOverrideMap.find(propertyId);
|
||||
if(propertyOverrideItr != editData.m_materialPropertyOverrideMap.end())
|
||||
if (propertyOverrideItr != editData.m_materialPropertyOverrideMap.end())
|
||||
{
|
||||
propertyValue = AZ::RPI::MaterialPropertyValue::FromAny(propertyOverrideItr->second);
|
||||
}
|
||||
|
||||
if (!editData.m_materialTypeSourceData.ConvertPropertyValueToSourceDataFormat(*propertyDefinition, propertyValue))
|
||||
if (!AtomToolsFramework::ConvertToExportFormat(path, propertyId, propertyDefinition, propertyValue))
|
||||
{
|
||||
AZ_Error("AZ::Render::EditorMaterialComponentUtil", false, "Failed to export: %s", path.c_str());
|
||||
result = false;
|
||||
@@ -171,10 +147,11 @@ namespace AZ
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TODO: Support populating the Material Editor with nested property sets, not just the top level.
|
||||
const AZStd::string groupName = propertyId.GetStringView().substr(0, propertyId.GetStringView().size() - propertyDefinition->m_name.size() - 1);
|
||||
exportData.m_properties[groupName][propertyDefinition->m_name].m_value = propertyValue;
|
||||
exportData.m_properties[groupName][propertyDefinition.m_name].m_value = propertyValue;
|
||||
return true;
|
||||
});
|
||||
|
||||
|
||||
+16
-8
@@ -290,14 +290,22 @@ namespace AZ
|
||||
menuButton->setAutoRaise(true);
|
||||
menuButton->setIcon(QIcon(":/Cards/img/UI20/Cards/menu_ico.svg"));
|
||||
menuButton->setVisible(true);
|
||||
QObject::connect(menuButton, &QToolButton::clicked, &dialog, [&]() {
|
||||
QAction* action = nullptr;
|
||||
|
||||
QMenu menu(&dialog);
|
||||
action = menu.addAction("Clear", [&] { inspector->SetUvNameMap(RPI::MaterialModelUvOverrideMap()); });
|
||||
action = menu.addAction("Revert", [&] { inspector->SetUvNameMap(matModUvOverrides);; });
|
||||
menu.exec(QCursor::pos());
|
||||
});
|
||||
QObject::connect(
|
||||
menuButton, &QToolButton::clicked, &dialog, [&]()
|
||||
{
|
||||
QMenu menu(&dialog);
|
||||
menu.addAction(
|
||||
"Clear", [&]
|
||||
{
|
||||
inspector->SetUvNameMap(RPI::MaterialModelUvOverrideMap());
|
||||
});
|
||||
menu.addAction(
|
||||
"Revert", [&]
|
||||
{
|
||||
inspector->SetUvNameMap(matModUvOverrides);
|
||||
});
|
||||
menu.exec(QCursor::pos());
|
||||
});
|
||||
|
||||
QDialogButtonBox* buttonBox = new QDialogButtonBox(&dialog);
|
||||
buttonBox->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user