Merge branch 'development' into animation/rhhong/RenderUtilOptions
Signed-off-by: rhhong <rhhong@amazon.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"Source" : "LyShineUI",
|
||||
"Source" : "LyShineUI.azsl",
|
||||
|
||||
"DepthStencilState" : {
|
||||
"Depth" : {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"Source" : "SimpleTextured",
|
||||
"Source" : "SimpleTextured.azsl",
|
||||
|
||||
"DepthStencilState" : {
|
||||
"Depth" : {
|
||||
|
||||
@@ -1353,8 +1353,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
|
||||
|
||||
@@ -84,10 +84,6 @@ namespace AtomImGuiTools
|
||||
{
|
||||
m_imguiGpuProfiler.Draw(m_showGpuProfiler, AZ::RPI::PassSystemInterface::Get()->GetRootPass().get());
|
||||
}
|
||||
if (m_showCpuProfiler)
|
||||
{
|
||||
m_imguiCpuProfiler.Draw(m_showCpuProfiler);
|
||||
}
|
||||
if (m_showTransientAttachmentProfiler)
|
||||
{
|
||||
auto* transientStats = AZ::RHI::RHISystemInterface::Get()->GetTransientAttachmentStatistics();
|
||||
@@ -108,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;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"Source" : "TexturedIcon",
|
||||
"Source" : "TexturedIcon.azsl",
|
||||
|
||||
"DepthStencilState" : {
|
||||
"Depth" : {
|
||||
|
||||
-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;
|
||||
|
||||
|
||||
-1
@@ -59,7 +59,6 @@ namespace AZ
|
||||
float m_bias = 0.1f;
|
||||
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;
|
||||
|
||||
|
||||
+16
-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,22 @@ 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;
|
||||
};
|
||||
using DirectionalLightRequestBus = EBus<DirectionalLightRequests>;
|
||||
|
||||
|
||||
+5
-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,9 @@ 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;
|
||||
|
||||
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
|
||||
|
||||
+3
@@ -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
|
||||
|
||||
-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
|
||||
-1
@@ -36,7 +36,6 @@ namespace AZ
|
||||
->Field("Shadow Bias", &AreaLightComponentConfig::m_bias)
|
||||
->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)
|
||||
;
|
||||
|
||||
-18
@@ -74,8 +74,6 @@ namespace AZ::Render
|
||||
->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)
|
||||
@@ -95,7 +93,6 @@ namespace AZ::Render
|
||||
->VirtualProperty("ShadowBias", "GetShadowBias", "SetShadowBias")
|
||||
->VirtualProperty("ShadowmapMaxSize", "GetShadowmapMaxSize", "SetShadowmapMaxSize")
|
||||
->VirtualProperty("ShadowFilterMethod", "GetShadowFilterMethod", "SetShadowFilterMethod")
|
||||
->VirtualProperty("SofteningBoundaryWidthAngle", "GetSofteningBoundaryWidthAngle", "SetSofteningBoundaryWidthAngle")
|
||||
->VirtualProperty("FilteringSampleCount", "GetFilteringSampleCount", "SetFilteringSampleCount")
|
||||
->VirtualProperty("EsmExponent", "GetEsmExponent", "SetEsmExponent");
|
||||
;
|
||||
@@ -307,7 +304,6 @@ namespace AZ::Render
|
||||
m_lightShapeDelegate->SetShadowBias(m_configuration.m_bias);
|
||||
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);
|
||||
}
|
||||
@@ -506,20 +502,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
@@ -82,8 +82,6 @@ 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;
|
||||
|
||||
+3
-2
@@ -37,9 +37,10 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+37
-20
@@ -80,12 +80,14 @@ 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)
|
||||
->VirtualProperty("Color", "GetColor", "SetColor")
|
||||
->VirtualProperty("Intensity", "GetIntensity", "SetIntensity")
|
||||
->VirtualProperty("AngularDiameter", "GetAngularDiameter", "SetAngularDiameter")
|
||||
@@ -99,9 +101,10 @@ 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");
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -404,26 +407,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,7 +533,8 @@ 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);
|
||||
|
||||
|
||||
+4
-2
@@ -76,12 +76,14 @@ 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;
|
||||
|
||||
private:
|
||||
friend class EditorDirectionalLightComponent;
|
||||
|
||||
@@ -147,14 +147,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,7 +44,6 @@ 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;
|
||||
|
||||
|
||||
+1
-10
@@ -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, 2.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)
|
||||
|
||||
+20
-13
@@ -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,26 @@ 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)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,6 @@ 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{};
|
||||
|
||||
|
||||
@@ -75,8 +75,6 @@ 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.
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -34,7 +34,6 @@ 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;
|
||||
|
||||
|
||||
+51
-11
@@ -6,15 +6,17 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <EditorCommonFeaturesSystemComponent.h>
|
||||
#include <SkinnedMesh/SkinnedMeshDebugDisplay.h>
|
||||
|
||||
#include <AzCore/Serialization/SerializeContext.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 +70,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 +84,23 @@ 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();
|
||||
AzFramework::AssetCatalogEventBus::Handler::BusConnect();
|
||||
AzFramework::ApplicationLifecycleEvents::Bus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
void EditorCommonFeaturesSystemComponent::Deactivate()
|
||||
{
|
||||
AzToolsFramework::EditorLevelNotificationBus::Handler::BusDisconnect();
|
||||
AzFramework::ApplicationLifecycleEvents::Bus::Handler::BusDisconnect();
|
||||
AzFramework::AssetCatalogEventBus::Handler::BusDisconnect();
|
||||
AzToolsFramework::EditorLevelNotificationBus::Handler::BusDisconnect();
|
||||
AzToolsFramework::AssetBrowser::PreviewerRequestBus::Handler::BusDisconnect();
|
||||
|
||||
m_skinnedMeshDebugDisplay.reset();
|
||||
m_previewerFactory.reset();
|
||||
m_renderer.reset();
|
||||
TeardownThumbnails();
|
||||
}
|
||||
|
||||
void EditorCommonFeaturesSystemComponent::OnNewLevelCreated()
|
||||
@@ -191,6 +192,13 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
void EditorCommonFeaturesSystemComponent::OnCatalogLoaded([[maybe_unused]] const char* catalogFile)
|
||||
{
|
||||
AZ::TickBus::QueueFunction([this](){
|
||||
SetupThumbnails();
|
||||
});
|
||||
}
|
||||
|
||||
const AzToolsFramework::AssetBrowser::PreviewerFactory* EditorCommonFeaturesSystemComponent::GetPreviewerFactory(
|
||||
const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry) const
|
||||
{
|
||||
@@ -199,7 +207,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
|
||||
|
||||
+16
-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
|
||||
{
|
||||
@@ -28,6 +28,7 @@ namespace AZ
|
||||
, public AzToolsFramework::EditorLevelNotificationBus::Handler
|
||||
, public AzToolsFramework::SliceEditorEntityOwnershipServiceNotificationBus::Handler
|
||||
, public AzToolsFramework::AssetBrowser::PreviewerRequestBus::Handler
|
||||
, public AzFramework::AssetCatalogEventBus::Handler
|
||||
, public AzFramework::ApplicationLifecycleEvents::Bus::Handler
|
||||
{
|
||||
public:
|
||||
@@ -53,15 +54,23 @@ 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;
|
||||
|
||||
// AzFramework::AssetCatalogEventBus::Handler overrides ...
|
||||
void OnCatalogLoaded(const char* catalogFile) 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 +78,8 @@ 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;
|
||||
};
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
@@ -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();
|
||||
|
||||
+27
@@ -148,11 +148,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 +240,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 +275,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;
|
||||
|
||||
+8
-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,8 +22,9 @@ 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:
|
||||
using BaseClass = EditorRenderComponentAdapter<MaterialComponentController, MaterialComponent, MaterialComponentConfig>;
|
||||
@@ -52,6 +54,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
|
||||
|
||||
+120
-88
@@ -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();
|
||||
}
|
||||
|
||||
@@ -140,7 +125,7 @@ namespace AZ
|
||||
}
|
||||
|
||||
Populate();
|
||||
m_messageLabel->setVisible(false);
|
||||
LoadOverridesFromEntity();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -152,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
|
||||
@@ -168,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(
|
||||
@@ -226,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())
|
||||
{
|
||||
@@ -234,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()
|
||||
@@ -282,13 +290,8 @@ namespace AZ
|
||||
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
|
||||
for (const auto& groupDefinition : m_editData.m_materialTypeSourceData.GetGroupDefinitionsInDisplayOrder())
|
||||
{
|
||||
@@ -327,10 +330,14 @@ namespace AZ
|
||||
[this](const auto node) { return GetInstanceNodePropertyIndicator(node); }, 0);
|
||||
AddGroup(groupName, groupDisplayName, groupDescription, propertyGroupWidget);
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialPropertyInspector::Populate()
|
||||
{
|
||||
AddGroupsBegin();
|
||||
AddUvNamesGroup();
|
||||
AddPropertiesGroup();
|
||||
AddGroupsEnd();
|
||||
|
||||
LoadOverridesFromEntity();
|
||||
}
|
||||
|
||||
void MaterialPropertyInspector::LoadOverridesFromEntity()
|
||||
@@ -345,6 +352,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)
|
||||
@@ -375,6 +401,7 @@ namespace AZ
|
||||
m_dirtyPropertyFlags.set();
|
||||
RunEditorMaterialFunctors();
|
||||
RebuildAll();
|
||||
UpdateHeading();
|
||||
}
|
||||
|
||||
void MaterialPropertyInspector::SaveOverridesToEntity(bool commitChanges)
|
||||
@@ -398,6 +425,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()
|
||||
@@ -521,9 +551,9 @@ namespace AZ
|
||||
{
|
||||
if (IsInstanceNodePropertyModifed(node))
|
||||
{
|
||||
return ":/PropertyEditor/Resources/changed_data_item.png";
|
||||
return ":/Icons/changed_property.svg";
|
||||
}
|
||||
return ":/PropertyEditor/Resources/blank.png";
|
||||
return ":/Icons/blank.png";
|
||||
}
|
||||
|
||||
bool MaterialPropertyInspector::SaveMaterial() const
|
||||
@@ -607,7 +637,8 @@ namespace AZ
|
||||
MaterialComponentRequestBus::Event(
|
||||
m_entityId, &MaterialComponentRequestBus::Events::SetPropertyOverrides, m_materialAssignmentId,
|
||||
MaterialPropertyOverrideMap());
|
||||
QueueUpdateUI();
|
||||
m_updateUI = true;
|
||||
m_updatePreview = true;
|
||||
});
|
||||
action->setEnabled(IsLoaded());
|
||||
|
||||
@@ -702,10 +733,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)
|
||||
@@ -719,25 +747,39 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -761,16 +803,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>
|
||||
|
||||
+17
-6
@@ -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,11 +89,19 @@ 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);
|
||||
@@ -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
|
||||
|
||||
+45
-19
@@ -6,23 +6,25 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Material/EditorMaterialComponentSlot.h>
|
||||
#include <Material/EditorMaterialComponentExporter.h>
|
||||
#include <Material/EditorMaterialComponentInspector.h>
|
||||
#include <Material/EditorMaterialModelUvNameMapInspector.h>
|
||||
#include <AzCore/Asset/AssetSerializer.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
|
||||
@@ -100,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)
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -118,6 +121,33 @@ 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();
|
||||
@@ -169,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(
|
||||
@@ -315,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(
|
||||
|
||||
+27
-11
@@ -8,37 +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();
|
||||
@@ -54,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.
|
||||
@@ -62,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
|
||||
|
||||
-1
@@ -99,7 +99,6 @@ namespace AZ
|
||||
{
|
||||
// Construct the material source data object that will be exported
|
||||
AZ::RPI::MaterialSourceData exportData;
|
||||
exportData.m_propertyLayoutVersion = editData.m_materialTypeSourceData.m_propertyLayout.m_version;
|
||||
|
||||
// Converting absolute material paths to relative paths
|
||||
bool result = false;
|
||||
|
||||
+106
-33
@@ -7,6 +7,11 @@
|
||||
*/
|
||||
|
||||
#include <Atom/RHI/Factory.h>
|
||||
#include <Atom/RPI.Reflect/Asset/AssetUtils.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/Material/EditorMaterialSystemComponentNotificationBus.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/Material/MaterialComponentBus.h>
|
||||
#include <AtomToolsFramework/PreviewRenderer/PreviewRendererCaptureRequest.h>
|
||||
#include <AtomToolsFramework/PreviewRenderer/PreviewRendererInterface.h>
|
||||
#include <AtomToolsFramework/Util/Util.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/EditContextConstants.inl>
|
||||
@@ -16,11 +21,10 @@
|
||||
#include <AzFramework/Application/Application.h>
|
||||
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
|
||||
#include <AzToolsFramework/API/ViewPaneOptions.h>
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailContext.h>
|
||||
#include <Editor/LyViewPaneNames.h>
|
||||
#include <Material/EditorMaterialComponentInspector.h>
|
||||
#include <Material/EditorMaterialSystemComponent.h>
|
||||
#include <Material/MaterialThumbnail.h>
|
||||
#include <SharedPreview/SharedPreviewContent.h>
|
||||
|
||||
// Disables warning messages triggered by the Qt library
|
||||
// 4251: class needs to have dll-interface to be used by clients of class
|
||||
@@ -30,6 +34,8 @@ AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option")
|
||||
#include <QApplication>
|
||||
#include <QDockWidget>
|
||||
#include <QObject>
|
||||
#include <QPixmap>
|
||||
#include <QImage>
|
||||
#include <QProcessEnvironment>
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
@@ -55,7 +61,7 @@ namespace AZ
|
||||
{
|
||||
ec->Class<EditorMaterialSystemComponent>("EditorMaterialSystemComponent", "System component that manages launching and maintaining connections the material editor.")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System", 0xc94d118b))
|
||||
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("System"))
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
;
|
||||
}
|
||||
@@ -64,17 +70,17 @@ namespace AZ
|
||||
|
||||
void EditorMaterialSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
|
||||
{
|
||||
provided.push_back(AZ_CRC("EditorMaterialSystem", 0x5c93bc4e));
|
||||
provided.push_back(AZ_CRC_CE("EditorMaterialSystem"));
|
||||
}
|
||||
|
||||
void EditorMaterialSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
|
||||
{
|
||||
incompatible.push_back(AZ_CRC("EditorMaterialSystem", 0x5c93bc4e));
|
||||
incompatible.push_back(AZ_CRC_CE("EditorMaterialSystem"));
|
||||
}
|
||||
|
||||
void EditorMaterialSystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
|
||||
{
|
||||
required.push_back(AZ_CRC("ThumbnailerService", 0x65422b97));
|
||||
required.push_back(AZ_CRC_CE("PreviewRendererSystem"));
|
||||
}
|
||||
|
||||
void EditorMaterialSystemComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
|
||||
@@ -89,25 +95,25 @@ namespace AZ
|
||||
|
||||
void EditorMaterialSystemComponent::Activate()
|
||||
{
|
||||
AZ::EntitySystemBus::Handler::BusConnect();
|
||||
EditorMaterialSystemComponentNotificationBus::Handler::BusConnect();
|
||||
EditorMaterialSystemComponentRequestBus::Handler::BusConnect();
|
||||
AzFramework::ApplicationLifecycleEvents::Bus::Handler::BusConnect();
|
||||
AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler::BusConnect();
|
||||
AzToolsFramework::EditorMenuNotificationBus::Handler::BusConnect();
|
||||
AzToolsFramework::EditorEvents::Bus::Handler::BusConnect();
|
||||
|
||||
SetupThumbnails();
|
||||
m_materialBrowserInteractions.reset(aznew MaterialBrowserInteractions);
|
||||
}
|
||||
|
||||
void EditorMaterialSystemComponent::Deactivate()
|
||||
{
|
||||
AZ::EntitySystemBus::Handler::BusDisconnect();
|
||||
EditorMaterialSystemComponentNotificationBus::Handler::BusDisconnect();
|
||||
EditorMaterialSystemComponentRequestBus::Handler::BusDisconnect();
|
||||
AzFramework::ApplicationLifecycleEvents::Bus::Handler::BusDisconnect();
|
||||
AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler::BusDisconnect();
|
||||
AzToolsFramework::EditorMenuNotificationBus::Handler::BusDisconnect();
|
||||
AzToolsFramework::EditorEvents::Bus::Handler::BusDisconnect();
|
||||
|
||||
TeardownThumbnails();
|
||||
m_materialBrowserInteractions.reset();
|
||||
|
||||
if (m_openMaterialEditorAction)
|
||||
@@ -154,11 +160,84 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
void EditorMaterialSystemComponent::OnApplicationAboutToStop()
|
||||
void EditorMaterialSystemComponent::RenderMaterialPreview(
|
||||
const AZ::EntityId& entityId, const AZ::Render::MaterialAssignmentId& materialAssignmentId)
|
||||
{
|
||||
TeardownThumbnails();
|
||||
static constexpr const char* DefaultModelPath = "models/sphere.azmodel";
|
||||
static constexpr const char* DefaultLightingPresetPath = "lightingpresets/thumbnail.lightingpreset.azasset";
|
||||
|
||||
if (auto previewRenderer = AZ::Interface<AtomToolsFramework::PreviewRendererInterface>::Get())
|
||||
{
|
||||
AZ::Data::AssetId materialAssetId = {};
|
||||
MaterialComponentRequestBus::EventResult(
|
||||
materialAssetId, entityId, &MaterialComponentRequestBus::Events::GetMaterialOverride, materialAssignmentId);
|
||||
if (!materialAssetId.IsValid())
|
||||
{
|
||||
MaterialComponentRequestBus::EventResult(
|
||||
materialAssetId, entityId, &MaterialComponentRequestBus::Events::GetDefaultMaterialAssetId, materialAssignmentId);
|
||||
if (!materialAssetId.IsValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
AZ::Render::MaterialPropertyOverrideMap propertyOverrides;
|
||||
AZ::Render::MaterialComponentRequestBus::EventResult(
|
||||
propertyOverrides, entityId, &AZ::Render::MaterialComponentRequestBus::Events::GetPropertyOverrides,
|
||||
materialAssignmentId);
|
||||
|
||||
previewRenderer->AddCaptureRequest(
|
||||
{ MaterialPreviewResolution,
|
||||
AZStd::make_shared<AZ::LyIntegration::SharedPreviewContent>(
|
||||
previewRenderer->GetScene(), previewRenderer->GetView(), previewRenderer->GetEntityContextId(),
|
||||
AZ::RPI::AssetUtils::GetAssetIdForProductPath(DefaultModelPath), materialAssetId,
|
||||
AZ::RPI::AssetUtils::GetAssetIdForProductPath(DefaultLightingPresetPath), propertyOverrides),
|
||||
[entityId, materialAssignmentId]()
|
||||
{
|
||||
AZ_UNUSED(entityId);
|
||||
AZ_UNUSED(materialAssignmentId);
|
||||
AZ_Warning(
|
||||
"EditorMaterialSystemComponent", false, "RenderMaterialPreview capture failed for entity %s slot %s.",
|
||||
entityId.ToString().c_str(), materialAssignmentId.ToString().c_str());
|
||||
},
|
||||
[entityId, materialAssignmentId](const QPixmap& pixmap)
|
||||
{
|
||||
AZ::Render::EditorMaterialSystemComponentNotificationBus::Broadcast(
|
||||
&AZ::Render::EditorMaterialSystemComponentNotificationBus::Events::OnRenderMaterialPreviewComplete, entityId,
|
||||
materialAssignmentId, pixmap);
|
||||
} });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QPixmap EditorMaterialSystemComponent::GetRenderedMaterialPreview(
|
||||
const AZ::EntityId& entityId, const AZ::Render::MaterialAssignmentId& materialAssignmentId) const
|
||||
{
|
||||
const auto& itr1 = m_materialPreviews.find(entityId);
|
||||
if (itr1 != m_materialPreviews.end())
|
||||
{
|
||||
const auto& itr2 = itr1->second.find(materialAssignmentId);
|
||||
if (itr2 != itr1->second.end())
|
||||
{
|
||||
return itr2->second;
|
||||
}
|
||||
}
|
||||
return QPixmap();
|
||||
}
|
||||
|
||||
void EditorMaterialSystemComponent::OnEntityDestroyed(const AZ::EntityId& entityId)
|
||||
{
|
||||
m_materialPreviews.erase(entityId);
|
||||
}
|
||||
|
||||
void EditorMaterialSystemComponent::OnRenderMaterialPreviewComplete(
|
||||
[[maybe_unused]] const AZ::EntityId& entityId,
|
||||
[[maybe_unused]] const AZ::Render::MaterialAssignmentId& materialAssignmentId,
|
||||
[[maybe_unused]] const QPixmap& pixmap)
|
||||
{
|
||||
PurgePreviews();
|
||||
m_materialPreviews[entityId][materialAssignmentId] = pixmap;
|
||||
}
|
||||
|
||||
void EditorMaterialSystemComponent::OnPopulateToolMenuItems()
|
||||
{
|
||||
if (!m_openMaterialEditorAction)
|
||||
@@ -201,26 +280,6 @@ namespace AZ
|
||||
"Material Property Inspector", LyViewPane::CategoryTools, inspectorOptions);
|
||||
}
|
||||
|
||||
void EditorMaterialSystemComponent::SetupThumbnails()
|
||||
{
|
||||
using namespace AzToolsFramework::Thumbnailer;
|
||||
using namespace LyIntegration;
|
||||
|
||||
ThumbnailerRequestsBus::Broadcast(
|
||||
&ThumbnailerRequests::RegisterThumbnailProvider, MAKE_TCACHE(Thumbnails::MaterialThumbnailCache),
|
||||
ThumbnailContext::DefaultContext);
|
||||
}
|
||||
|
||||
void EditorMaterialSystemComponent::TeardownThumbnails()
|
||||
{
|
||||
using namespace AzToolsFramework::Thumbnailer;
|
||||
using namespace LyIntegration;
|
||||
|
||||
ThumbnailerRequestsBus::Broadcast(
|
||||
&ThumbnailerRequests::UnregisterThumbnailProvider, Thumbnails::MaterialThumbnailCache::ProviderName,
|
||||
ThumbnailContext::DefaultContext);
|
||||
}
|
||||
|
||||
AzToolsFramework::AssetBrowser::SourceFileDetails EditorMaterialSystemComponent::GetSourceFileDetails(
|
||||
const char* fullSourceFileName)
|
||||
{
|
||||
@@ -232,5 +291,19 @@ namespace AZ
|
||||
}
|
||||
return AzToolsFramework::AssetBrowser::SourceFileDetails();
|
||||
}
|
||||
|
||||
void EditorMaterialSystemComponent::PurgePreviews()
|
||||
{
|
||||
size_t materialPreviewCount = 0;
|
||||
for (const auto& materialPreviewPair : m_materialPreviews)
|
||||
{
|
||||
materialPreviewCount += materialPreviewPair.second.size();
|
||||
}
|
||||
|
||||
if (materialPreviewCount > MaterialPreviewLimit)
|
||||
{
|
||||
m_materialPreviews.clear();
|
||||
}
|
||||
}
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
+25
-16
@@ -5,31 +5,32 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AtomLyIntegration/CommonFeatures/Material/EditorMaterialSystemComponentRequestBus.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/Component/Component.h>
|
||||
#include <AzFramework/Application/Application.h>
|
||||
#include <AzCore/Component/EntityBus.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
|
||||
#include <AzToolsFramework/Thumbnails/Thumbnail.h>
|
||||
#include <AzToolsFramework/Viewport/ActionBus.h>
|
||||
|
||||
#include <AtomLyIntegration/CommonFeatures/Material/EditorMaterialSystemComponentRequestBus.h>
|
||||
|
||||
#include <Material/MaterialBrowserInteractions.h>
|
||||
#include <QPixmap>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
//! System component that manages launching and maintaining connections with the material editor.
|
||||
class EditorMaterialSystemComponent
|
||||
class EditorMaterialSystemComponent final
|
||||
: public AZ::Component
|
||||
, private EditorMaterialSystemComponentRequestBus::Handler
|
||||
, private AzFramework::ApplicationLifecycleEvents::Bus::Handler
|
||||
, private AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler
|
||||
, private AzToolsFramework::EditorMenuNotificationBus::Handler
|
||||
, private AzToolsFramework::EditorEvents::Bus::Handler
|
||||
, public AZ::EntitySystemBus::Handler
|
||||
, public EditorMaterialSystemComponentNotificationBus::Handler
|
||||
, public EditorMaterialSystemComponentRequestBus::Handler
|
||||
, public AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler
|
||||
, public AzToolsFramework::EditorMenuNotificationBus::Handler
|
||||
, public AzToolsFramework::EditorEvents::Bus::Handler
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(EditorMaterialSystemComponent, "{96652157-DA0B-420F-B49C-0207C585144C}");
|
||||
@@ -51,9 +52,16 @@ namespace AZ
|
||||
//! EditorMaterialSystemComponentRequestBus::Handler overrides...
|
||||
void OpenMaterialEditor(const AZStd::string& sourcePath) override;
|
||||
void OpenMaterialInspector(const AZ::EntityId& entityId, const AZ::Render::MaterialAssignmentId& materialAssignmentId) override;
|
||||
void RenderMaterialPreview(const AZ::EntityId& entityId, const AZ::Render::MaterialAssignmentId& materialAssignmentId) override;
|
||||
QPixmap GetRenderedMaterialPreview(
|
||||
const AZ::EntityId& entityId, const AZ::Render::MaterialAssignmentId& materialAssignmentId) const override;
|
||||
|
||||
// AzFramework::ApplicationLifecycleEvents overrides...
|
||||
void OnApplicationAboutToStop() override;
|
||||
// AZ::EntitySystemBus::Handler overrides...
|
||||
void OnEntityDestroyed(const AZ::EntityId& entityId) override;
|
||||
|
||||
//! EditorMaterialSystemComponentNotificationBus::Handler overrides...
|
||||
void OnRenderMaterialPreviewComplete(
|
||||
const AZ::EntityId& entityId, const AZ::Render::MaterialAssignmentId& materialAssignmentId, const QPixmap& pixmap) override;
|
||||
|
||||
//! AssetBrowserInteractionNotificationBus::Handler overrides...
|
||||
AzToolsFramework::AssetBrowser::SourceFileDetails GetSourceFileDetails(const char* fullSourceFileName) override;
|
||||
@@ -65,12 +73,13 @@ namespace AZ
|
||||
// AztoolsFramework::EditorEvents::Bus::Handler overrides...
|
||||
void NotifyRegisterViews() override;
|
||||
|
||||
void SetupThumbnails();
|
||||
void TeardownThumbnails();
|
||||
void PurgePreviews();
|
||||
|
||||
QAction* m_openMaterialEditorAction = nullptr;
|
||||
|
||||
AZStd::unique_ptr<MaterialBrowserInteractions> m_materialBrowserInteractions;
|
||||
AZStd::unordered_map<AZ::EntityId, AZStd::unordered_map<AZ::Render::MaterialAssignmentId, QPixmap>> m_materialPreviews;
|
||||
static constexpr const size_t MaterialPreviewLimit = 100;
|
||||
static constexpr const int MaterialPreviewResolution = 128;
|
||||
};
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
+32
@@ -49,6 +49,7 @@ namespace AZ
|
||||
->Event("ClearIncompatibleMaterialOverrides", &MaterialComponentRequestBus::Events::ClearIncompatibleMaterialOverrides)
|
||||
->Event("ClearInvalidMaterialOverrides", &MaterialComponentRequestBus::Events::ClearInvalidMaterialOverrides)
|
||||
->Event("RepairInvalidMaterialOverrides", &MaterialComponentRequestBus::Events::RepairInvalidMaterialOverrides)
|
||||
->Event("ApplyAutomaticPropertyUpdates", &MaterialComponentRequestBus::Events::ApplyAutomaticPropertyUpdates)
|
||||
->Event("SetMaterialOverride", &MaterialComponentRequestBus::Events::SetMaterialOverride)
|
||||
->Event("GetMaterialOverride", &MaterialComponentRequestBus::Events::GetMaterialOverride)
|
||||
->Event("ClearMaterialOverride", &MaterialComponentRequestBus::Events::ClearMaterialOverride)
|
||||
@@ -406,6 +407,37 @@ namespace AZ
|
||||
}
|
||||
LoadMaterials();
|
||||
}
|
||||
|
||||
uint32_t MaterialComponentController::ApplyAutomaticPropertyUpdates()
|
||||
{
|
||||
uint32_t propertiesUpdated = 0;
|
||||
|
||||
for (auto& materialAssignmentPair : m_configuration.m_materials)
|
||||
{
|
||||
MaterialAssignment& materialAssignment = materialAssignmentPair.second;
|
||||
|
||||
AZStd::vector<AZStd::pair<Name, Name>> renamedProperties;
|
||||
|
||||
for (const auto& propertyPair : materialAssignment.m_propertyOverrides)
|
||||
{
|
||||
Name propertyId = propertyPair.first;
|
||||
|
||||
if (materialAssignment.m_materialInstance->GetAsset()->GetMaterialTypeAsset()->ApplyPropertyRenames(propertyId))
|
||||
{
|
||||
renamedProperties.emplace_back(propertyPair.first, propertyId);
|
||||
++propertiesUpdated;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& [oldName, newName] : renamedProperties)
|
||||
{
|
||||
materialAssignment.m_propertyOverrides[newName] = materialAssignment.m_propertyOverrides[oldName];
|
||||
materialAssignment.m_propertyOverrides.erase(oldName);
|
||||
}
|
||||
}
|
||||
|
||||
return propertiesUpdated;
|
||||
}
|
||||
|
||||
void MaterialComponentController::SetDefaultMaterialOverride(const AZ::Data::AssetId& materialAssetId)
|
||||
{
|
||||
|
||||
+1
@@ -58,6 +58,7 @@ namespace AZ
|
||||
void ClearIncompatibleMaterialOverrides() override;
|
||||
void ClearInvalidMaterialOverrides() override;
|
||||
void RepairInvalidMaterialOverrides() override;
|
||||
uint32_t ApplyAutomaticPropertyUpdates() override;
|
||||
void SetDefaultMaterialOverride(const AZ::Data::AssetId& materialAssetId) override;
|
||||
const AZ::Data::AssetId GetDefaultMaterialOverride() const override;
|
||||
void ClearDefaultMaterialOverride() override;
|
||||
|
||||
@@ -1,112 +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 <AzToolsFramework/API/EditorAssetSystemAPI.h>
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
#include <Source/Material/MaterialThumbnail.h>
|
||||
#include <Source/Thumbnails/ThumbnailUtils.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace LyIntegration
|
||||
{
|
||||
namespace Thumbnails
|
||||
{
|
||||
static constexpr const int MaterialThumbnailSize = 512; // 512 is the default size in render to texture pass
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// MaterialThumbnail
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
MaterialThumbnail::MaterialThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey key)
|
||||
: Thumbnail(key)
|
||||
{
|
||||
m_assetId = GetAssetId(key, RPI::MaterialAsset::RTTI_Type());
|
||||
if (!m_assetId.IsValid())
|
||||
{
|
||||
AZ_Error("MaterialThumbnail", false, "Failed to find matching assetId for the thumbnailKey.");
|
||||
m_state = State::Failed;
|
||||
return;
|
||||
}
|
||||
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Handler::BusConnect(key);
|
||||
AzFramework::AssetCatalogEventBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
void MaterialThumbnail::LoadThread()
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::QueueEvent(
|
||||
RPI::MaterialAsset::RTTI_Type(),
|
||||
&AzToolsFramework::Thumbnailer::ThumbnailerRendererRequests::RenderThumbnail,
|
||||
m_key,
|
||||
MaterialThumbnailSize);
|
||||
// wait for response from thumbnail renderer
|
||||
m_renderWait.acquire();
|
||||
}
|
||||
|
||||
MaterialThumbnail::~MaterialThumbnail()
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Handler::BusDisconnect();
|
||||
AzFramework::AssetCatalogEventBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
void MaterialThumbnail::ThumbnailRendered(QPixmap& thumbnailImage)
|
||||
{
|
||||
m_pixmap = thumbnailImage;
|
||||
m_renderWait.release();
|
||||
}
|
||||
|
||||
void MaterialThumbnail::ThumbnailFailedToRender()
|
||||
{
|
||||
m_state = State::Failed;
|
||||
m_renderWait.release();
|
||||
}
|
||||
|
||||
void MaterialThumbnail::OnCatalogAssetChanged([[maybe_unused]] const AZ::Data::AssetId& assetId)
|
||||
{
|
||||
if (m_assetId == assetId &&
|
||||
m_state == State::Ready)
|
||||
{
|
||||
m_state = State::Unloaded;
|
||||
Load();
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// MaterialThumbnailCache
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
MaterialThumbnailCache::MaterialThumbnailCache()
|
||||
: ThumbnailCache<MaterialThumbnail>()
|
||||
{
|
||||
}
|
||||
|
||||
MaterialThumbnailCache::~MaterialThumbnailCache() = default;
|
||||
|
||||
int MaterialThumbnailCache::GetPriority() const
|
||||
{
|
||||
// Material thumbnails override default source thumbnails, so carry higher priority
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char* MaterialThumbnailCache::GetProviderName() const
|
||||
{
|
||||
return ProviderName;
|
||||
}
|
||||
|
||||
bool MaterialThumbnailCache::IsSupportedThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey key) const
|
||||
{
|
||||
return
|
||||
GetAssetId(key, RPI::MaterialAsset::RTTI_Type()).IsValid() &&
|
||||
// in case it's a source scene file, it will contain both material and model products
|
||||
// model thumbnails are handled by MeshThumbnail
|
||||
!GetAssetId(key, RPI::ModelAsset::RTTI_Type()).IsValid();
|
||||
}
|
||||
} // namespace Thumbnails
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
|
||||
#include <Material/moc_MaterialThumbnail.cpp>
|
||||
@@ -1,73 +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
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <AzCore/std/parallel/binary_semaphore.h>
|
||||
#include <AzFramework/Asset/AssetCatalogBus.h>
|
||||
#include <AzToolsFramework/Thumbnails/Thumbnail.h>
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailerBus.h>
|
||||
#include <Thumbnails/Rendering/CommonThumbnailRenderer.h>
|
||||
#endif
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace LyIntegration
|
||||
{
|
||||
namespace Thumbnails
|
||||
{
|
||||
/**
|
||||
* Custom material or model thumbnail that detects when an asset changes and updates the thumbnail
|
||||
*/
|
||||
class MaterialThumbnail
|
||||
: public AzToolsFramework::Thumbnailer::Thumbnail
|
||||
, public AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Handler
|
||||
, private AzFramework::AssetCatalogEventBus::Handler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MaterialThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey key);
|
||||
~MaterialThumbnail() override;
|
||||
|
||||
//! AzToolsFramework::ThumbnailerRendererNotificationBus::Handler overrides...
|
||||
void ThumbnailRendered(QPixmap& thumbnailImage) override;
|
||||
void ThumbnailFailedToRender() override;
|
||||
|
||||
protected:
|
||||
void LoadThread() override;
|
||||
|
||||
private:
|
||||
// AzFramework::AssetCatalogEventBus::Handler interface overrides...
|
||||
void OnCatalogAssetChanged(const AZ::Data::AssetId& assetId) override;
|
||||
|
||||
AZStd::binary_semaphore m_renderWait;
|
||||
Data::AssetId m_assetId;
|
||||
};
|
||||
|
||||
/**
|
||||
* Cache configuration for large material thumbnails
|
||||
*/
|
||||
class MaterialThumbnailCache
|
||||
: public AzToolsFramework::Thumbnailer::ThumbnailCache<MaterialThumbnail>
|
||||
{
|
||||
public:
|
||||
MaterialThumbnailCache();
|
||||
~MaterialThumbnailCache() override;
|
||||
|
||||
int GetPriority() const override;
|
||||
const char* GetProviderName() const override;
|
||||
|
||||
static constexpr const char* ProviderName = "Material Thumbnails";
|
||||
|
||||
protected:
|
||||
bool IsSupportedThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey key) const override;
|
||||
};
|
||||
} // namespace Thumbnails
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
+2
-39
@@ -6,13 +6,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/EditContextConstants.inl>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailContext.h>
|
||||
#include <Source/Mesh/EditorMeshSystemComponent.h>
|
||||
#include <Source/Mesh/MeshThumbnail.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <Mesh/EditorMeshSystemComponent.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -47,11 +44,6 @@ namespace AZ
|
||||
incompatible.push_back(AZ_CRC_CE("EditorMeshSystem"));
|
||||
}
|
||||
|
||||
void EditorMeshSystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
|
||||
{
|
||||
required.push_back(AZ_CRC_CE("ThumbnailerService"));
|
||||
}
|
||||
|
||||
void EditorMeshSystemComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
|
||||
{
|
||||
AZ_UNUSED(dependent);
|
||||
@@ -59,39 +51,10 @@ namespace AZ
|
||||
|
||||
void EditorMeshSystemComponent::Activate()
|
||||
{
|
||||
AzFramework::ApplicationLifecycleEvents::Bus::Handler::BusConnect();
|
||||
SetupThumbnails();
|
||||
}
|
||||
|
||||
void EditorMeshSystemComponent::Deactivate()
|
||||
{
|
||||
TeardownThumbnails();
|
||||
AzFramework::ApplicationLifecycleEvents::Bus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
void EditorMeshSystemComponent::OnApplicationAboutToStop()
|
||||
{
|
||||
TeardownThumbnails();
|
||||
}
|
||||
|
||||
void EditorMeshSystemComponent::SetupThumbnails()
|
||||
{
|
||||
using namespace AzToolsFramework::Thumbnailer;
|
||||
using namespace LyIntegration;
|
||||
|
||||
ThumbnailerRequestsBus::Broadcast(&ThumbnailerRequests::RegisterThumbnailProvider,
|
||||
MAKE_TCACHE(Thumbnails::MeshThumbnailCache),
|
||||
ThumbnailContext::DefaultContext);
|
||||
}
|
||||
|
||||
void EditorMeshSystemComponent::TeardownThumbnails()
|
||||
{
|
||||
using namespace AzToolsFramework::Thumbnailer;
|
||||
using namespace LyIntegration;
|
||||
|
||||
ThumbnailerRequestsBus::Broadcast(&ThumbnailerRequests::UnregisterThumbnailProvider,
|
||||
Thumbnails::MeshThumbnailCache::ProviderName,
|
||||
ThumbnailContext::DefaultContext);
|
||||
}
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Component/Component.h>
|
||||
#include <AzFramework/Application/Application.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -17,7 +16,6 @@ namespace AZ
|
||||
//! System component that sets up necessary logic related to EditorMeshComponent.
|
||||
class EditorMeshSystemComponent
|
||||
: public AZ::Component
|
||||
, private AzFramework::ApplicationLifecycleEvents::Bus::Handler
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(EditorMeshSystemComponent, "{4D332E3D-C4FC-410B-A915-8E234CBDD4EC}");
|
||||
@@ -26,20 +24,12 @@ namespace AZ
|
||||
|
||||
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
|
||||
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
|
||||
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
|
||||
static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
|
||||
|
||||
protected:
|
||||
// AZ::Component interface overrides...
|
||||
void Activate() override;
|
||||
void Deactivate() override;
|
||||
|
||||
private:
|
||||
// AzFramework::ApplicationLifecycleEvents overrides...
|
||||
void OnApplicationAboutToStop() override;
|
||||
|
||||
void SetupThumbnails();
|
||||
void TeardownThumbnails();
|
||||
};
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
@@ -1,109 +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 <AzToolsFramework/API/EditorAssetSystemAPI.h>
|
||||
#include <Atom/RPI.Reflect/Model/ModelAsset.h>
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
#include <Source/Mesh/MeshThumbnail.h>
|
||||
#include <Source/Thumbnails/ThumbnailUtils.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace LyIntegration
|
||||
{
|
||||
namespace Thumbnails
|
||||
{
|
||||
static constexpr const int MeshThumbnailSize = 512; // 512 is the default size in render to texture pass
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// MeshThumbnail
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
MeshThumbnail::MeshThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey key)
|
||||
: Thumbnail(key)
|
||||
{
|
||||
m_assetId = GetAssetId(key, RPI::ModelAsset::RTTI_Type());
|
||||
if (!m_assetId.IsValid())
|
||||
{
|
||||
AZ_Error("MeshThumbnail", false, "Failed to find matching assetId for the thumbnailKey.");
|
||||
m_state = State::Failed;
|
||||
return;
|
||||
}
|
||||
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Handler::BusConnect(key);
|
||||
AzFramework::AssetCatalogEventBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
void MeshThumbnail::LoadThread()
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::QueueEvent(
|
||||
RPI::ModelAsset::RTTI_Type(),
|
||||
&AzToolsFramework::Thumbnailer::ThumbnailerRendererRequests::RenderThumbnail,
|
||||
m_key,
|
||||
MeshThumbnailSize);
|
||||
// wait for response from thumbnail renderer
|
||||
m_renderWait.acquire();
|
||||
}
|
||||
|
||||
MeshThumbnail::~MeshThumbnail()
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Handler::BusDisconnect();
|
||||
AzFramework::AssetCatalogEventBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
void MeshThumbnail::ThumbnailRendered(QPixmap& thumbnailImage)
|
||||
{
|
||||
m_pixmap = thumbnailImage;
|
||||
m_renderWait.release();
|
||||
}
|
||||
|
||||
void MeshThumbnail::ThumbnailFailedToRender()
|
||||
{
|
||||
m_state = State::Failed;
|
||||
m_renderWait.release();
|
||||
}
|
||||
|
||||
void MeshThumbnail::OnCatalogAssetChanged([[maybe_unused]] const AZ::Data::AssetId& assetId)
|
||||
{
|
||||
if (m_assetId == assetId &&
|
||||
m_state == State::Ready)
|
||||
{
|
||||
m_state = State::Unloaded;
|
||||
Load();
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// MeshThumbnailCache
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
MeshThumbnailCache::MeshThumbnailCache()
|
||||
: ThumbnailCache<MeshThumbnail>()
|
||||
{
|
||||
}
|
||||
|
||||
MeshThumbnailCache::~MeshThumbnailCache() = default;
|
||||
|
||||
int MeshThumbnailCache::GetPriority() const
|
||||
{
|
||||
// Material thumbnails override default source thumbnails, so carry higher priority
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char* MeshThumbnailCache::GetProviderName() const
|
||||
{
|
||||
return ProviderName;
|
||||
}
|
||||
|
||||
bool MeshThumbnailCache::IsSupportedThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey key) const
|
||||
{
|
||||
return GetAssetId(key, RPI::ModelAsset::RTTI_Type()).IsValid();
|
||||
}
|
||||
} // namespace Thumbnails
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
|
||||
#include <Mesh/moc_MeshThumbnail.cpp>
|
||||
@@ -1,72 +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
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <AzCore/std/parallel/binary_semaphore.h>
|
||||
#include <AzFramework/Asset/AssetCatalogBus.h>
|
||||
#include <AzToolsFramework/Thumbnails/Thumbnail.h>
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailerBus.h>
|
||||
#endif
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace LyIntegration
|
||||
{
|
||||
namespace Thumbnails
|
||||
{
|
||||
/**
|
||||
* Custom material or model thumbnail that detects when an asset changes and updates the thumbnail
|
||||
*/
|
||||
class MeshThumbnail
|
||||
: public AzToolsFramework::Thumbnailer::Thumbnail
|
||||
, public AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Handler
|
||||
, private AzFramework::AssetCatalogEventBus::Handler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MeshThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey key);
|
||||
~MeshThumbnail() override;
|
||||
|
||||
//! AzToolsFramework::ThumbnailerRendererNotificationBus::Handler overrides...
|
||||
void ThumbnailRendered(QPixmap& thumbnailImage) override;
|
||||
void ThumbnailFailedToRender() override;
|
||||
|
||||
protected:
|
||||
void LoadThread() override;
|
||||
|
||||
private:
|
||||
// AzFramework::AssetCatalogEventBus::Handler interface overrides...
|
||||
void OnCatalogAssetChanged(const AZ::Data::AssetId& assetId) override;
|
||||
|
||||
AZStd::binary_semaphore m_renderWait;
|
||||
Data::AssetId m_assetId;
|
||||
};
|
||||
|
||||
/**
|
||||
* Cache configuration for large material thumbnails
|
||||
*/
|
||||
class MeshThumbnailCache
|
||||
: public AzToolsFramework::Thumbnailer::ThumbnailCache<MeshThumbnail>
|
||||
{
|
||||
public:
|
||||
MeshThumbnailCache();
|
||||
~MeshThumbnailCache() override;
|
||||
|
||||
int GetPriority() const override;
|
||||
const char* GetProviderName() const override;
|
||||
|
||||
static constexpr const char* ProviderName = "Mesh Thumbnails";
|
||||
|
||||
protected:
|
||||
bool IsSupportedThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey key) const override;
|
||||
};
|
||||
} // namespace Thumbnails
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
+187
-19
@@ -7,6 +7,10 @@
|
||||
*/
|
||||
|
||||
#include <PostProcess/ColorGrading/EditorHDRColorGradingComponent.h>
|
||||
#include <AzToolsFramework/API/EditorPythonRunnerRequestsBus.h>
|
||||
#include <AzToolsFramework/API/ComponentEntityObjectBus.h>
|
||||
#include <AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI.h>
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -18,7 +22,10 @@ namespace AZ
|
||||
|
||||
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<EditorHDRColorGradingComponent, BaseClass>()->Version(1);
|
||||
serializeContext->Class<EditorHDRColorGradingComponent, BaseClass>()
|
||||
->Version(2)
|
||||
->Field("generatedLut", &EditorHDRColorGradingComponent::m_generatedLutAbsolutePath)
|
||||
;
|
||||
|
||||
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
|
||||
{
|
||||
@@ -31,6 +38,20 @@ namespace AZ
|
||||
->Attribute(Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("Game"))
|
||||
->Attribute(Edit::Attributes::AutoExpand, true)
|
||||
->Attribute(Edit::Attributes::HelpPageURL, "https://") // [TODO ATOM-2672][PostFX] need to create page for PostProcessing.
|
||||
->ClassElement(AZ::Edit::ClassElements::Group, "LUT Generation")
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->UIElement(AZ::Edit::UIHandlers::Button, "Generate LUT", "Generates a LUT from the scene's enabled color grading blend.")
|
||||
->Attribute(AZ::Edit::Attributes::NameLabelOverride, "")
|
||||
->Attribute(AZ::Edit::Attributes::ButtonText, "Generate LUT")
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorHDRColorGradingComponent::GenerateLut)
|
||||
->DataElement(AZ::Edit::UIHandlers::MultiLineEdit, &EditorHDRColorGradingComponent::m_generatedLutAbsolutePath, "Generated LUT Path", "Generated LUT Path")
|
||||
->Attribute(AZ::Edit::Attributes::ReadOnly, true)
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, &EditorHDRColorGradingComponent::GetGeneratedLutVisibilitySettings)
|
||||
->UIElement(AZ::Edit::UIHandlers::Button, "Activate LUT", "Use the generated LUT asset in a Look Modification component")
|
||||
->Attribute(AZ::Edit::Attributes::NameLabelOverride, "")
|
||||
->Attribute(AZ::Edit::Attributes::ButtonText, "Activate LUT")
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorHDRColorGradingComponent::ActivateLut)
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, &EditorHDRColorGradingComponent::GetGeneratedLutVisibilitySettings)
|
||||
;
|
||||
|
||||
editContext->Class<HDRColorGradingComponentController>(
|
||||
@@ -47,6 +68,9 @@ namespace AZ
|
||||
"Enable HDR color grading.")
|
||||
->ClassElement(AZ::Edit::ClassElements::Group, "Color Adjustment")
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_colorAdjustmentWeight, "Weight", "Weight of color adjustments")
|
||||
->Attribute(Edit::Attributes::Min, 0.0f)
|
||||
->Attribute(Edit::Attributes::Max, 1.0f)
|
||||
->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_colorGradingExposure, "Exposure", "Exposure Value")
|
||||
->Attribute(Edit::Attributes::Min, AZStd::numeric_limits<float>::lowest())
|
||||
->Attribute(Edit::Attributes::Max, AZStd::numeric_limits<float>::max())
|
||||
@@ -66,27 +90,34 @@ namespace AZ
|
||||
->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_colorGradingFilterMultiply, "Filter Multiply", "Filter Multiply Value")
|
||||
->Attribute(Edit::Attributes::Min, 0.0f)
|
||||
->Attribute(Edit::Attributes::Max, 1.0f)
|
||||
->DataElement(AZ::Edit::UIHandlers::Color, &HDRColorGradingComponentConfig::m_colorFilterSwatch, "Color Filter Swatch", "Color Filter Swatch Value")
|
||||
->DataElement(AZ::Edit::UIHandlers::Color, &HDRColorGradingComponentConfig::m_colorFilterSwatch, "Filter Swatch", "Color Filter Swatch Value")
|
||||
|
||||
->ClassElement(AZ::Edit::ClassElements::Group, "White Balance")
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_whiteBalanceWeight, "Weight", "Weight of white balance")
|
||||
->Attribute(Edit::Attributes::Min, 0.0f)
|
||||
->Attribute(Edit::Attributes::Max, 1.0f)
|
||||
->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_whiteBalanceKelvin, "Temperature", "Temperature in Kelvin")
|
||||
->Attribute(Edit::Attributes::Min, 1000.0f)
|
||||
->Attribute(Edit::Attributes::Max, 40000.0f)
|
||||
->Attribute(AZ::Edit::Attributes::SliderCurveMidpoint, 0.165f)
|
||||
->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_whiteBalanceTint, "Tint", "Tint Value")
|
||||
->Attribute(Edit::Attributes::Min, -100.0f)
|
||||
->Attribute(Edit::Attributes::Max, 100.0f)
|
||||
->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_whiteBalanceLuminancePreservation, "Luminance Preservation", "Modulate the preservation of luminance")
|
||||
->Attribute(Edit::Attributes::Min, 0.0f)
|
||||
->Attribute(Edit::Attributes::Max, 1.0f)
|
||||
|
||||
->ClassElement(AZ::Edit::ClassElements::Group, "Split Toning")
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_splitToneWeight, "Split Tone Weight", "Modulates the split toning effect.")
|
||||
->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_splitToneWeight, "Weight", "Modulates the split toning effect.")
|
||||
->Attribute(Edit::Attributes::Min, 0.0f)
|
||||
->Attribute(Edit::Attributes::Max, 1.0f)
|
||||
->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_splitToneBalance, "Split Tone Balance", "Split Tone Balance Value")
|
||||
->Attribute(Edit::Attributes::Min, 0.0f)
|
||||
->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_splitToneBalance, "Balance", "Split Tone Balance Value")
|
||||
->Attribute(Edit::Attributes::Min, -1.0f)
|
||||
->Attribute(Edit::Attributes::Max, 1.0f)
|
||||
->DataElement(AZ::Edit::UIHandlers::Color, &HDRColorGradingComponentConfig::m_splitToneShadowsColor, "Split Tone Shadows Color", "Split Tone Shadows Color")
|
||||
->DataElement(AZ::Edit::UIHandlers::Color, &HDRColorGradingComponentConfig::m_splitToneHighlightsColor, "Split Tone Highlights Color", "Split Tone Highlights Color")
|
||||
->DataElement(AZ::Edit::UIHandlers::Color, &HDRColorGradingComponentConfig::m_splitToneShadowsColor, "Shadows Color", "Split Tone Shadows Color")
|
||||
->DataElement(AZ::Edit::UIHandlers::Color, &HDRColorGradingComponentConfig::m_splitToneHighlightsColor, "Highlights Color", "Split Tone Highlights Color")
|
||||
|
||||
->ClassElement(AZ::Edit::ClassElements::Group, "Channel Mixing")
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
@@ -99,33 +130,56 @@ namespace AZ
|
||||
|
||||
->ClassElement(AZ::Edit::ClassElements::Group, "Shadow Midtones Highlights")
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_smhWeight, "SMH Weight", "Modulates the SMH effect.")
|
||||
->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_smhWeight, "Weight", "Modulates the SMH effect.")
|
||||
->Attribute(Edit::Attributes::Min, 0.0f)
|
||||
->Attribute(Edit::Attributes::Max, 1.0f)
|
||||
->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_smhShadowsStart, "SMH Shadows Start", "SMH Shadows Start Value")
|
||||
->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_smhShadowsStart, "Shadows Start", "SMH Shadows Start Value")
|
||||
->Attribute(Edit::Attributes::Min, 0.0f)
|
||||
->Attribute(Edit::Attributes::Max, 1.0f)
|
||||
->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_smhShadowsEnd, "SMH Shadows End", "SMH Shadows End Value")
|
||||
->Attribute(Edit::Attributes::Max, 16.0f)
|
||||
->Attribute(Edit::Attributes::SoftMax, 2.0f)
|
||||
->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_smhShadowsEnd, "Shadows End", "SMH Shadows End Value")
|
||||
->Attribute(Edit::Attributes::Min, 0.0f)
|
||||
->Attribute(Edit::Attributes::Max, 1.0f)
|
||||
->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_smhHighlightsStart, "SMH Highlights Start", "SMH Highlights Start Value")
|
||||
->Attribute(Edit::Attributes::Max, 16.0f)
|
||||
->Attribute(Edit::Attributes::SoftMax, 2.0f)
|
||||
->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_smhHighlightsStart, "Highlights Start", "SMH Highlights Start Value")
|
||||
->Attribute(Edit::Attributes::Min, 0.0f)
|
||||
->Attribute(Edit::Attributes::Max, 1.0f)
|
||||
->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_smhHighlightsEnd, "SMH Highlights End", "SMH Highlights End Value")
|
||||
->Attribute(Edit::Attributes::Max, 16.0f)
|
||||
->Attribute(Edit::Attributes::SoftMax, 2.0f)
|
||||
->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_smhHighlightsEnd, "Highlights End", "SMH Highlights End Value")
|
||||
->Attribute(Edit::Attributes::Min, 0.0f)
|
||||
->Attribute(Edit::Attributes::Max, 1.0f)
|
||||
->DataElement(AZ::Edit::UIHandlers::Color, &HDRColorGradingComponentConfig::m_smhShadowsColor, "SMH Shadows Color", "SMH Shadows Color")
|
||||
->DataElement(AZ::Edit::UIHandlers::Color, &HDRColorGradingComponentConfig::m_smhMidtonesColor, "SMH Midtones Color", "SMH Midtones Color")
|
||||
->DataElement(AZ::Edit::UIHandlers::Color, &HDRColorGradingComponentConfig::m_smhHighlightsColor, "SMH Highlights Color", "SMH Highlights Color")
|
||||
->Attribute(Edit::Attributes::Max, 16.0f)
|
||||
->Attribute(Edit::Attributes::SoftMax, 2.0f)
|
||||
->DataElement(AZ::Edit::UIHandlers::Color, &HDRColorGradingComponentConfig::m_smhShadowsColor, "Shadows Color", "SMH Shadows Color")
|
||||
->DataElement(AZ::Edit::UIHandlers::Color, &HDRColorGradingComponentConfig::m_smhMidtonesColor, "Midtones Color", "SMH Midtones Color")
|
||||
->DataElement(AZ::Edit::UIHandlers::Color, &HDRColorGradingComponentConfig::m_smhHighlightsColor, "Highlights Color", "SMH Highlights Color")
|
||||
|
||||
->ClassElement(AZ::Edit::ClassElements::Group, "Final Adjustment")
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_finalAdjustmentWeight, "Weight", "Weight of final adjustments")
|
||||
->Attribute(Edit::Attributes::Min, 0.0f)
|
||||
->Attribute(Edit::Attributes::Max, 1.0f)
|
||||
->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_colorGradingHueShift, "Hue Shift", "Hue Shift Value")
|
||||
->Attribute(Edit::Attributes::Min, 0.0f)
|
||||
->Attribute(Edit::Attributes::Max, 1.0f)
|
||||
->DataElement(AZ::Edit::UIHandlers::Slider, &HDRColorGradingComponentConfig::m_colorGradingPostSaturation, "Post Saturation", "Post Saturation Value")
|
||||
->Attribute(Edit::Attributes::Min, -100.0f)
|
||||
->Attribute(Edit::Attributes::Max, 100.0f)
|
||||
|
||||
->ClassElement(AZ::Edit::ClassElements::Group, "LUT Generation")
|
||||
->DataElement(AZ::Edit::UIHandlers::ComboBox, &HDRColorGradingComponentConfig::m_lutResolution, "LUT Resolution", "Resolution of generated LUT")
|
||||
->EnumAttribute(LutResolution::Lut16x16x16, "16x16x16")
|
||||
->EnumAttribute(LutResolution::Lut32x32x32, "32x32x32")
|
||||
->EnumAttribute(LutResolution::Lut64x64x64, "64x64x64")
|
||||
->DataElement(Edit::UIHandlers::ComboBox, &HDRColorGradingComponentConfig::m_shaperPresetType,
|
||||
"Shaper Type", "Shaper Type.")
|
||||
->EnumAttribute(ShaperPresetType::None, "None")
|
||||
->EnumAttribute(ShaperPresetType::LinearCustomRange, "Linear Custom Range")
|
||||
->EnumAttribute(ShaperPresetType::Log2_48Nits, "Log2 48 nits")
|
||||
->EnumAttribute(ShaperPresetType::Log2_1000Nits, "Log2 1000 nits")
|
||||
->EnumAttribute(ShaperPresetType::Log2_2000Nits, "Log2 2000 nits")
|
||||
->EnumAttribute(ShaperPresetType::Log2_4000Nits, "Log2 4000 nits")
|
||||
->EnumAttribute(ShaperPresetType::Log2CustomRange, "Log2 Custom Range")
|
||||
->EnumAttribute(ShaperPresetType::PqSmpteSt2084, "PQ (SMPTE ST 2084)")
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -136,6 +190,120 @@ namespace AZ
|
||||
{
|
||||
}
|
||||
|
||||
void EditorHDRColorGradingComponent::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time)
|
||||
{
|
||||
if (m_waitOneFrame)
|
||||
{
|
||||
m_waitOneFrame = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const char* LutAttachment = "LutOutput";
|
||||
const AZStd::vector<AZStd::string> LutGenerationPassHierarchy{ "LutGenerationPass" };
|
||||
|
||||
char resolvedOutputFilePath[AZ_MAX_PATH_LEN] = { 0 };
|
||||
AZ::IO::FileIOBase::GetDirectInstance()->ResolvePath(m_currentTiffFilePath.c_str(), resolvedOutputFilePath, AZ_MAX_PATH_LEN);
|
||||
|
||||
AZStd::string lutGenerationCacheFolder;
|
||||
AzFramework::StringFunc::Path::GetFolderPath(resolvedOutputFilePath, lutGenerationCacheFolder);
|
||||
AZ::IO::SystemFile::CreateDir(lutGenerationCacheFolder.c_str());
|
||||
|
||||
bool startedCapture = false;
|
||||
AZ::Render::FrameCaptureRequestBus::BroadcastResult(
|
||||
startedCapture,
|
||||
&AZ::Render::FrameCaptureRequestBus::Events::CapturePassAttachment,
|
||||
LutGenerationPassHierarchy,
|
||||
AZStd::string(LutAttachment),
|
||||
m_currentTiffFilePath,
|
||||
AZ::RPI::PassAttachmentReadbackOption::Output);
|
||||
|
||||
if (startedCapture)
|
||||
{
|
||||
AZ::TickBus::Handler::BusDisconnect();
|
||||
AZ::Render::FrameCaptureNotificationBus::Handler::BusConnect();
|
||||
}
|
||||
}
|
||||
|
||||
void EditorHDRColorGradingComponent::OnCaptureFinished([[maybe_unused]] AZ::Render::FrameCaptureResult result, [[maybe_unused]]const AZStd::string& info)
|
||||
{
|
||||
char resolvedInputFilePath[AZ_MAX_PATH_LEN] = { 0 };
|
||||
AZ::IO::FileIOBase::GetDirectInstance()->ResolvePath(m_currentTiffFilePath.c_str(), resolvedInputFilePath, AZ_MAX_PATH_LEN);
|
||||
char resolvedOutputFilePath[AZ_MAX_PATH_LEN] = { 0 };
|
||||
AZ::IO::FileIOBase::GetDirectInstance()->ResolvePath(m_currentLutFilePath.c_str(), resolvedOutputFilePath, AZ_MAX_PATH_LEN);
|
||||
|
||||
AZStd::string lutGenerationFolder;
|
||||
AzFramework::StringFunc::Path::GetFolderPath(resolvedOutputFilePath, lutGenerationFolder);
|
||||
AZ::IO::SystemFile::CreateDir(lutGenerationFolder.c_str());
|
||||
|
||||
AZStd::vector<AZStd::string_view> pythonArgs
|
||||
{
|
||||
"--i", resolvedInputFilePath,
|
||||
"--o", resolvedOutputFilePath
|
||||
};
|
||||
|
||||
AzToolsFramework::EditorPythonRunnerRequestBus::Broadcast(
|
||||
&AzToolsFramework::EditorPythonRunnerRequestBus::Events::ExecuteByFilenameWithArgs,
|
||||
TiffToAzassetPythonScriptPath,
|
||||
pythonArgs);
|
||||
|
||||
m_controller.m_configuration.m_generateLut = false;
|
||||
m_controller.OnConfigChanged();
|
||||
|
||||
m_generatedLutAbsolutePath = resolvedOutputFilePath + AZStd::string(".azasset");
|
||||
AzToolsFramework::PropertyEditorGUIMessages::Bus::Broadcast(
|
||||
&AzToolsFramework::PropertyEditorGUIMessages::RequestRefresh,
|
||||
AzToolsFramework::PropertyModificationRefreshLevel::Refresh_EntireTree);
|
||||
|
||||
AZ::Render::FrameCaptureNotificationBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
void EditorHDRColorGradingComponent::GenerateLut()
|
||||
{
|
||||
// turn on lut generation pass
|
||||
AZ::Uuid uuid = AZ::Uuid::CreateRandom();
|
||||
AZStd::string uuidString;
|
||||
uuid.ToString(uuidString);
|
||||
|
||||
m_currentTiffFilePath = AZStd::string::format(TempTiffFilePath, uuidString.c_str());
|
||||
m_currentLutFilePath = "@projectroot@/" + AZStd::string::format(GeneratedLutRelativePath, uuidString.c_str());
|
||||
|
||||
m_controller.SetGenerateLut(true);
|
||||
m_controller.OnConfigChanged();
|
||||
|
||||
m_waitOneFrame = true;
|
||||
|
||||
AZ::TickBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
AZ::u32 EditorHDRColorGradingComponent::ActivateLut()
|
||||
{
|
||||
using namespace AzFramework::StringFunc::Path;
|
||||
|
||||
AZStd::string entityName;
|
||||
AZ::ComponentApplicationBus::BroadcastResult(entityName, &AZ::ComponentApplicationRequests::GetEntityName, GetEntityId());
|
||||
|
||||
AZStd::string filename;
|
||||
GetFileName(m_generatedLutAbsolutePath.c_str(), filename);
|
||||
AZStd::string assetRelativePath = "LutGeneration/" + filename + ".azasset";
|
||||
AZStd::vector<AZStd::string_view> pythonArgs
|
||||
{
|
||||
"--entityName", entityName,
|
||||
"--assetRelativePath", assetRelativePath
|
||||
};
|
||||
|
||||
AzToolsFramework::EditorPythonRunnerRequestBus::Broadcast(
|
||||
&AzToolsFramework::EditorPythonRunnerRequestBus::Events::ExecuteByFilenameWithArgs,
|
||||
ActivateLutAssetPythonScriptPath,
|
||||
pythonArgs);
|
||||
|
||||
return AZ::Edit::PropertyRefreshLevels::EntireTree;
|
||||
}
|
||||
|
||||
bool EditorHDRColorGradingComponent::GetGeneratedLutVisibilitySettings()
|
||||
{
|
||||
return !m_generatedLutAbsolutePath.empty();
|
||||
}
|
||||
|
||||
u32 EditorHDRColorGradingComponent::OnConfigurationChanged()
|
||||
{
|
||||
m_controller.OnConfigChanged();
|
||||
|
||||
+26
@@ -8,16 +8,25 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorComponentAdapter.h>
|
||||
#include <Atom/Feature/Utils/FrameCaptureBus.h>
|
||||
#include <PostProcess/ColorGrading/HDRColorGradingComponent.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
static constexpr const char* const TempTiffFilePath{ "@usercache@/LutGeneration/SavedLut_%s.tiff" };
|
||||
static constexpr const char* const GeneratedLutRelativePath = { "LutGeneration/SavedLut_%s" };
|
||||
static constexpr const char* const TiffToAzassetPythonScriptPath{ "@engroot@/Gems/Atom/Feature/Common/Editor/Scripts/ColorGrading/tiff_to_3dl_azasset.py" };
|
||||
static constexpr const char* const ActivateLutAssetPythonScriptPath{ "@engroot@/Gems/Atom/Feature/Common/Editor/Scripts/ColorGrading/activate_lut_asset.py" };
|
||||
|
||||
class EditorHDRColorGradingComponent final
|
||||
: public AzToolsFramework::Components::
|
||||
EditorComponentAdapter<HDRColorGradingComponentController, HDRColorGradingComponent, HDRColorGradingComponentConfig>
|
||||
, private TickBus::Handler
|
||||
, private FrameCaptureNotificationBus::Handler
|
||||
{
|
||||
public:
|
||||
using BaseClass = AzToolsFramework::Components::EditorComponentAdapter<HDRColorGradingComponentController, HDRColorGradingComponent, HDRColorGradingComponentConfig>;
|
||||
@@ -30,6 +39,23 @@ namespace AZ
|
||||
|
||||
//! EditorRenderComponentAdapter overrides...
|
||||
AZ::u32 OnConfigurationChanged() override;
|
||||
|
||||
private:
|
||||
// AZ::TickBus overrides ...
|
||||
void OnTick(float deltaTime, AZ::ScriptTimePoint time) override;
|
||||
|
||||
// FrameCaptureNotificationBus overrides ...
|
||||
void OnCaptureFinished(AZ::Render::FrameCaptureResult result, const AZStd::string& info) override;
|
||||
|
||||
void GenerateLut();
|
||||
AZ::u32 ActivateLut();
|
||||
bool GetGeneratedLutVisibilitySettings();
|
||||
|
||||
bool m_waitOneFrame = false;
|
||||
AZStd::string m_currentTiffFilePath;
|
||||
AZStd::string m_currentLutFilePath;
|
||||
|
||||
AZStd::string m_generatedLutAbsolutePath;
|
||||
};
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
+1
@@ -52,6 +52,7 @@ namespace AZ
|
||||
void HDRColorGradingComponentController::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
|
||||
{
|
||||
incompatible.push_back(AZ_CRC_CE("HDRColorGradingService"));
|
||||
incompatible.push_back(AZ_CRC_CE("LookModificationService"));
|
||||
}
|
||||
|
||||
void HDRColorGradingComponentController::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
|
||||
|
||||
+2
-2
@@ -49,12 +49,12 @@ namespace AZ
|
||||
|
||||
void LookModificationComponentController::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
|
||||
{
|
||||
provided.push_back(AZ_CRC("LookModificationService", 0x207b7539));
|
||||
provided.push_back(AZ_CRC_CE("LookModificationService"));
|
||||
}
|
||||
|
||||
void LookModificationComponentController::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
|
||||
{
|
||||
incompatible.push_back(AZ_CRC("LookModificationService", 0x207b7539));
|
||||
incompatible.push_back(AZ_CRC("LookModificationService"));
|
||||
}
|
||||
|
||||
void LookModificationComponentController::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
|
||||
|
||||
+173
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* 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/Feature/ImageBasedLights/ImageBasedLightFeatureProcessorInterface.h>
|
||||
#include <Atom/Feature/PostProcess/PostProcessFeatureProcessorInterface.h>
|
||||
#include <Atom/Feature/SkyBox/SkyBoxFeatureProcessorInterface.h>
|
||||
#include <Atom/Feature/Utils/LightingPreset.h>
|
||||
#include <Atom/RPI.Public/Scene.h>
|
||||
#include <Atom/RPI.Reflect/Asset/AssetUtils.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/Material/MaterialComponentBus.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/Material/MaterialComponentConstants.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/Mesh/MeshComponentBus.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/Mesh/MeshComponentConstants.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzCore/Math/MatrixUtils.h>
|
||||
#include <AzCore/Math/Transform.h>
|
||||
#include <AzFramework/Components/TransformComponent.h>
|
||||
#include <AzFramework/Entity/EntityContextBus.h>
|
||||
#include <SharedPreview/SharedPreviewContent.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace LyIntegration
|
||||
{
|
||||
SharedPreviewContent::SharedPreviewContent(
|
||||
RPI::ScenePtr scene,
|
||||
RPI::ViewPtr view,
|
||||
AZ::Uuid entityContextId,
|
||||
const Data::AssetId& modelAssetId,
|
||||
const Data::AssetId& materialAssetId,
|
||||
const Data::AssetId& lightingPresetAssetId,
|
||||
const Render::MaterialPropertyOverrideMap& materialPropertyOverrides)
|
||||
: m_scene(scene)
|
||||
, m_view(view)
|
||||
, m_entityContextId(entityContextId)
|
||||
, m_materialPropertyOverrides(materialPropertyOverrides)
|
||||
{
|
||||
// Create preview model
|
||||
AzFramework::EntityContextRequestBus::EventResult(
|
||||
m_modelEntity, m_entityContextId, &AzFramework::EntityContextRequestBus::Events::CreateEntity, "SharedPreviewContentModel");
|
||||
m_modelEntity->CreateComponent(Render::MeshComponentTypeId);
|
||||
m_modelEntity->CreateComponent(Render::MaterialComponentTypeId);
|
||||
m_modelEntity->CreateComponent(azrtti_typeid<AzFramework::TransformComponent>());
|
||||
m_modelEntity->Init();
|
||||
m_modelEntity->Activate();
|
||||
|
||||
m_modelAsset.Create(modelAssetId);
|
||||
m_materialAsset.Create(materialAssetId);
|
||||
m_lightingPresetAsset.Create(lightingPresetAssetId);
|
||||
}
|
||||
|
||||
SharedPreviewContent::~SharedPreviewContent()
|
||||
{
|
||||
if (m_modelEntity)
|
||||
{
|
||||
m_modelEntity->Deactivate();
|
||||
AzFramework::EntityContextRequestBus::Event(
|
||||
m_entityContextId, &AzFramework::EntityContextRequestBus::Events::DestroyEntity, m_modelEntity);
|
||||
m_modelEntity = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void SharedPreviewContent::Load()
|
||||
{
|
||||
m_modelAsset.QueueLoad();
|
||||
m_materialAsset.QueueLoad();
|
||||
m_lightingPresetAsset.QueueLoad();
|
||||
}
|
||||
|
||||
bool SharedPreviewContent::IsReady() const
|
||||
{
|
||||
return (!m_modelAsset.GetId().IsValid() || m_modelAsset.IsReady()) &&
|
||||
(!m_materialAsset.GetId().IsValid() || m_materialAsset.IsReady()) &&
|
||||
(!m_lightingPresetAsset.GetId().IsValid() || m_lightingPresetAsset.IsReady());
|
||||
}
|
||||
|
||||
bool SharedPreviewContent::IsError() const
|
||||
{
|
||||
return m_modelAsset.IsError() || m_materialAsset.IsError() || m_lightingPresetAsset.IsError();
|
||||
}
|
||||
|
||||
void SharedPreviewContent::ReportErrors()
|
||||
{
|
||||
AZ_Warning(
|
||||
"SharedPreviewContent", !m_modelAsset.GetId().IsValid() || m_modelAsset.IsReady(), "Asset failed to load in time: %s",
|
||||
m_modelAsset.ToString<AZStd::string>().c_str());
|
||||
AZ_Warning(
|
||||
"SharedPreviewContent", !m_materialAsset.GetId().IsValid() || m_materialAsset.IsReady(), "Asset failed to load in time: %s",
|
||||
m_materialAsset.ToString<AZStd::string>().c_str());
|
||||
AZ_Warning(
|
||||
"SharedPreviewContent", !m_lightingPresetAsset.GetId().IsValid() || m_lightingPresetAsset.IsReady(),
|
||||
"Asset failed to load in time: %s", m_lightingPresetAsset.ToString<AZStd::string>().c_str());
|
||||
}
|
||||
|
||||
void SharedPreviewContent::Update()
|
||||
{
|
||||
UpdateModel();
|
||||
UpdateLighting();
|
||||
UpdateCamera();
|
||||
}
|
||||
|
||||
void SharedPreviewContent::UpdateModel()
|
||||
{
|
||||
Render::MeshComponentRequestBus::Event(
|
||||
m_modelEntity->GetId(), &Render::MeshComponentRequestBus::Events::SetModelAsset, m_modelAsset);
|
||||
|
||||
Render::MaterialComponentRequestBus::Event(
|
||||
m_modelEntity->GetId(), &Render::MaterialComponentRequestBus::Events::SetMaterialOverride,
|
||||
Render::DefaultMaterialAssignmentId, m_materialAsset.GetId());
|
||||
|
||||
Render::MaterialComponentRequestBus::Event(
|
||||
m_modelEntity->GetId(), &Render::MaterialComponentRequestBus::Events::SetPropertyOverrides,
|
||||
Render::DefaultMaterialAssignmentId, m_materialPropertyOverrides);
|
||||
}
|
||||
|
||||
void SharedPreviewContent::UpdateLighting()
|
||||
{
|
||||
if (m_lightingPresetAsset.IsReady())
|
||||
{
|
||||
auto preset = m_lightingPresetAsset->GetDataAs<Render::LightingPreset>();
|
||||
if (preset)
|
||||
{
|
||||
auto iblFeatureProcessor = m_scene->GetFeatureProcessor<Render::ImageBasedLightFeatureProcessorInterface>();
|
||||
auto postProcessFeatureProcessor = m_scene->GetFeatureProcessor<Render::PostProcessFeatureProcessorInterface>();
|
||||
auto postProcessSettingInterface = postProcessFeatureProcessor->GetOrCreateSettingsInterface(EntityId());
|
||||
auto exposureControlSettingInterface = postProcessSettingInterface->GetOrCreateExposureControlSettingsInterface();
|
||||
auto directionalLightFeatureProcessor =
|
||||
m_scene->GetFeatureProcessor<Render::DirectionalLightFeatureProcessorInterface>();
|
||||
auto skyboxFeatureProcessor = m_scene->GetFeatureProcessor<Render::SkyBoxFeatureProcessorInterface>();
|
||||
skyboxFeatureProcessor->Enable(true);
|
||||
skyboxFeatureProcessor->SetSkyboxMode(Render::SkyBoxMode::Cubemap);
|
||||
|
||||
Camera::Configuration cameraConfig;
|
||||
cameraConfig.m_fovRadians = FieldOfView;
|
||||
cameraConfig.m_nearClipDistance = NearDist;
|
||||
cameraConfig.m_farClipDistance = FarDist;
|
||||
cameraConfig.m_frustumWidth = 100.0f;
|
||||
cameraConfig.m_frustumHeight = 100.0f;
|
||||
|
||||
AZStd::vector<Render::DirectionalLightFeatureProcessorInterface::LightHandle> lightHandles;
|
||||
|
||||
preset->ApplyLightingPreset(
|
||||
iblFeatureProcessor, skyboxFeatureProcessor, exposureControlSettingInterface, directionalLightFeatureProcessor,
|
||||
cameraConfig, lightHandles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SharedPreviewContent::UpdateCamera()
|
||||
{
|
||||
// Get bounding sphere of the model asset and estimate how far the camera needs to be see all of it
|
||||
Vector3 center = {};
|
||||
float radius = {};
|
||||
if (m_modelAsset.IsReady())
|
||||
{
|
||||
m_modelAsset->GetAabb().GetAsSphere(center, radius);
|
||||
}
|
||||
|
||||
const auto distance = radius + NearDist;
|
||||
const auto cameraRotation = Quaternion::CreateFromAxisAngle(Vector3::CreateAxisZ(), CameraRotationAngle);
|
||||
const auto cameraPosition = center + cameraRotation.TransformVector(Vector3(0.0f, distance, 0.0f));
|
||||
const auto cameraTransform = Transform::CreateLookAt(cameraPosition, center);
|
||||
m_view->SetCameraTransform(Matrix3x4::CreateFromTransform(cameraTransform));
|
||||
}
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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/MaterialAssignment.h>
|
||||
#include <Atom/RPI.Public/Base.h>
|
||||
#include <Atom/RPI.Reflect/Material/MaterialAsset.h>
|
||||
#include <Atom/RPI.Reflect/Model/ModelAsset.h>
|
||||
#include <Atom/RPI.Reflect/System/AnyAsset.h>
|
||||
#include <AtomToolsFramework/PreviewRenderer/PreviewContent.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace LyIntegration
|
||||
{
|
||||
//! Creates a simple scene used for most previews and thumbnails
|
||||
class SharedPreviewContent final : public AtomToolsFramework::PreviewContent
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(SharedPreviewContent, AZ::SystemAllocator, 0);
|
||||
|
||||
SharedPreviewContent(
|
||||
RPI::ScenePtr scene,
|
||||
RPI::ViewPtr view,
|
||||
AZ::Uuid entityContextId,
|
||||
const Data::AssetId& modelAssetId,
|
||||
const Data::AssetId& materialAssetId,
|
||||
const Data::AssetId& lightingPresetAssetId,
|
||||
const Render::MaterialPropertyOverrideMap& materialPropertyOverrides);
|
||||
|
||||
~SharedPreviewContent() override;
|
||||
|
||||
void Load() override;
|
||||
bool IsReady() const override;
|
||||
bool IsError() const override;
|
||||
void ReportErrors() override;
|
||||
void Update() override;
|
||||
|
||||
private:
|
||||
void UpdateModel();
|
||||
void UpdateLighting();
|
||||
void UpdateCamera();
|
||||
|
||||
static constexpr float AspectRatio = 1.0f;
|
||||
static constexpr float NearDist = 0.001f;
|
||||
static constexpr float FarDist = 100.0f;
|
||||
static constexpr float FieldOfView = Constants::HalfPi;
|
||||
static constexpr float CameraRotationAngle = Constants::QuarterPi / 2.0f;
|
||||
|
||||
RPI::ScenePtr m_scene;
|
||||
RPI::ViewPtr m_view;
|
||||
AZ::Uuid m_entityContextId;
|
||||
Entity* m_modelEntity = nullptr;
|
||||
|
||||
Data::Asset<RPI::ModelAsset> m_modelAsset;
|
||||
Data::Asset<RPI::MaterialAsset> m_materialAsset;
|
||||
Data::Asset<RPI::AnyAsset> m_lightingPresetAsset;
|
||||
Render::MaterialPropertyOverrideMap m_materialPropertyOverrides;
|
||||
};
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
+42
-12
@@ -11,37 +11,42 @@
|
||||
#include <AssetBrowser/Thumbnails/SourceThumbnail.h>
|
||||
#include <Atom/RPI.Reflect/Material/MaterialAsset.h>
|
||||
#include <Atom/RPI.Reflect/Model/ModelAsset.h>
|
||||
#include <Thumbnails/ThumbnailUtils.h>
|
||||
#include <Atom/RPI.Reflect/System/AnyAsset.h>
|
||||
#include <SharedPreview/SharedPreviewUtils.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace LyIntegration
|
||||
{
|
||||
namespace Thumbnails
|
||||
namespace SharedPreviewUtils
|
||||
{
|
||||
Data::AssetId GetAssetId(AzToolsFramework::Thumbnailer::SharedThumbnailKey key, const Data::AssetType& assetType)
|
||||
Data::AssetId GetAssetId(
|
||||
AzToolsFramework::Thumbnailer::SharedThumbnailKey key,
|
||||
const Data::AssetType& assetType,
|
||||
const Data::AssetId& defaultAssetId)
|
||||
{
|
||||
static const Data::AssetId invalidAssetId;
|
||||
|
||||
// if it's a source thumbnail key, find first product with a matching asset type
|
||||
auto sourceKey = azrtti_cast<const AzToolsFramework::AssetBrowser::SourceThumbnailKey*>(key.data());
|
||||
if (sourceKey)
|
||||
{
|
||||
bool foundIt = false;
|
||||
AZStd::vector<Data::AssetInfo> productsAssetInfo;
|
||||
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(foundIt, &AzToolsFramework::AssetSystemRequestBus::Events::GetAssetsProducedBySourceUUID, sourceKey->GetSourceUuid(), productsAssetInfo);
|
||||
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(
|
||||
foundIt, &AzToolsFramework::AssetSystemRequestBus::Events::GetAssetsProducedBySourceUUID,
|
||||
sourceKey->GetSourceUuid(), productsAssetInfo);
|
||||
if (!foundIt)
|
||||
{
|
||||
return invalidAssetId;
|
||||
return defaultAssetId;
|
||||
}
|
||||
auto assetInfoIt = AZStd::find_if(productsAssetInfo.begin(), productsAssetInfo.end(),
|
||||
auto assetInfoIt = AZStd::find_if(
|
||||
productsAssetInfo.begin(), productsAssetInfo.end(),
|
||||
[&assetType](const Data::AssetInfo& assetInfo)
|
||||
{
|
||||
return assetInfo.m_assetType == assetType;
|
||||
});
|
||||
if (assetInfoIt == productsAssetInfo.end())
|
||||
{
|
||||
return invalidAssetId;
|
||||
return defaultAssetId;
|
||||
}
|
||||
|
||||
return assetInfoIt->m_assetId;
|
||||
@@ -53,10 +58,9 @@ namespace AZ
|
||||
{
|
||||
return productKey->GetAssetId();
|
||||
}
|
||||
return invalidAssetId;
|
||||
return defaultAssetId;
|
||||
}
|
||||
|
||||
|
||||
QString WordWrap(const QString& string, int maxLength)
|
||||
{
|
||||
QString result;
|
||||
@@ -81,6 +85,32 @@ namespace AZ
|
||||
}
|
||||
return result;
|
||||
}
|
||||
} // namespace Thumbnails
|
||||
|
||||
AZStd::unordered_set<AZ::Uuid> GetSupportedAssetTypes()
|
||||
{
|
||||
return { RPI::AnyAsset::RTTI_Type(), RPI::MaterialAsset::RTTI_Type(), RPI::ModelAsset::RTTI_Type() };
|
||||
}
|
||||
|
||||
bool IsSupportedAssetType(AzToolsFramework::Thumbnailer::SharedThumbnailKey key)
|
||||
{
|
||||
for (const AZ::Uuid& typeId : SharedPreviewUtils::GetSupportedAssetTypes())
|
||||
{
|
||||
const AZ::Data::AssetId& assetId = SharedPreviewUtils::GetAssetId(key, typeId);
|
||||
if (assetId.IsValid())
|
||||
{
|
||||
if (typeId == RPI::AnyAsset::RTTI_Type())
|
||||
{
|
||||
AZ::Data::AssetInfo assetInfo;
|
||||
AZ::Data::AssetCatalogRequestBus::BroadcastResult(
|
||||
assetInfo, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetInfoById, assetId);
|
||||
return AzFramework::StringFunc::EndsWith(assetInfo.m_relativePath.c_str(), "lightingpreset.azasset");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
} // namespace SharedPreviewUtils
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
+14
-4
@@ -18,13 +18,23 @@ namespace AZ
|
||||
{
|
||||
namespace LyIntegration
|
||||
{
|
||||
namespace Thumbnails
|
||||
namespace SharedPreviewUtils
|
||||
{
|
||||
//! Get assetId by assetType that belongs to either source or product thumbnail key
|
||||
Data::AssetId GetAssetId(AzToolsFramework::Thumbnailer::SharedThumbnailKey key, const Data::AssetType& assetType);
|
||||
Data::AssetId GetAssetId(
|
||||
AzToolsFramework::Thumbnailer::SharedThumbnailKey key,
|
||||
const Data::AssetType& assetType,
|
||||
const Data::AssetId& defaultAssetId = {});
|
||||
|
||||
//! Word wrap function for previewer QLabel, since by default it does not break long words such as filenames, so manual word wrap needed
|
||||
//! Word wrap function for previewer QLabel, since by default it does not break long words such as filenames, so manual word
|
||||
//! wrap needed
|
||||
QString WordWrap(const QString& string, int maxLength);
|
||||
} // namespace Thumbnails
|
||||
|
||||
//! Get the set of all asset types supported by the shared preview
|
||||
AZStd::unordered_set<AZ::Uuid> GetSupportedAssetTypes();
|
||||
|
||||
//! Determine if a thumbnail key has an asset supported by the shared preview
|
||||
bool IsSupportedAssetType(AzToolsFramework::Thumbnailer::SharedThumbnailKey key);
|
||||
} // namespace SharedPreviewUtils
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
+20
-18
@@ -7,23 +7,21 @@
|
||||
*/
|
||||
|
||||
#include <AzCore/IO/FileIO.h>
|
||||
|
||||
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
|
||||
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
|
||||
#include <AzToolsFramework/AssetBrowser/AssetBrowserEntry.h>
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailContext.h>
|
||||
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
|
||||
#include <AzToolsFramework/Thumbnails/Thumbnail.h>
|
||||
|
||||
#include <Source/Thumbnails/Preview/CommonPreviewer.h>
|
||||
#include <Source/Thumbnails/ThumbnailUtils.h>
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailContext.h>
|
||||
#include <SharedPreview/SharedPreviewUtils.h>
|
||||
#include <SharedPreview/SharedPreviewer.h>
|
||||
|
||||
// Disables warning messages triggered by the Qt library
|
||||
// 4251: class needs to have dll-interface to be used by clients of class
|
||||
// 4251: class needs to have dll-interface to be used by clients of class
|
||||
// 4800: forcing value to bool 'true' or 'false' (performance warning)
|
||||
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option")
|
||||
#include <Source/Thumbnails/Preview/ui_CommonPreviewer.h>
|
||||
#include <QString>
|
||||
#include <QResizeEvent>
|
||||
#include <QString>
|
||||
#include <SharedPreview/ui_SharedPreviewer.h>
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
namespace AZ
|
||||
@@ -32,18 +30,22 @@ namespace AZ
|
||||
{
|
||||
static constexpr int CharWidth = 6;
|
||||
|
||||
CommonPreviewer::CommonPreviewer(QWidget* parent)
|
||||
SharedPreviewer::SharedPreviewer(QWidget* parent)
|
||||
: Previewer(parent)
|
||||
, m_ui(new Ui::CommonPreviewerClass())
|
||||
, m_ui(new Ui::SharedPreviewerClass())
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
}
|
||||
|
||||
CommonPreviewer::~CommonPreviewer()
|
||||
SharedPreviewer::~SharedPreviewer()
|
||||
{
|
||||
}
|
||||
|
||||
void CommonPreviewer::Display(const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry)
|
||||
void SharedPreviewer::Clear() const
|
||||
{
|
||||
}
|
||||
|
||||
void SharedPreviewer::Display(const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry)
|
||||
{
|
||||
using namespace AzToolsFramework::AssetBrowser;
|
||||
using namespace AzToolsFramework::Thumbnailer;
|
||||
@@ -54,23 +56,23 @@ namespace AZ
|
||||
UpdateFileInfo();
|
||||
}
|
||||
|
||||
const QString& CommonPreviewer::GetName() const
|
||||
const QString& SharedPreviewer::GetName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void CommonPreviewer::resizeEvent([[maybe_unused]] QResizeEvent* event)
|
||||
void SharedPreviewer::resizeEvent([[maybe_unused]] QResizeEvent* event)
|
||||
{
|
||||
m_ui->m_previewWidget->setMaximumHeight(m_ui->m_previewWidget->width());
|
||||
|
||||
UpdateFileInfo();
|
||||
}
|
||||
|
||||
void CommonPreviewer::UpdateFileInfo() const
|
||||
void SharedPreviewer::UpdateFileInfo() const
|
||||
{
|
||||
m_ui->m_fileInfoLabel->setText(Thumbnails::WordWrap(m_fileInfo, m_ui->m_fileInfoLabel->width() / CharWidth));
|
||||
m_ui->m_fileInfoLabel->setText(SharedPreviewUtils::WordWrap(m_fileInfo, m_ui->m_fileInfoLabel->width() / CharWidth));
|
||||
}
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
|
||||
#include <Source/Thumbnails/Preview/moc_CommonPreviewer.cpp>
|
||||
#include <SharedPreview/moc_SharedPreviewer.cpp>
|
||||
+13
-13
@@ -5,22 +5,23 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzToolsFramework/AssetBrowser/Previewer/Previewer.h>
|
||||
|
||||
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT
|
||||
#include <QWidget>
|
||||
#include <QScopedPointer>
|
||||
#include <QWidget>
|
||||
AZ_POP_DISABLE_WARNING
|
||||
#endif
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class CommonPreviewerClass;
|
||||
class SharedPreviewerClass;
|
||||
}
|
||||
|
||||
namespace AzToolsFramework
|
||||
@@ -30,8 +31,8 @@ namespace AzToolsFramework
|
||||
class ProductAssetBrowserEntry;
|
||||
class SourceAssetBrowserEntry;
|
||||
class AssetBrowserEntry;
|
||||
}
|
||||
}
|
||||
} // namespace AssetBrowser
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
class QResizeEvent;
|
||||
|
||||
@@ -39,18 +40,17 @@ namespace AZ
|
||||
{
|
||||
namespace LyIntegration
|
||||
{
|
||||
class CommonPreviewer final
|
||||
: public AzToolsFramework::AssetBrowser::Previewer
|
||||
class SharedPreviewer final : public AzToolsFramework::AssetBrowser::Previewer
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(CommonPreviewer, AZ::SystemAllocator, 0);
|
||||
AZ_CLASS_ALLOCATOR(SharedPreviewer, AZ::SystemAllocator, 0);
|
||||
|
||||
explicit CommonPreviewer(QWidget* parent = nullptr);
|
||||
~CommonPreviewer();
|
||||
explicit SharedPreviewer(QWidget* parent = nullptr);
|
||||
~SharedPreviewer();
|
||||
|
||||
// AzToolsFramework::AssetBrowser::Previewer overrides...
|
||||
void Clear() const override {}
|
||||
void Clear() const override;
|
||||
void Display(const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry) override;
|
||||
const QString& GetName() const override;
|
||||
|
||||
@@ -60,9 +60,9 @@ namespace AZ
|
||||
private:
|
||||
void UpdateFileInfo() const;
|
||||
|
||||
QScopedPointer<Ui::CommonPreviewerClass> m_ui;
|
||||
QScopedPointer<Ui::SharedPreviewerClass> m_ui;
|
||||
QString m_fileInfo;
|
||||
QString m_name = "CommonPreviewer";
|
||||
QString m_name = "SharedPreviewer";
|
||||
};
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CommonPreviewerClass</class>
|
||||
<widget class="QWidget" name="CommonPreviewerClass">
|
||||
<class>SharedPreviewerClass</class>
|
||||
<widget class="QWidget" name="SharedPreviewerClass">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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 <AzToolsFramework/AssetBrowser/AssetBrowserEntry.h>
|
||||
#include <SharedPreview/SharedPreviewUtils.h>
|
||||
#include <SharedPreview/SharedPreviewer.h>
|
||||
#include <SharedPreview/SharedPreviewerFactory.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace LyIntegration
|
||||
{
|
||||
AzToolsFramework::AssetBrowser::Previewer* SharedPreviewerFactory::CreatePreviewer(QWidget* parent) const
|
||||
{
|
||||
return new SharedPreviewer(parent);
|
||||
}
|
||||
|
||||
bool SharedPreviewerFactory::IsEntrySupported(const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry) const
|
||||
{
|
||||
return SharedPreviewUtils::IsSupportedAssetType(entry->GetThumbnailKey());
|
||||
}
|
||||
|
||||
const QString& SharedPreviewerFactory::GetName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
+6
-6
@@ -5,6 +5,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
@@ -18,14 +19,13 @@ namespace AZ
|
||||
{
|
||||
namespace LyIntegration
|
||||
{
|
||||
class CommonPreviewerFactory final
|
||||
: public AzToolsFramework::AssetBrowser::PreviewerFactory
|
||||
class SharedPreviewerFactory final : public AzToolsFramework::AssetBrowser::PreviewerFactory
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(CommonPreviewerFactory, AZ::SystemAllocator, 0);
|
||||
AZ_CLASS_ALLOCATOR(SharedPreviewerFactory, AZ::SystemAllocator, 0);
|
||||
|
||||
CommonPreviewerFactory() = default;
|
||||
~CommonPreviewerFactory() = default;
|
||||
SharedPreviewerFactory() = default;
|
||||
~SharedPreviewerFactory() = default;
|
||||
|
||||
// AzToolsFramework::AssetBrowser::PreviewerFactory overrides...
|
||||
AzToolsFramework::AssetBrowser::Previewer* CreatePreviewer(QWidget* parent = nullptr) const override;
|
||||
@@ -33,7 +33,7 @@ namespace AZ
|
||||
const QString& GetName() const override;
|
||||
|
||||
private:
|
||||
QString m_name = "CommonPreviewer";
|
||||
QString m_name = "SharedPreviewer";
|
||||
};
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* 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 <AzToolsFramework/API/EditorAssetSystemAPI.h>
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
#include <SharedPreview/SharedPreviewUtils.h>
|
||||
#include <SharedPreview/SharedThumbnail.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace LyIntegration
|
||||
{
|
||||
static constexpr const int SharedThumbnailSize = 256;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// SharedThumbnail
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
SharedThumbnail::SharedThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey key)
|
||||
: Thumbnail(key)
|
||||
{
|
||||
for (const AZ::Uuid& typeId : SharedPreviewUtils::GetSupportedAssetTypes())
|
||||
{
|
||||
const AZ::Data::AssetId& assetId = SharedPreviewUtils::GetAssetId(key, typeId);
|
||||
if (assetId.IsValid())
|
||||
{
|
||||
m_assetId = assetId;
|
||||
m_typeId = typeId;
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Handler::BusConnect(key);
|
||||
AzFramework::AssetCatalogEventBus::Handler::BusConnect();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
AZ_Error("SharedThumbnail", false, "Failed to find matching assetId for the thumbnailKey.");
|
||||
m_state = State::Failed;
|
||||
}
|
||||
|
||||
void SharedThumbnail::LoadThread()
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::QueueEvent(
|
||||
m_typeId, &AzToolsFramework::Thumbnailer::ThumbnailerRendererRequests::RenderThumbnail, m_key, SharedThumbnailSize);
|
||||
// wait for response from thumbnail renderer
|
||||
m_renderWait.acquire();
|
||||
}
|
||||
|
||||
SharedThumbnail::~SharedThumbnail()
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Handler::BusDisconnect();
|
||||
AzFramework::AssetCatalogEventBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
void SharedThumbnail::ThumbnailRendered(const QPixmap& thumbnailImage)
|
||||
{
|
||||
m_pixmap = thumbnailImage;
|
||||
m_renderWait.release();
|
||||
}
|
||||
|
||||
void SharedThumbnail::ThumbnailFailedToRender()
|
||||
{
|
||||
m_state = State::Failed;
|
||||
m_renderWait.release();
|
||||
}
|
||||
|
||||
void SharedThumbnail::OnCatalogAssetChanged([[maybe_unused]] const AZ::Data::AssetId& assetId)
|
||||
{
|
||||
if (m_assetId == assetId && m_state == State::Ready)
|
||||
{
|
||||
m_state = State::Unloaded;
|
||||
Load();
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// SharedThumbnailCache
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
SharedThumbnailCache::SharedThumbnailCache()
|
||||
: ThumbnailCache<SharedThumbnail>()
|
||||
{
|
||||
}
|
||||
|
||||
SharedThumbnailCache::~SharedThumbnailCache() = default;
|
||||
|
||||
int SharedThumbnailCache::GetPriority() const
|
||||
{
|
||||
// Custom thumbnails have a higher priority to override default source thumbnails
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char* SharedThumbnailCache::GetProviderName() const
|
||||
{
|
||||
return ProviderName;
|
||||
}
|
||||
|
||||
bool SharedThumbnailCache::IsSupportedThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey key) const
|
||||
{
|
||||
return SharedPreviewUtils::IsSupportedAssetType(key);
|
||||
}
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
|
||||
#include <SharedPreview/moc_SharedThumbnail.cpp>
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <AzCore/std/parallel/binary_semaphore.h>
|
||||
#include <AzFramework/Asset/AssetCatalogBus.h>
|
||||
#include <AzToolsFramework/Thumbnails/Thumbnail.h>
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailerBus.h>
|
||||
#endif
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace LyIntegration
|
||||
{
|
||||
//! Custom thumbnail for most common Atom assets
|
||||
//! Detects asset changes and updates the thumbnail
|
||||
class SharedThumbnail final
|
||||
: public AzToolsFramework::Thumbnailer::Thumbnail
|
||||
, public AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Handler
|
||||
, private AzFramework::AssetCatalogEventBus::Handler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SharedThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey key);
|
||||
~SharedThumbnail() override;
|
||||
|
||||
//! AzToolsFramework::ThumbnailerRendererNotificationBus::Handler overrides...
|
||||
void ThumbnailRendered(const QPixmap& thumbnailImage) override;
|
||||
void ThumbnailFailedToRender() override;
|
||||
|
||||
protected:
|
||||
void LoadThread() override;
|
||||
|
||||
private:
|
||||
// AzFramework::AssetCatalogEventBus::Handler interface overrides...
|
||||
void OnCatalogAssetChanged(const AZ::Data::AssetId& assetId) override;
|
||||
|
||||
AZStd::binary_semaphore m_renderWait;
|
||||
Data::AssetId m_assetId;
|
||||
AZ::Uuid m_typeId;
|
||||
};
|
||||
|
||||
//! Cache configuration for shared thumbnails
|
||||
class SharedThumbnailCache final : public AzToolsFramework::Thumbnailer::ThumbnailCache<SharedThumbnail>
|
||||
{
|
||||
public:
|
||||
SharedThumbnailCache();
|
||||
~SharedThumbnailCache() override;
|
||||
|
||||
int GetPriority() const override;
|
||||
const char* GetProviderName() const override;
|
||||
|
||||
static constexpr const char* ProviderName = "Common Feature Shared Thumbnail Provider";
|
||||
|
||||
protected:
|
||||
bool IsSupportedThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey key) const override;
|
||||
};
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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 <AtomToolsFramework/PreviewRenderer/PreviewRendererCaptureRequest.h>
|
||||
#include <AtomToolsFramework/PreviewRenderer/PreviewRendererInterface.h>
|
||||
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailerBus.h>
|
||||
#include <SharedPreview/SharedPreviewContent.h>
|
||||
#include <SharedPreview/SharedPreviewUtils.h>
|
||||
#include <SharedPreview/SharedThumbnailRenderer.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace LyIntegration
|
||||
{
|
||||
SharedThumbnailRenderer::SharedThumbnailRenderer()
|
||||
{
|
||||
m_defaultModelAsset.Create(DefaultModelAssetId, true);
|
||||
m_defaultMaterialAsset.Create(DefaultMaterialAssetId, true);
|
||||
m_defaultLightingPresetAsset.Create(DefaultLightingPresetAssetId, true);
|
||||
|
||||
for (const AZ::Uuid& typeId : SharedPreviewUtils::GetSupportedAssetTypes())
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::MultiHandler::BusConnect(typeId);
|
||||
}
|
||||
SystemTickBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
SharedThumbnailRenderer::~SharedThumbnailRenderer()
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::MultiHandler::BusDisconnect();
|
||||
SystemTickBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
void SharedThumbnailRenderer::RenderThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey thumbnailKey, int thumbnailSize)
|
||||
{
|
||||
if (auto previewRenderer = AZ::Interface<AtomToolsFramework::PreviewRendererInterface>::Get())
|
||||
{
|
||||
previewRenderer->AddCaptureRequest(
|
||||
{ thumbnailSize,
|
||||
AZStd::make_shared<SharedPreviewContent>(
|
||||
previewRenderer->GetScene(), previewRenderer->GetView(), previewRenderer->GetEntityContextId(),
|
||||
SharedPreviewUtils::GetAssetId(thumbnailKey, RPI::ModelAsset::RTTI_Type(), DefaultModelAssetId),
|
||||
SharedPreviewUtils::GetAssetId(thumbnailKey, RPI::MaterialAsset::RTTI_Type(), DefaultMaterialAssetId),
|
||||
SharedPreviewUtils::GetAssetId(thumbnailKey, RPI::AnyAsset::RTTI_Type(), DefaultLightingPresetAssetId),
|
||||
Render::MaterialPropertyOverrideMap()),
|
||||
[thumbnailKey]()
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Event(
|
||||
thumbnailKey, &AzToolsFramework::Thumbnailer::ThumbnailerRendererNotifications::ThumbnailFailedToRender);
|
||||
},
|
||||
[thumbnailKey](const QPixmap& pixmap)
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Event(
|
||||
thumbnailKey, &AzToolsFramework::Thumbnailer::ThumbnailerRendererNotifications::ThumbnailRendered, pixmap);
|
||||
} });
|
||||
}
|
||||
}
|
||||
|
||||
bool SharedThumbnailRenderer::Installed() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void SharedThumbnailRenderer::OnSystemTick()
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::ExecuteQueuedEvents();
|
||||
}
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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/RPI.Reflect/Asset/AssetUtils.h>
|
||||
#include <Atom/RPI.Reflect/Material/MaterialAsset.h>
|
||||
#include <Atom/RPI.Reflect/Model/ModelAsset.h>
|
||||
#include <Atom/RPI.Reflect/System/AnyAsset.h>
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
#include <AzToolsFramework/Thumbnails/Thumbnail.h>
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailerBus.h>
|
||||
#include <Thumbnails/Thumbnail.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace LyIntegration
|
||||
{
|
||||
//! Provides custom thumbnail rendering of supported asset types
|
||||
class SharedThumbnailRenderer final
|
||||
: public AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::MultiHandler
|
||||
, public SystemTickBus::Handler
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(SharedThumbnailRenderer, AZ::SystemAllocator, 0);
|
||||
|
||||
SharedThumbnailRenderer();
|
||||
~SharedThumbnailRenderer();
|
||||
|
||||
private:
|
||||
//! ThumbnailerRendererRequestsBus::Handler interface overrides...
|
||||
void RenderThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey thumbnailKey, int thumbnailSize) override;
|
||||
bool Installed() const override;
|
||||
|
||||
//! SystemTickBus::Handler interface overrides...
|
||||
void OnSystemTick() override;
|
||||
|
||||
// Default assets to be kept loaded and used for rendering if not overridden
|
||||
static constexpr const char* DefaultLightingPresetPath = "lightingpresets/thumbnail.lightingpreset.azasset";
|
||||
const Data::AssetId DefaultLightingPresetAssetId = AZ::RPI::AssetUtils::GetAssetIdForProductPath(DefaultLightingPresetPath);
|
||||
Data::Asset<RPI::AnyAsset> m_defaultLightingPresetAsset;
|
||||
|
||||
static constexpr const char* DefaultModelPath = "models/sphere.azmodel";
|
||||
const Data::AssetId DefaultModelAssetId = AZ::RPI::AssetUtils::GetAssetIdForProductPath(DefaultModelPath);
|
||||
Data::Asset<RPI::ModelAsset> m_defaultModelAsset;
|
||||
|
||||
static constexpr const char* DefaultMaterialPath = "";
|
||||
const Data::AssetId DefaultMaterialAssetId;
|
||||
Data::Asset<RPI::MaterialAsset> m_defaultMaterialAsset;
|
||||
};
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
+1
-1
@@ -65,7 +65,7 @@ namespace AZ
|
||||
m_featureProcessorInterface = RPI::Scene::GetFeatureProcessorForEntity<SkyBoxFeatureProcessorInterface>(entityId);
|
||||
|
||||
// only activate if there is no other skybox activate
|
||||
if (!m_featureProcessorInterface->IsEnabled())
|
||||
if (m_featureProcessorInterface && !m_featureProcessorInterface->IsEnabled())
|
||||
{
|
||||
m_featureProcessorInterface->SetSkyboxMode(SkyBoxMode::Cubemap);
|
||||
m_featureProcessorInterface->Enable(true);
|
||||
|
||||
-37
@@ -1,37 +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 <AzToolsFramework/AssetBrowser/AssetBrowserEntry.h>
|
||||
#include <Atom/RPI.Reflect/Material/MaterialAsset.h>
|
||||
#include <Atom/RPI.Reflect/Model/ModelAsset.h>
|
||||
#include <Source/Thumbnails/Preview/CommonPreviewer.h>
|
||||
#include <Source/Thumbnails/Preview/CommonPreviewerFactory.h>
|
||||
#include <Source/Thumbnails/ThumbnailUtils.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace LyIntegration
|
||||
{
|
||||
AzToolsFramework::AssetBrowser::Previewer* CommonPreviewerFactory::CreatePreviewer(QWidget* parent) const
|
||||
{
|
||||
return new CommonPreviewer(parent);
|
||||
}
|
||||
|
||||
bool CommonPreviewerFactory::IsEntrySupported(const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry) const
|
||||
{
|
||||
return
|
||||
Thumbnails::GetAssetId(entry->GetThumbnailKey(), RPI::MaterialAsset::RTTI_Type()).IsValid() ||
|
||||
Thumbnails::GetAssetId(entry->GetThumbnailKey(), RPI::ModelAsset::RTTI_Type()).IsValid();
|
||||
}
|
||||
|
||||
const QString& CommonPreviewerFactory::GetName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
-120
@@ -1,120 +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/RPI.Reflect/Material/MaterialAsset.h>
|
||||
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
|
||||
#include <Thumbnails/Rendering/CommonThumbnailRenderer.h>
|
||||
#include <Thumbnails/Rendering/ThumbnailRendererData.h>
|
||||
#include <Thumbnails/Rendering/ThumbnailRendererSteps/CaptureStep.h>
|
||||
#include <Thumbnails/Rendering/ThumbnailRendererSteps/FindThumbnailToRenderStep.h>
|
||||
#include <Thumbnails/Rendering/ThumbnailRendererSteps/InitializeStep.h>
|
||||
#include <Thumbnails/Rendering/ThumbnailRendererSteps/ReleaseResourcesStep.h>
|
||||
#include <Thumbnails/Rendering/ThumbnailRendererSteps/WaitForAssetsToLoadStep.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace LyIntegration
|
||||
{
|
||||
namespace Thumbnails
|
||||
{
|
||||
CommonThumbnailRenderer::CommonThumbnailRenderer()
|
||||
: m_data(new ThumbnailRendererData)
|
||||
{
|
||||
// CommonThumbnailRenderer supports both models and materials, but we connect on materialAssetType
|
||||
// since MaterialOrModelThumbnail dispatches event on materialAssetType address too
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::MultiHandler::BusConnect(RPI::MaterialAsset::RTTI_Type());
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::MultiHandler::BusConnect(RPI::ModelAsset::RTTI_Type());
|
||||
SystemTickBus::Handler::BusConnect();
|
||||
ThumbnailFeatureProcessorProviderBus::Handler::BusConnect();
|
||||
|
||||
m_steps[Step::Initialize] = AZStd::make_shared<InitializeStep>(this);
|
||||
m_steps[Step::FindThumbnailToRender] = AZStd::make_shared<FindThumbnailToRenderStep>(this);
|
||||
m_steps[Step::WaitForAssetsToLoad] = AZStd::make_shared<WaitForAssetsToLoadStep>(this);
|
||||
m_steps[Step::Capture] = AZStd::make_shared<CaptureStep>(this);
|
||||
m_steps[Step::ReleaseResources] = AZStd::make_shared<ReleaseResourcesStep>(this);
|
||||
|
||||
m_minimalFeatureProcessors =
|
||||
{
|
||||
"AZ::Render::TransformServiceFeatureProcessor",
|
||||
"AZ::Render::MeshFeatureProcessor",
|
||||
"AZ::Render::SimplePointLightFeatureProcessor",
|
||||
"AZ::Render::SimpleSpotLightFeatureProcessor",
|
||||
"AZ::Render::PointLightFeatureProcessor",
|
||||
// There is currently a bug where having multiple DirectionalLightFeatureProcessors active can result in shadow
|
||||
// flickering [ATOM-13568]
|
||||
// as well as continually rebuilding MeshDrawPackets [ATOM-13633]. Lets just disable the directional light FP for now.
|
||||
// Possibly re-enable with [GFX TODO][ATOM-13639]
|
||||
// "AZ::Render::DirectionalLightFeatureProcessor",
|
||||
"AZ::Render::DiskLightFeatureProcessor",
|
||||
"AZ::Render::CapsuleLightFeatureProcessor",
|
||||
"AZ::Render::QuadLightFeatureProcessor",
|
||||
"AZ::Render::DecalTextureArrayFeatureProcessor",
|
||||
"AZ::Render::ImageBasedLightFeatureProcessor",
|
||||
"AZ::Render::PostProcessFeatureProcessor",
|
||||
"AZ::Render::SkyBoxFeatureProcessor"
|
||||
};
|
||||
}
|
||||
|
||||
CommonThumbnailRenderer::~CommonThumbnailRenderer()
|
||||
{
|
||||
if (m_currentStep != Step::None)
|
||||
{
|
||||
CommonThumbnailRenderer::SetStep(Step::ReleaseResources);
|
||||
}
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::MultiHandler::BusDisconnect();
|
||||
SystemTickBus::Handler::BusDisconnect();
|
||||
ThumbnailFeatureProcessorProviderBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
void CommonThumbnailRenderer::SetStep(Step step)
|
||||
{
|
||||
if (m_currentStep != Step::None)
|
||||
{
|
||||
m_steps[m_currentStep]->Stop();
|
||||
}
|
||||
m_currentStep = step;
|
||||
m_steps[m_currentStep]->Start();
|
||||
}
|
||||
|
||||
Step CommonThumbnailRenderer::GetStep() const
|
||||
{
|
||||
return m_currentStep;
|
||||
}
|
||||
|
||||
bool CommonThumbnailRenderer::Installed() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void CommonThumbnailRenderer::OnSystemTick()
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::ExecuteQueuedEvents();
|
||||
}
|
||||
|
||||
const AZStd::vector<AZStd::string>& CommonThumbnailRenderer::GetCustomFeatureProcessors() const
|
||||
{
|
||||
return m_minimalFeatureProcessors;
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<ThumbnailRendererData> CommonThumbnailRenderer::GetData() const
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
void CommonThumbnailRenderer::RenderThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey thumbnailKey, int thumbnailSize)
|
||||
{
|
||||
m_data->m_thumbnailSize = thumbnailSize;
|
||||
m_data->m_thumbnailQueue.push(thumbnailKey);
|
||||
if (m_currentStep == Step::None)
|
||||
{
|
||||
SetStep(Step::Initialize);
|
||||
}
|
||||
}
|
||||
} // namespace Thumbnails
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
-69
@@ -1,69 +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 <AzToolsFramework/Thumbnails/Thumbnail.h>
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailerBus.h>
|
||||
#include <Thumbnails/Rendering/ThumbnailRendererContext.h>
|
||||
#include <Thumbnails/Rendering/ThumbnailRendererData.h>
|
||||
|
||||
#include <AtomLyIntegration/CommonFeatures/Thumbnails/ThumbnailFeatureProcessorProviderBus.h>
|
||||
|
||||
// Disables warning messages triggered by the Qt library
|
||||
// 4251: class needs to have dll-interface to be used by clients of class
|
||||
// 4800: forcing value to bool 'true' or 'false' (performance warning)
|
||||
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option")
|
||||
#include <QPixmap>
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace LyIntegration
|
||||
{
|
||||
namespace Thumbnails
|
||||
{
|
||||
class ThumbnailRendererStep;
|
||||
|
||||
//! Provides custom rendering of material and model thumbnails
|
||||
class CommonThumbnailRenderer
|
||||
: public ThumbnailRendererContext
|
||||
, private AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::MultiHandler
|
||||
, private SystemTickBus::Handler
|
||||
, private ThumbnailFeatureProcessorProviderBus::Handler
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(CommonThumbnailRenderer, AZ::SystemAllocator, 0)
|
||||
|
||||
CommonThumbnailRenderer();
|
||||
~CommonThumbnailRenderer();
|
||||
|
||||
//! ThumbnailRendererContext overrides...
|
||||
void SetStep(Step step) override;
|
||||
Step GetStep() const override;
|
||||
AZStd::shared_ptr<ThumbnailRendererData> GetData() const override;
|
||||
|
||||
private:
|
||||
//! ThumbnailerRendererRequestsBus::Handler interface overrides...
|
||||
void RenderThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey thumbnailKey, int thumbnailSize) override;
|
||||
bool Installed() const override;
|
||||
|
||||
//! SystemTickBus::Handler interface overrides...
|
||||
void OnSystemTick() override;
|
||||
|
||||
//! Render::ThumbnailFeatureProcessorProviderBus::Handler interface overrides...
|
||||
const AZStd::vector<AZStd::string>& GetCustomFeatureProcessors() const override;
|
||||
|
||||
AZStd::unordered_map<Step, AZStd::shared_ptr<ThumbnailRendererStep>> m_steps;
|
||||
Step m_currentStep = Step::None;
|
||||
AZStd::shared_ptr<ThumbnailRendererData> m_data;
|
||||
AZStd::vector<AZStd::string> m_minimalFeatureProcessors;
|
||||
};
|
||||
} // namespace Thumbnails
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
-42
@@ -1,42 +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/std/smart_ptr/shared_ptr.h>
|
||||
#include <Thumbnails/Rendering/ThumbnailRendererSteps/ThumbnailRendererStep.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace LyIntegration
|
||||
{
|
||||
namespace Thumbnails
|
||||
{
|
||||
struct ThumbnailRendererData;
|
||||
|
||||
enum class Step
|
||||
{
|
||||
None,
|
||||
Initialize,
|
||||
FindThumbnailToRender,
|
||||
WaitForAssetsToLoad,
|
||||
Capture,
|
||||
ReleaseResources
|
||||
};
|
||||
|
||||
//! An interface for ThumbnailRendererSteps to communicate with thumbnail renderer
|
||||
class ThumbnailRendererContext
|
||||
{
|
||||
public:
|
||||
virtual void SetStep(Step step) = 0;
|
||||
virtual Step GetStep() const = 0;
|
||||
virtual AZStd::shared_ptr<ThumbnailRendererData> GetData() const = 0;
|
||||
};
|
||||
} // namespace Thumbnails
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
-70
@@ -1,70 +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 "Atom/RPI.Reflect/Model/ModelAsset.h"
|
||||
|
||||
#include <Atom/RPI.Public/Base.h>
|
||||
#include <Atom/RPI.Reflect/System/AnyAsset.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/Math/Transform.h>
|
||||
#include <AzFramework/Entity/GameEntityContextComponent.h>
|
||||
#include <Thumbnails/Thumbnail.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
class Scene;
|
||||
}
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace LyIntegration
|
||||
{
|
||||
namespace Thumbnails
|
||||
{
|
||||
//! ThumbnailRendererData encapsulates all data used by thumbnail renderer and caches assets
|
||||
struct ThumbnailRendererData final
|
||||
{
|
||||
static constexpr const char* LightingPresetPath = "lightingpresets/thumbnail.lightingpreset.azasset";
|
||||
static constexpr const char* DefaultModelPath = "models/sphere.azmodel";
|
||||
static constexpr const char* DefaultMaterialPath = "materials/basic_grey.azmaterial";
|
||||
|
||||
RPI::ScenePtr m_scene;
|
||||
AZStd::string m_sceneName = "Material Thumbnail Scene";
|
||||
AZStd::string m_pipelineName = "Material Thumbnail Pipeline";
|
||||
AZStd::shared_ptr<AzFramework::Scene> m_frameworkScene;
|
||||
RPI::RenderPipelinePtr m_renderPipeline;
|
||||
AZStd::unique_ptr<AzFramework::EntityContext> m_entityContext;
|
||||
AZStd::vector<AZStd::string> m_passHierarchy;
|
||||
|
||||
RPI::ViewPtr m_view = nullptr;
|
||||
Entity* m_modelEntity = nullptr;
|
||||
|
||||
int m_thumbnailSize = 512;
|
||||
|
||||
//! Incoming thumbnail requests are appended to this queue and processed one at a time in OnTick function.
|
||||
AZStd::queue<AzToolsFramework::Thumbnailer::SharedThumbnailKey> m_thumbnailQueue;
|
||||
//! Current thumbnail key being rendered.
|
||||
AzToolsFramework::Thumbnailer::SharedThumbnailKey m_thumbnailKeyRendered;
|
||||
|
||||
Data::Asset<RPI::AnyAsset> m_lightingPresetAsset;
|
||||
|
||||
Data::Asset<RPI::ModelAsset> m_defaultModelAsset;
|
||||
//! Model asset about to be rendered
|
||||
Data::Asset<RPI::ModelAsset> m_modelAsset;
|
||||
|
||||
Data::Asset<RPI::MaterialAsset> m_defaultMaterialAsset;
|
||||
//! Material asset about to be rendered
|
||||
Data::Asset<RPI::MaterialAsset> m_materialAsset;
|
||||
|
||||
AZStd::unordered_set<Data::AssetId> m_assetsToLoad;
|
||||
};
|
||||
} // namespace Thumbnails
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
-130
@@ -1,130 +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/Feature/Utils/FrameCaptureBus.h>
|
||||
#include <Atom/RPI.Public/RenderPipeline.h>
|
||||
#include <Atom/RPI.Public/RPISystemInterface.h>
|
||||
#include <Atom/RPI.Public/View.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/Material/MaterialComponentBus.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/Mesh/MeshComponentBus.h>
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailerBus.h>
|
||||
#include <Thumbnails/Rendering/ThumbnailRendererContext.h>
|
||||
#include <Thumbnails/Rendering/ThumbnailRendererData.h>
|
||||
#include <Thumbnails/Rendering/ThumbnailRendererSteps/CaptureStep.h>
|
||||
#include <AzCore/Math/MatrixUtils.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace LyIntegration
|
||||
{
|
||||
namespace Thumbnails
|
||||
{
|
||||
CaptureStep::CaptureStep(ThumbnailRendererContext* context)
|
||||
: ThumbnailRendererStep(context)
|
||||
{
|
||||
}
|
||||
|
||||
void CaptureStep::Start()
|
||||
{
|
||||
if (!m_context->GetData()->m_materialAsset ||
|
||||
!m_context->GetData()->m_modelAsset)
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Event(
|
||||
m_context->GetData()->m_thumbnailKeyRendered,
|
||||
&AzToolsFramework::Thumbnailer::ThumbnailerRendererNotifications::ThumbnailFailedToRender);
|
||||
m_context->SetStep(Step::FindThumbnailToRender);
|
||||
return;
|
||||
}
|
||||
Render::MaterialComponentRequestBus::Event(
|
||||
m_context->GetData()->m_modelEntity->GetId(),
|
||||
&Render::MaterialComponentRequestBus::Events::SetDefaultMaterialOverride,
|
||||
m_context->GetData()->m_materialAsset.GetId());
|
||||
Render::MeshComponentRequestBus::Event(
|
||||
m_context->GetData()->m_modelEntity->GetId(),
|
||||
&Render::MeshComponentRequestBus::Events::SetModelAsset,
|
||||
m_context->GetData()->m_modelAsset);
|
||||
RepositionCamera();
|
||||
m_readyToCapture = true;
|
||||
m_ticksToCapture = 1;
|
||||
TickBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
void CaptureStep::Stop()
|
||||
{
|
||||
m_context->GetData()->m_renderPipeline->RemoveFromRenderTick();
|
||||
TickBus::Handler::BusDisconnect();
|
||||
Render::FrameCaptureNotificationBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
void CaptureStep::RepositionCamera() const
|
||||
{
|
||||
// Get bounding sphere of the model asset and estimate how far the camera needs to be see all of it
|
||||
const Aabb& aabb = m_context->GetData()->m_modelAsset->GetAabb();
|
||||
Vector3 modelCenter;
|
||||
float radius;
|
||||
aabb.GetAsSphere(modelCenter, radius);
|
||||
|
||||
float distance = StartingDistanceMultiplier *
|
||||
GetMax(GetMax(aabb.GetExtents().GetX(), aabb.GetExtents().GetY()), aabb.GetExtents().GetZ()) +
|
||||
DepthNear;
|
||||
const Quaternion cameraRotation = Quaternion::CreateFromAxisAngle(Vector3::CreateAxisZ(), StartingRotationAngle);
|
||||
Vector3 cameraPosition(modelCenter.GetX(), modelCenter.GetY() - distance, modelCenter.GetZ());
|
||||
cameraPosition = cameraRotation.TransformVector(cameraPosition);
|
||||
auto cameraTransform = Transform::CreateFromQuaternionAndTranslation(cameraRotation, cameraPosition);
|
||||
m_context->GetData()->m_view->SetCameraTransform(Matrix3x4::CreateFromTransform(cameraTransform));
|
||||
}
|
||||
|
||||
void CaptureStep::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] ScriptTimePoint time)
|
||||
{
|
||||
if (m_readyToCapture && m_ticksToCapture-- <= 0)
|
||||
{
|
||||
m_context->GetData()->m_renderPipeline->AddToRenderTickOnce();
|
||||
|
||||
RPI::AttachmentReadback::CallbackFunction readbackCallback = [&](const RPI::AttachmentReadback::ReadbackResult& result)
|
||||
{
|
||||
if (!result.m_dataBuffer)
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Event(
|
||||
m_context->GetData()->m_thumbnailKeyRendered,
|
||||
&AzToolsFramework::Thumbnailer::ThumbnailerRendererNotifications::ThumbnailFailedToRender);
|
||||
return;
|
||||
}
|
||||
uchar* data = result.m_dataBuffer.get()->data();
|
||||
QImage image(
|
||||
data, result.m_imageDescriptor.m_size.m_width, result.m_imageDescriptor.m_size.m_height, QImage::Format_RGBA8888);
|
||||
QPixmap pixmap;
|
||||
pixmap.convertFromImage(image);
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Event(
|
||||
m_context->GetData()->m_thumbnailKeyRendered,
|
||||
&AzToolsFramework::Thumbnailer::ThumbnailerRendererNotifications::ThumbnailRendered,
|
||||
pixmap);
|
||||
};
|
||||
|
||||
Render::FrameCaptureNotificationBus::Handler::BusConnect();
|
||||
bool startedCapture = false;
|
||||
Render::FrameCaptureRequestBus::BroadcastResult(
|
||||
startedCapture,
|
||||
&Render::FrameCaptureRequestBus::Events::CapturePassAttachmentWithCallback,
|
||||
m_context->GetData()->m_passHierarchy, AZStd::string("Output"), readbackCallback, RPI::PassAttachmentReadbackOption::Output);
|
||||
// Reset the capture flag if the capture request was successful. Otherwise try capture it again next tick.
|
||||
if (startedCapture)
|
||||
{
|
||||
m_readyToCapture = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CaptureStep::OnCaptureFinished([[maybe_unused]] Render::FrameCaptureResult result, [[maybe_unused]] const AZStd::string& info)
|
||||
{
|
||||
m_context->SetStep(Step::FindThumbnailToRender);
|
||||
}
|
||||
} // namespace Thumbnails
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
-55
@@ -1,55 +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 <Atom/Feature/Utils/FrameCaptureBus.h>
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
#include <Thumbnails/Rendering/ThumbnailRendererSteps/ThumbnailRendererStep.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace LyIntegration
|
||||
{
|
||||
namespace Thumbnails
|
||||
{
|
||||
//! CaptureStep renders a thumbnail to a pixmap and notifies MaterialOrModelThumbnail once finished
|
||||
class CaptureStep
|
||||
: public ThumbnailRendererStep
|
||||
, private TickBus::Handler
|
||||
, private Render::FrameCaptureNotificationBus::Handler
|
||||
{
|
||||
public:
|
||||
CaptureStep(ThumbnailRendererContext* context);
|
||||
|
||||
void Start() override;
|
||||
void Stop() override;
|
||||
|
||||
private:
|
||||
//! Places the camera so that the entire model is visible
|
||||
void RepositionCamera() const;
|
||||
|
||||
//! AZ::TickBus::Handler interface overrides...
|
||||
void OnTick(float deltaTime, AZ::ScriptTimePoint time) override;
|
||||
|
||||
//! Render::FrameCaptureNotificationBus::Handler overrides...
|
||||
void OnCaptureFinished(Render::FrameCaptureResult result, const AZStd::string& info) override;
|
||||
|
||||
static constexpr float DepthNear = 0.01f;
|
||||
static constexpr float StartingDistanceMultiplier = 1.75f;
|
||||
static constexpr float StartingRotationAngle = Constants::QuarterPi / 2.0f;
|
||||
|
||||
//! This flag is needed to wait one frame after each frame capture to reset FrameCaptureSystemComponent
|
||||
bool m_readyToCapture = true;
|
||||
//! This is necessary to suspend capture to allow a frame for Material and Mesh components to assign materials
|
||||
int m_ticksToCapture = 0;
|
||||
};
|
||||
} // namespace Thumbnails
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
|
||||
-79
@@ -1,79 +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/RPI.Reflect/Material/MaterialAsset.h>
|
||||
#include <Atom/RPI.Reflect/Model/ModelAsset.h>
|
||||
#include <Thumbnails/ThumbnailUtils.h>
|
||||
#include <Thumbnails/Rendering/ThumbnailRendererContext.h>
|
||||
#include <Thumbnails/Rendering/ThumbnailRendererData.h>
|
||||
#include <Thumbnails/Rendering/ThumbnailRendererSteps/FindThumbnailToRenderStep.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace LyIntegration
|
||||
{
|
||||
namespace Thumbnails
|
||||
{
|
||||
FindThumbnailToRenderStep::FindThumbnailToRenderStep(ThumbnailRendererContext* context)
|
||||
: ThumbnailRendererStep(context)
|
||||
{
|
||||
}
|
||||
|
||||
void FindThumbnailToRenderStep::Start()
|
||||
{
|
||||
TickBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
void FindThumbnailToRenderStep::Stop()
|
||||
{
|
||||
TickBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
void FindThumbnailToRenderStep::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] ScriptTimePoint time)
|
||||
{
|
||||
PickNextThumbnail();
|
||||
}
|
||||
|
||||
void FindThumbnailToRenderStep::PickNextThumbnail()
|
||||
{
|
||||
if (!m_context->GetData()->m_thumbnailQueue.empty())
|
||||
{
|
||||
// pop the next thumbnailkey to be rendered from the queue
|
||||
m_context->GetData()->m_thumbnailKeyRendered = m_context->GetData()->m_thumbnailQueue.front();
|
||||
m_context->GetData()->m_thumbnailQueue.pop();
|
||||
|
||||
// Find whether thumbnailkey contains a material asset or set a default material
|
||||
m_context->GetData()->m_materialAsset = m_context->GetData()->m_defaultMaterialAsset;
|
||||
Data::AssetId materialAssetId = GetAssetId(m_context->GetData()->m_thumbnailKeyRendered, RPI::MaterialAsset::RTTI_Type());
|
||||
if (materialAssetId.IsValid())
|
||||
{
|
||||
if (m_context->GetData()->m_assetsToLoad.emplace(materialAssetId).second)
|
||||
{
|
||||
m_context->GetData()->m_materialAsset.Create(materialAssetId);
|
||||
m_context->GetData()->m_materialAsset.QueueLoad();
|
||||
}
|
||||
}
|
||||
|
||||
// Find whether thumbnailkey contains a model asset or set a default model
|
||||
m_context->GetData()->m_modelAsset = m_context->GetData()->m_defaultModelAsset;
|
||||
Data::AssetId modelAssetId = GetAssetId(m_context->GetData()->m_thumbnailKeyRendered, RPI::ModelAsset::RTTI_Type());
|
||||
if (modelAssetId.IsValid())
|
||||
{
|
||||
if (m_context->GetData()->m_assetsToLoad.emplace(modelAssetId).second)
|
||||
{
|
||||
m_context->GetData()->m_modelAsset.Create(modelAssetId);
|
||||
m_context->GetData()->m_modelAsset.QueueLoad();
|
||||
}
|
||||
}
|
||||
|
||||
m_context->SetStep(Step::WaitForAssetsToLoad);
|
||||
}
|
||||
}
|
||||
} // namespace Thumbnails
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
-40
@@ -1,40 +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 <Thumbnails/Rendering/ThumbnailRendererSteps/ThumbnailRendererStep.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace LyIntegration
|
||||
{
|
||||
namespace Thumbnails
|
||||
{
|
||||
//! FindThumbnailToRenderStep checks whether there are any new thumbnails that need to be rendered every tick
|
||||
class FindThumbnailToRenderStep
|
||||
: public ThumbnailRendererStep
|
||||
, private TickBus::Handler
|
||||
{
|
||||
public:
|
||||
FindThumbnailToRenderStep(ThumbnailRendererContext* context);
|
||||
|
||||
void Start() override;
|
||||
void Stop() override;
|
||||
|
||||
private:
|
||||
|
||||
//! AZ::TickBus::Handler interface overrides...
|
||||
void OnTick(float deltaTime, AZ::ScriptTimePoint time) override;
|
||||
|
||||
void PickNextThumbnail();
|
||||
};
|
||||
} // namespace Thumbnails
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
|
||||
-191
@@ -1,191 +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 <AzCore/Math/MatrixUtils.h>
|
||||
#include <AzCore/EBus/Results.h>
|
||||
|
||||
#include <AzFramework/Components/TransformComponent.h>
|
||||
|
||||
#include <Atom/Feature/ImageBasedLights/ImageBasedLightFeatureProcessorInterface.h>
|
||||
#include <Atom/Feature/PostProcess/PostProcessFeatureProcessorInterface.h>
|
||||
#include <Atom/Feature/SkyBox/SkyBoxFeatureProcessorInterface.h>
|
||||
#include <Atom/Feature/Utils/LightingPreset.h>
|
||||
|
||||
#include <Atom/RPI.Public/RenderPipeline.h>
|
||||
#include <Atom/RPI.Public/Scene.h>
|
||||
#include <Atom/RPI.Public/View.h>
|
||||
#include <Atom/RPI.Public/Shader/ShaderResourceGroup.h>
|
||||
#include <Atom/RPI.Reflect/Asset/AssetUtils.h>
|
||||
#include <Atom/RPI.Reflect/Model/ModelAsset.h>
|
||||
#include <Atom/RPI.Reflect/System/RenderPipelineDescriptor.h>
|
||||
#include <Atom/RPI.Reflect/System/SceneDescriptor.h>
|
||||
|
||||
#include <AtomLyIntegration/CommonFeatures/Material/MaterialComponentConstants.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/Mesh/MeshComponentConstants.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/Thumbnails/ThumbnailFeatureProcessorProviderBus.h>
|
||||
|
||||
#include <Thumbnails/Rendering/ThumbnailRendererData.h>
|
||||
#include <Thumbnails/Rendering/ThumbnailRendererContext.h>
|
||||
#include <Thumbnails/Rendering/ThumbnailRendererSteps/InitializeStep.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace LyIntegration
|
||||
{
|
||||
namespace Thumbnails
|
||||
{
|
||||
InitializeStep::InitializeStep(ThumbnailRendererContext* context)
|
||||
: ThumbnailRendererStep(context)
|
||||
{
|
||||
}
|
||||
|
||||
void InitializeStep::Start()
|
||||
{
|
||||
auto data = m_context->GetData();
|
||||
|
||||
data->m_entityContext = AZStd::make_unique<AzFramework::EntityContext>();
|
||||
data->m_entityContext->InitContext();
|
||||
|
||||
// Create and register a scene with all required feature processors
|
||||
RPI::SceneDescriptor sceneDesc;
|
||||
|
||||
AZ::EBusAggregateResults<AZStd::vector<AZStd::string>> results;
|
||||
ThumbnailFeatureProcessorProviderBus::BroadcastResult(results, &ThumbnailFeatureProcessorProviderBus::Handler::GetCustomFeatureProcessors);
|
||||
|
||||
AZStd::set<AZStd::string> featureProcessorNames;
|
||||
for (auto& resultCollection : results.values)
|
||||
{
|
||||
for (auto& featureProcessorName : resultCollection)
|
||||
{
|
||||
if (featureProcessorNames.emplace(featureProcessorName).second)
|
||||
{
|
||||
sceneDesc.m_featureProcessorNames.push_back(featureProcessorName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data->m_scene = RPI::Scene::CreateScene(sceneDesc);
|
||||
|
||||
// Bind m_defaultScene to the GameEntityContext's AzFramework::Scene
|
||||
auto* sceneSystem = AzFramework::SceneSystemInterface::Get();
|
||||
AZ_Assert(sceneSystem, "Thumbnail system failed to get scene system implementation.");
|
||||
Outcome<AZStd::shared_ptr<AzFramework::Scene>, AZStd::string> createSceneOutcome =
|
||||
sceneSystem->CreateScene(data->m_sceneName);
|
||||
AZ_Assert(createSceneOutcome, createSceneOutcome.GetError().c_str()); // This should never happen unless scene creation has changed.
|
||||
data->m_frameworkScene = createSceneOutcome.TakeValue();
|
||||
data->m_frameworkScene->SetSubsystem(data->m_scene);
|
||||
|
||||
data->m_frameworkScene->SetSubsystem(data->m_entityContext.get());
|
||||
// Create a render pipeline from the specified asset for the window context and add the pipeline to the scene
|
||||
RPI::RenderPipelineDescriptor pipelineDesc;
|
||||
pipelineDesc.m_mainViewTagName = "MainCamera";
|
||||
pipelineDesc.m_name = data->m_pipelineName;
|
||||
pipelineDesc.m_rootPassTemplate = "ThumbnailPipelineRenderToTexture";
|
||||
// We have to set the samples to 4 to match the pipeline passes' setting, otherwise it may lead to device lost issue
|
||||
// [GFX TODO] [ATOM-13551] Default value sand validation required to prevent pipeline crash and device lost
|
||||
pipelineDesc.m_renderSettings.m_multisampleState.m_samples = 4;
|
||||
data->m_renderPipeline = RPI::RenderPipeline::CreateRenderPipeline(pipelineDesc);
|
||||
data->m_scene->AddRenderPipeline(data->m_renderPipeline);
|
||||
data->m_scene->Activate();
|
||||
RPI::RPISystemInterface::Get()->RegisterScene(data->m_scene);
|
||||
data->m_passHierarchy.push_back(data->m_pipelineName);
|
||||
data->m_passHierarchy.push_back("CopyToSwapChain");
|
||||
|
||||
// Connect camera to pipeline's default view after camera entity activated
|
||||
Name viewName = Name("MainCamera");
|
||||
data->m_view = RPI::View::CreateView(viewName, RPI::View::UsageCamera);
|
||||
|
||||
Matrix4x4 viewToClipMatrix;
|
||||
MakePerspectiveFovMatrixRH(viewToClipMatrix,
|
||||
Constants::QuarterPi,
|
||||
AspectRatio,
|
||||
NearDist,
|
||||
FarDist, true);
|
||||
data->m_view->SetViewToClipMatrix(viewToClipMatrix);
|
||||
|
||||
data->m_renderPipeline->SetDefaultView(data->m_view);
|
||||
|
||||
// Create lighting preset
|
||||
data->m_lightingPresetAsset = AZ::RPI::AssetUtils::LoadAssetByProductPath<AZ::RPI::AnyAsset>(ThumbnailRendererData::LightingPresetPath);
|
||||
if (data->m_lightingPresetAsset.IsReady())
|
||||
{
|
||||
auto preset = data->m_lightingPresetAsset->GetDataAs<Render::LightingPreset>();
|
||||
if (preset)
|
||||
{
|
||||
auto iblFeatureProcessor = data->m_scene->GetFeatureProcessor<Render::ImageBasedLightFeatureProcessorInterface>();
|
||||
auto postProcessFeatureProcessor = data->m_scene->GetFeatureProcessor<Render::PostProcessFeatureProcessorInterface>();
|
||||
auto exposureControlSettingInterface = postProcessFeatureProcessor->GetOrCreateSettingsInterface(EntityId())->GetOrCreateExposureControlSettingsInterface();
|
||||
auto directionalLightFeatureProcessor = data->m_scene->GetFeatureProcessor<Render::DirectionalLightFeatureProcessorInterface>();
|
||||
auto skyboxFeatureProcessor = data->m_scene->GetFeatureProcessor<Render::SkyBoxFeatureProcessorInterface>();
|
||||
skyboxFeatureProcessor->Enable(true);
|
||||
skyboxFeatureProcessor->SetSkyboxMode(Render::SkyBoxMode::Cubemap);
|
||||
|
||||
Camera::Configuration cameraConfig;
|
||||
cameraConfig.m_fovRadians = Constants::HalfPi;
|
||||
cameraConfig.m_nearClipDistance = NearDist;
|
||||
cameraConfig.m_farClipDistance = FarDist;
|
||||
cameraConfig.m_frustumWidth = 100.0f;
|
||||
cameraConfig.m_frustumHeight = 100.0f;
|
||||
|
||||
AZStd::vector<Render::DirectionalLightFeatureProcessorInterface::LightHandle> lightHandles;
|
||||
|
||||
preset->ApplyLightingPreset(
|
||||
iblFeatureProcessor,
|
||||
skyboxFeatureProcessor,
|
||||
exposureControlSettingInterface,
|
||||
directionalLightFeatureProcessor,
|
||||
cameraConfig,
|
||||
lightHandles);
|
||||
}
|
||||
}
|
||||
|
||||
// Create preview model
|
||||
AzFramework::EntityContextRequestBus::EventResult(data->m_modelEntity, data->m_entityContext->GetContextId(),
|
||||
&AzFramework::EntityContextRequestBus::Events::CreateEntity, "ThumbnailPreviewModel");
|
||||
data->m_modelEntity->CreateComponent(Render::MeshComponentTypeId);
|
||||
data->m_modelEntity->CreateComponent(Render::MaterialComponentTypeId);
|
||||
data->m_modelEntity->CreateComponent(azrtti_typeid<AzFramework::TransformComponent>());
|
||||
data->m_modelEntity->Init();
|
||||
data->m_modelEntity->Activate();
|
||||
|
||||
// preload default model
|
||||
Data::AssetId defaultModelAssetId;
|
||||
Data::AssetCatalogRequestBus::BroadcastResult(
|
||||
defaultModelAssetId,
|
||||
&Data::AssetCatalogRequestBus::Events::GetAssetIdByPath,
|
||||
m_context->GetData()->DefaultModelPath,
|
||||
RPI::ModelAsset::RTTI_Type(),
|
||||
false);
|
||||
AZ_Error("ThumbnailRenderer", defaultModelAssetId.IsValid(), "Default model asset is invalid. Verify the asset %s exists.", m_context->GetData()->DefaultModelPath);
|
||||
if (m_context->GetData()->m_assetsToLoad.emplace(defaultModelAssetId).second)
|
||||
{
|
||||
data->m_defaultModelAsset.Create(defaultModelAssetId);
|
||||
data->m_defaultModelAsset.QueueLoad();
|
||||
}
|
||||
|
||||
// preload default material
|
||||
Data::AssetId defaultMaterialAssetId;
|
||||
Data::AssetCatalogRequestBus::BroadcastResult(
|
||||
defaultMaterialAssetId,
|
||||
&Data::AssetCatalogRequestBus::Events::GetAssetIdByPath,
|
||||
m_context->GetData()->DefaultMaterialPath,
|
||||
RPI::MaterialAsset::RTTI_Type(),
|
||||
false);
|
||||
AZ_Error("ThumbnailRenderer", defaultMaterialAssetId.IsValid(), "Default material asset is invalid. Verify the asset %s exists.", m_context->GetData()->DefaultMaterialPath);
|
||||
if (m_context->GetData()->m_assetsToLoad.emplace(defaultMaterialAssetId).second)
|
||||
{
|
||||
data->m_defaultMaterialAsset.Create(defaultMaterialAssetId);
|
||||
data->m_defaultMaterialAsset.QueueLoad();
|
||||
}
|
||||
|
||||
m_context->SetStep(Step::FindThumbnailToRender);
|
||||
}
|
||||
} // namespace Thumbnails
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
-37
@@ -1,37 +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 <Thumbnails/Rendering/ThumbnailRendererSteps/ThumbnailRendererStep.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace LyIntegration
|
||||
{
|
||||
namespace Thumbnails
|
||||
{
|
||||
//! InitializeStep sets up RPI system and scene and prepares it for rendering thumbnail entities
|
||||
//! This step is only called once when CommonThumbnailRenderer begins rendering its first thumbnail
|
||||
class InitializeStep
|
||||
: public ThumbnailRendererStep
|
||||
{
|
||||
public:
|
||||
InitializeStep(ThumbnailRendererContext* context);
|
||||
|
||||
void Start() override;
|
||||
|
||||
private:
|
||||
static constexpr float AspectRatio = 1.0f;
|
||||
static constexpr float NearDist = 0.1f;
|
||||
static constexpr float FarDist = 100.0f;
|
||||
};
|
||||
} // namespace Thumbnails
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
|
||||
-57
@@ -1,57 +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/RPI.Public/RenderPipeline.h>
|
||||
#include <Atom/RPI.Public/RPISystemInterface.h>
|
||||
#include <Atom/RPI.Public/Scene.h>
|
||||
#include <AzFramework/Scene/Scene.h>
|
||||
#include <AzFramework/Scene/SceneSystemInterface.h>
|
||||
#include <Thumbnails/Rendering/ThumbnailRendererContext.h>
|
||||
#include <Thumbnails/Rendering/ThumbnailRendererData.h>
|
||||
#include <Thumbnails/Rendering/ThumbnailRendererSteps/ReleaseResourcesStep.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace LyIntegration
|
||||
{
|
||||
namespace Thumbnails
|
||||
{
|
||||
ReleaseResourcesStep::ReleaseResourcesStep(ThumbnailRendererContext* context)
|
||||
: ThumbnailRendererStep(context)
|
||||
{
|
||||
}
|
||||
|
||||
void ReleaseResourcesStep::Start()
|
||||
{
|
||||
auto data = m_context->GetData();
|
||||
|
||||
data->m_defaultMaterialAsset.Release();
|
||||
data->m_defaultModelAsset.Release();
|
||||
data->m_materialAsset.Release();
|
||||
data->m_modelAsset.Release();
|
||||
data->m_lightingPresetAsset.Release();
|
||||
|
||||
if (data->m_modelEntity)
|
||||
{
|
||||
AzFramework::EntityContextRequestBus::Event(data->m_entityContext->GetContextId(),
|
||||
&AzFramework::EntityContextRequestBus::Events::DestroyEntity, data->m_modelEntity);
|
||||
data->m_modelEntity = nullptr;
|
||||
}
|
||||
|
||||
data->m_scene->Deactivate();
|
||||
data->m_scene->RemoveRenderPipeline(data->m_renderPipeline->GetId());
|
||||
RPI::RPISystemInterface::Get()->UnregisterScene(data->m_scene);
|
||||
data->m_frameworkScene->UnsetSubsystem(data->m_scene);
|
||||
data->m_frameworkScene->UnsetSubsystem(data->m_entityContext.get());
|
||||
data->m_scene = nullptr;
|
||||
data->m_frameworkScene = nullptr;
|
||||
data->m_renderPipeline = nullptr;
|
||||
}
|
||||
} // namespace Thumbnails
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
-30
@@ -1,30 +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 <Thumbnails/Rendering/ThumbnailRendererSteps/ThumbnailRendererStep.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace LyIntegration
|
||||
{
|
||||
namespace Thumbnails
|
||||
{
|
||||
class ReleaseResourcesStep
|
||||
: public ThumbnailRendererStep
|
||||
{
|
||||
public:
|
||||
ReleaseResourcesStep(ThumbnailRendererContext* context);
|
||||
|
||||
void Start() override;
|
||||
};
|
||||
} // namespace Thumbnails
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
|
||||
-37
@@ -1,37 +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
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace LyIntegration
|
||||
{
|
||||
namespace Thumbnails
|
||||
{
|
||||
class ThumbnailRendererContext;
|
||||
|
||||
//! ThumbnailRendererStep decouples CommonThumbnailRenderer logic into easy-to-understand and debug pieces
|
||||
class ThumbnailRendererStep
|
||||
{
|
||||
public:
|
||||
explicit ThumbnailRendererStep(ThumbnailRendererContext* context) : m_context(context) {}
|
||||
virtual ~ThumbnailRendererStep() = default;
|
||||
|
||||
//! Start is called when step begins execution
|
||||
virtual void Start() {}
|
||||
//! Stop is called when step ends execution
|
||||
virtual void Stop() {}
|
||||
|
||||
protected:
|
||||
ThumbnailRendererContext* m_context;
|
||||
};
|
||||
} // namespace Thumbnails
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
|
||||
-101
@@ -1,101 +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 "Thumbnails/ThumbnailerBus.h"
|
||||
|
||||
#include <Thumbnails/Rendering/ThumbnailRendererData.h>
|
||||
#include <Thumbnails/Rendering/ThumbnailRendererContext.h>
|
||||
#include <Thumbnails/Rendering/ThumbnailRendererSteps/CaptureStep.h>
|
||||
#include <Thumbnails/Rendering/ThumbnailRendererSteps/WaitForAssetsToLoadStep.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace LyIntegration
|
||||
{
|
||||
namespace Thumbnails
|
||||
{
|
||||
WaitForAssetsToLoadStep::WaitForAssetsToLoadStep(ThumbnailRendererContext* context)
|
||||
: ThumbnailRendererStep(context)
|
||||
{
|
||||
}
|
||||
|
||||
void WaitForAssetsToLoadStep::Start()
|
||||
{
|
||||
LoadNextAsset();
|
||||
}
|
||||
|
||||
void WaitForAssetsToLoadStep::Stop()
|
||||
{
|
||||
Data::AssetBus::Handler::BusDisconnect();
|
||||
TickBus::Handler::BusDisconnect();
|
||||
m_context->GetData()->m_assetsToLoad.clear();
|
||||
}
|
||||
|
||||
void WaitForAssetsToLoadStep::LoadNextAsset()
|
||||
{
|
||||
if (m_context->GetData()->m_assetsToLoad.empty())
|
||||
{
|
||||
// When all assets are loaded, render the thumbnail itself
|
||||
m_context->SetStep(Step::Capture);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Pick the the next asset and wait until its ready
|
||||
const auto assetIdIt = m_context->GetData()->m_assetsToLoad.begin();
|
||||
m_context->GetData()->m_assetsToLoad.erase(assetIdIt);
|
||||
m_assetId = *assetIdIt;
|
||||
Data::AssetBus::Handler::BusConnect(m_assetId);
|
||||
// If asset is already loaded, then AssetEvents will call OnAssetReady instantly and we don't need to wait this time
|
||||
if (Data::AssetBus::Handler::BusIsConnected())
|
||||
{
|
||||
TickBus::Handler::BusConnect();
|
||||
m_timeRemainingS = TimeOutS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WaitForAssetsToLoadStep::OnAssetReady([[maybe_unused]] Data::Asset<Data::AssetData> asset)
|
||||
{
|
||||
Data::AssetBus::Handler::BusDisconnect();
|
||||
LoadNextAsset();
|
||||
}
|
||||
|
||||
void WaitForAssetsToLoadStep::OnAssetError([[maybe_unused]] Data::Asset<Data::AssetData> asset)
|
||||
{
|
||||
Data::AssetBus::Handler::BusDisconnect();
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Event(
|
||||
m_context->GetData()->m_thumbnailKeyRendered,
|
||||
&AzToolsFramework::Thumbnailer::ThumbnailerRendererNotifications::ThumbnailFailedToRender);
|
||||
m_context->SetStep(Step::FindThumbnailToRender);
|
||||
}
|
||||
|
||||
void WaitForAssetsToLoadStep::OnAssetCanceled([[maybe_unused]] Data::AssetId assetId)
|
||||
{
|
||||
Data::AssetBus::Handler::BusDisconnect();
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Event(
|
||||
m_context->GetData()->m_thumbnailKeyRendered,
|
||||
&AzToolsFramework::Thumbnailer::ThumbnailerRendererNotifications::ThumbnailFailedToRender);
|
||||
m_context->SetStep(Step::FindThumbnailToRender);
|
||||
}
|
||||
|
||||
void WaitForAssetsToLoadStep::OnTick(float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time)
|
||||
{
|
||||
m_timeRemainingS -= deltaTime;
|
||||
if (m_timeRemainingS < 0)
|
||||
{
|
||||
auto assetIdStr = m_assetId.ToString<AZStd::string>();
|
||||
AZ_Warning("CommonThumbnailRenderer", false, "Timed out waiting for asset %s to load.", assetIdStr.c_str());
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Event(
|
||||
m_context->GetData()->m_thumbnailKeyRendered,
|
||||
&AzToolsFramework::Thumbnailer::ThumbnailerRendererNotifications::ThumbnailFailedToRender);
|
||||
m_context->SetStep(Step::FindThumbnailToRender);
|
||||
}
|
||||
}
|
||||
} // namespace Thumbnails
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
-50
@@ -1,50 +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/Asset/AssetCommon.h>
|
||||
#include <Thumbnails/Rendering/ThumbnailRendererSteps/ThumbnailRendererStep.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace LyIntegration
|
||||
{
|
||||
namespace Thumbnails
|
||||
{
|
||||
//! WaitForAssetsToLoadStep pauses further rendering until all assets used for rendering a thumbnail have been loaded
|
||||
class WaitForAssetsToLoadStep
|
||||
: public ThumbnailRendererStep
|
||||
, private Data::AssetBus::Handler
|
||||
, private TickBus::Handler
|
||||
{
|
||||
public:
|
||||
WaitForAssetsToLoadStep(ThumbnailRendererContext* context);
|
||||
|
||||
void Start() override;
|
||||
void Stop() override;
|
||||
|
||||
private:
|
||||
void LoadNextAsset();
|
||||
|
||||
// AZ::Data::AssetBus::Handler
|
||||
void OnAssetReady(Data::Asset<Data::AssetData> asset) override;
|
||||
void OnAssetError(Data::Asset<Data::AssetData> asset) override;
|
||||
void OnAssetCanceled(Data::AssetId assetId) override;
|
||||
|
||||
//! AZ::TickBus::Handler interface overrides...
|
||||
void OnTick(float deltaTime, AZ::ScriptTimePoint time) override;
|
||||
|
||||
static constexpr float TimeOutS = 3.0f;
|
||||
Data::AssetId m_assetId;
|
||||
float m_timeRemainingS = 0;
|
||||
};
|
||||
} // namespace Thumbnails
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
|
||||
+14
-27
@@ -7,9 +7,9 @@
|
||||
#
|
||||
|
||||
set(FILES
|
||||
Include/AtomLyIntegration/CommonFeatures/Material/EditorMaterialSystemComponentNotificationBus.h
|
||||
Include/AtomLyIntegration/CommonFeatures/Material/EditorMaterialSystemComponentRequestBus.h
|
||||
Include/AtomLyIntegration/CommonFeatures/ReflectionProbe/EditorReflectionProbeBus.h
|
||||
Include/AtomLyIntegration/CommonFeatures/Thumbnails/ThumbnailFeatureProcessorProviderBus.h
|
||||
Source/Module.cpp
|
||||
Source/Animation/EditorAttachmentComponent.h
|
||||
Source/Animation/EditorAttachmentComponent.cpp
|
||||
@@ -45,8 +45,6 @@ set(FILES
|
||||
Source/Material/EditorMaterialSystemComponent.h
|
||||
Source/Material/MaterialBrowserInteractions.h
|
||||
Source/Material/MaterialBrowserInteractions.cpp
|
||||
Source/Material/MaterialThumbnail.cpp
|
||||
Source/Material/MaterialThumbnail.h
|
||||
Source/Mesh/EditorMeshComponent.h
|
||||
Source/Mesh/EditorMeshComponent.cpp
|
||||
Source/Mesh/EditorMeshStats.h
|
||||
@@ -55,8 +53,6 @@ set(FILES
|
||||
Source/Mesh/EditorMeshSystemComponent.h
|
||||
Source/Mesh/EditorMeshStatsSerializer.cpp
|
||||
Source/Mesh/EditorMeshStatsSerializer.h
|
||||
Source/Mesh/MeshThumbnail.h
|
||||
Source/Mesh/MeshThumbnail.cpp
|
||||
Source/OcclusionCullingPlane/EditorOcclusionCullingPlaneComponent.h
|
||||
Source/OcclusionCullingPlane/EditorOcclusionCullingPlaneComponent.cpp
|
||||
Source/PostProcess/EditorPostFxLayerComponent.cpp
|
||||
@@ -95,28 +91,19 @@ set(FILES
|
||||
Source/SkyBox/EditorHDRiSkyboxComponent.h
|
||||
Source/SkyBox/EditorPhysicalSkyComponent.cpp
|
||||
Source/SkyBox/EditorPhysicalSkyComponent.h
|
||||
Source/Thumbnails/ThumbnailUtils.h
|
||||
Source/Thumbnails/ThumbnailUtils.cpp
|
||||
Source/Thumbnails/Preview/CommonPreviewer.cpp
|
||||
Source/Thumbnails/Preview/CommonPreviewer.h
|
||||
Source/Thumbnails/Preview/CommonPreviewer.ui
|
||||
Source/Thumbnails/Preview/CommonPreviewerFactory.cpp
|
||||
Source/Thumbnails/Preview/CommonPreviewerFactory.h
|
||||
Source/Thumbnails/Rendering/CommonThumbnailRenderer.cpp
|
||||
Source/Thumbnails/Rendering/CommonThumbnailRenderer.h
|
||||
Source/Thumbnails/Rendering/ThumbnailRendererData.h
|
||||
Source/Thumbnails/Rendering/ThumbnailRendererContext.h
|
||||
Source/Thumbnails/Rendering/ThumbnailRendererSteps/ThumbnailRendererStep.h
|
||||
Source/Thumbnails/Rendering/ThumbnailRendererSteps/InitializeStep.cpp
|
||||
Source/Thumbnails/Rendering/ThumbnailRendererSteps/InitializeStep.h
|
||||
Source/Thumbnails/Rendering/ThumbnailRendererSteps/FindThumbnailToRenderStep.cpp
|
||||
Source/Thumbnails/Rendering/ThumbnailRendererSteps/FindThumbnailToRenderStep.h
|
||||
Source/Thumbnails/Rendering/ThumbnailRendererSteps/WaitForAssetsToLoadStep.cpp
|
||||
Source/Thumbnails/Rendering/ThumbnailRendererSteps/WaitForAssetsToLoadStep.h
|
||||
Source/Thumbnails/Rendering/ThumbnailRendererSteps/CaptureStep.cpp
|
||||
Source/Thumbnails/Rendering/ThumbnailRendererSteps/CaptureStep.h
|
||||
Source/Thumbnails/Rendering/ThumbnailRendererSteps/ReleaseResourcesStep.cpp
|
||||
Source/Thumbnails/Rendering/ThumbnailRendererSteps/ReleaseResourcesStep.h
|
||||
Source/SharedPreview/SharedPreviewer.cpp
|
||||
Source/SharedPreview/SharedPreviewer.h
|
||||
Source/SharedPreview/SharedPreviewer.ui
|
||||
Source/SharedPreview/SharedPreviewerFactory.cpp
|
||||
Source/SharedPreview/SharedPreviewerFactory.h
|
||||
Source/SharedPreview/SharedPreviewContent.cpp
|
||||
Source/SharedPreview/SharedPreviewContent.h
|
||||
Source/SharedPreview/SharedPreviewUtils.cpp
|
||||
Source/SharedPreview/SharedPreviewUtils.h
|
||||
Source/SharedPreview/SharedThumbnail.cpp
|
||||
Source/SharedPreview/SharedThumbnail.h
|
||||
Source/SharedPreview/SharedThumbnailRenderer.cpp
|
||||
Source/SharedPreview/SharedThumbnailRenderer.h
|
||||
Source/Scripting/EditorEntityReferenceComponent.cpp
|
||||
Source/Scripting/EditorEntityReferenceComponent.h
|
||||
Source/SurfaceData/EditorSurfaceDataMeshComponent.cpp
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
|
||||
"Source" : "ImGuiAtom",
|
||||
"Source" : "ImGuiAtom.azsl",
|
||||
|
||||
|
||||
"RasterState" : { "CullMode" : "None" },
|
||||
|
||||
+14
-14
@@ -4,18 +4,18 @@
|
||||
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
#
|
||||
#
|
||||
# -- This line is 75 characters -------------------------------------------
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# Sets up the project environment for python scripting using the
|
||||
export DYNACONF_COMPANY=Amazon
|
||||
# if a lumberyard project isn't set use this gem
|
||||
export DYNACONF_LY_PROJECT=DccScriptingInterface
|
||||
export DYNACONF_LY_PROJECT_PATH=`pwd`
|
||||
export DYNACONF_LY_DEV=${LY_PROJECT_PATH}\..\..\..\..
|
||||
# if a O3DE project isn't set use this gem
|
||||
export DYNACONF_O3DE_PROJECT=DccScriptingInterface
|
||||
export DYNACONF_O3DE_PROJECT_PATH=`pwd`
|
||||
export DYNACONF_O3DE_DEV=${O3DE_PROJECT_PATH}\..\..\..\..
|
||||
|
||||
# LY build folder
|
||||
export DYNACONF_LY_BUILD_PATH=${LY_DEV}\build
|
||||
export DYNACONF_LY_BIN_PATH=${LY_BUILD_PATH}\bin\profile
|
||||
export DYNACONF_O3DE_BUILD_PATH=${O3DE_DEV}\build
|
||||
export DYNACONF_O3DE_BIN_PATH=${O3DE_BUILD_PATH}\bin\profile
|
||||
|
||||
# default IDE and debug settings
|
||||
#export DYNACONF_DCCSI_GDEBUG=false
|
||||
@@ -24,9 +24,9 @@ export DYNACONF_DCCSI_GDEBUGGER=WING
|
||||
export DYNACONF_DCCSI_LOGLEVEL=20
|
||||
|
||||
# defaults for DccScriptingInterface (DCCsi)
|
||||
export DYNACONF_DCCSIG_PATH=${LY_DEV}\Gems\AtomLyIntegration\TechnicalArt\DccScriptingInterface
|
||||
export DYNACONF_DCCSIG_PATH=${O3DE_DEV}\Gems\AtomLyIntegration\TechnicalArt\DccScriptingInterface
|
||||
|
||||
# set up default python interpreter (Lumberyard)
|
||||
# set up default python interpreter (O3DE)
|
||||
# we may want to entirely remove these and rely on config.py to dynamically set up
|
||||
# however VScode can be configured with a .env so might be valueable to keep
|
||||
export DYNACONF_DCCSI_PY_VERSION_MAJOR=3
|
||||
@@ -40,13 +40,13 @@ export DYNACONF_DCCSI_PYTHON_PATH=${DCCSIG_PATH}\3rdParty\Python
|
||||
export DYNACONF_DCCSI_PYTHON_LIB_PATH=${DCCSI_PYTHON_PATH}\Lib\${DCCSI_PY_VERSION_MAJOR}.x\${DCCSI_PY_VERSION_MAJOR}.${DCCSI_PY_VERSION_MINOR}.x\site-packages
|
||||
|
||||
# TO DO: figure out how to best deal with OS folder (i.e. 'windows')
|
||||
export DYNACONF_DCCSI_PYTHON_INSTALL=${LY_DEV}\python
|
||||
export DYNACONF_DDCCSI_PY_BASE=${DCCSI_PYTHON_INSTALL}\python.cmd
|
||||
export DYNACONF_O3DE_PYTHON_INSTALL=${O3DE_DEV}\python
|
||||
export DYNACONF_DCCSI_PY_BASE=${O3DE_PYTHON_INSTALL}\python.cmd
|
||||
|
||||
# set up Qt / PySide2
|
||||
# TO DO: These should NOT be set in the global env as they will cause conflicts
|
||||
# with other Qt apps (like DCC tools), only set in local.env, or modify config.py
|
||||
# for utils/tools/apps that need them ( see config.init_ly_pyside() )
|
||||
#export DYNACONF_QTFORPYTHON_PATH=${LY_DEV}\Gems\QtForPython\3rdParty\pyside2\windows\release
|
||||
#export DYNACONF_QT_PLUGIN_PATH=${LY_BUILD_PATH}\bin\profile\EditorPlugins
|
||||
#export DYNACONF_QT_QPA_PLATFORM_PLUGIN_PATH=${LY_BUILD_PATH}\bin\profile\EditorPlugins\platforms
|
||||
#export DYNACONF_QTFORPYTHON_PATH=${O3DE_DEV}\Gems\QtForPython\3rdParty\pyside2\windows\release
|
||||
#export DYNACONF_QT_PLUGIN_PATH=${O3DE_BUILD_PATH}\bin\profile\EditorPlugins
|
||||
#export DYNACONF_QT_QPA_PLATFORM_PLUGIN_PATH=${O3DE_BUILD_PATH}\bin\profile\EditorPlugins\platforms
|
||||
@@ -8,4 +8,6 @@ workspace.xml
|
||||
# Ignore dynaconf secret files
|
||||
.secrets.*
|
||||
settings.local.json
|
||||
azpy/_sample_package_/*
|
||||
azpy/_sample_package_/*
|
||||
.env
|
||||
settings_export.json.tmp
|
||||
@@ -19,3 +19,4 @@ __WIP__/*
|
||||
!.gitignore
|
||||
.secrets.*
|
||||
settings.local.json
|
||||
.env
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
DccScriptingInterface (DCCsi)
|
||||
|
||||
This location can be extended with additional 3rdParty Python Utils, Tools, Packages, etc.
|
||||
|
||||
These are not installed or distributed with O3DE
|
||||
|
||||
However, there is some stubbed scaffolding in place.
|
||||
|
||||
This is a bootstrapped sandbox for installing python libs (version bootstrapped procedurally):
|
||||
C:\Depot\o3de-engine\Gems\AtomLyIntegration\TechnicalArt\DccScriptingInterface\3rdParty\Python\Lib\2.x\2.7.x\site-packages
|
||||
C:\Depot\o3de-engine\Gems\AtomLyIntegration\TechnicalArt\DccScriptingInterface\3rdParty\Python\Lib\3.x\3.7.x\site-packages
|
||||
|
||||
Any libs installed to this location will be accessible (use at your own risk)
|
||||
|
||||
For instance, if you want to add py2.7 compatible libs, for apps like Maya2020:
|
||||
"C:\Depot\o3de-engine\Gems\AtomLyIntegration\TechnicalArt\DccScriptingInterface\Tools\DCC\Maya\readme.txt"
|
||||
|
||||
These pyside2-tools can be useful, and they are not pip installed, nor distributed.
|
||||
C:\Depot\o3de-engine\Gems\AtomLyIntegration\TechnicalArt\DccScriptingInterface\3rdParty\Python\pyside2-tools
|
||||
|
||||
pyside2-tools instructions:
|
||||
|
||||
1. clone the repo in this location: C:\Depot\o3de-engine\Gems\AtomLyIntegration\TechnicalArt\DccScriptingInterface\3rdParty\Python
|
||||
>git clone https://github.com/pyside/pyside2-tools
|
||||
|
||||
2. to use as a python package ...
|
||||
find this and copy:
|
||||
"< local DCCsi >\3rdParty\Python\pyside2-tools\pyside2uic\__init__.py.in"
|
||||
|
||||
and rename to this:
|
||||
"< local DCCsi >\3rdParty\Python\pyside2-tools\pyside2uic\__init__.py"
|
||||
|
||||
3. add to PYTHONPATH: < local DCCsi >\3rdParty\Python
|
||||
in .py something like: site.addsitedir(DCCSI_PYSIDE2_TOOLS)
|
||||
|
||||
See: "< local DCCsi >\config.py"
|
||||
+128
-52
@@ -7,9 +7,9 @@
|
||||
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
#
|
||||
#
|
||||
# -- This line is 75 characters -------------------------------------------
|
||||
# -------------------------------------------------------------------------
|
||||
"""This module is for use in boostrapping the DccScriptingInterface Gem
|
||||
with Lumberyard. Note: this boostrap is only designed fo be py3 compatible.
|
||||
with O3DE. Note: this boostrap is only designed fo be py3 compatible.
|
||||
If you need DCCsi access in py27 (Autodesk Maya for instance) you may need
|
||||
to implement your own boostrapper module. Currently this is boostrapped
|
||||
from add_dccsi.py, as a temporty measure related to this Jira:
|
||||
@@ -24,40 +24,64 @@ import logging as _logging
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
_O3DE_RUNNING=None
|
||||
try:
|
||||
import azlmbr
|
||||
_O3DE_RUNNING=True
|
||||
except:
|
||||
_O3DE_RUNNING=False
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# we don't use dynaconf setting here as we might not yet have access
|
||||
# to that site-dir.
|
||||
|
||||
_MODULE = 'DCCsi.bootstrap'
|
||||
_MODULENAME = __name__
|
||||
if _MODULENAME is '__main__':
|
||||
_MODULENAME = 'O3DE.DCCsi.bootstrap'
|
||||
|
||||
# set up module logging
|
||||
for handler in _logging.root.handlers[:]:
|
||||
_logging.root.removeHandler(handler)
|
||||
_LOGGER = _logging.getLogger(_MODULENAME)
|
||||
|
||||
# we need to set up basic access to the DCCsi
|
||||
_MODULE_PATH = os.path.realpath(__file__) # To Do: what if frozen?
|
||||
_DCCSIG_PATH = os.path.normpath(os.path.join(_MODULE_PATH, '../../..'))
|
||||
_DCCSIG_PATH = os.getenv('DCCSIG_PATH', _DCCSIG_PATH)
|
||||
site.addsitedir(_DCCSIG_PATH)
|
||||
_DCCSI_PATH = os.path.normpath(os.path.join(_MODULE_PATH, '../../..'))
|
||||
_DCCSI_PATH = os.getenv('DCCSI_PATH', _DCCSI_PATH)
|
||||
site.addsitedir(_DCCSI_PATH)
|
||||
|
||||
# we can get basic access to the DCCsi.azpy api now
|
||||
import azpy
|
||||
# now we have azpy api access
|
||||
from azpy.env_bool import env_bool
|
||||
from azpy.constants import ENVAR_DCCSI_GDEBUG
|
||||
from azpy.constants import ENVAR_DCCSI_DEV_MODE
|
||||
from azpy.constants import ENVAR_DCCSI_LOGLEVEL
|
||||
from azpy.constants import FRMT_LOG_LONG
|
||||
|
||||
# early attach WingIDE debugger (can refactor to include other IDEs later)
|
||||
while 0: # flag on to attemp to connect wingIDE debugger
|
||||
from azpy.env_bool import env_bool
|
||||
if not env_bool('DCCSI_DEBUGGER_ATTACHED', False):
|
||||
# if not already attached lets do it here
|
||||
from azpy.test.entry_test import connect_wing
|
||||
foo = connect_wing()
|
||||
# set up global space, logging etc.
|
||||
# set these true if you want them set globally for debugging
|
||||
_DCCSI_GDEBUG = env_bool(ENVAR_DCCSI_GDEBUG, False)
|
||||
_DCCSI_DEV_MODE = env_bool(ENVAR_DCCSI_DEV_MODE, False)
|
||||
_DCCSI_LOGLEVEL = int(env_bool(ENVAR_DCCSI_LOGLEVEL, int(20)))
|
||||
if _DCCSI_GDEBUG:
|
||||
_DCCSI_LOGLEVEL = int(10)
|
||||
|
||||
_logging.basicConfig(format=FRMT_LOG_LONG, level=_DCCSI_LOGLEVEL)
|
||||
_LOGGER.debug('Initializing: {0}.'.format({_MODULENAME}))
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# settings.setenv() # doing this will add the additional DYNACONF_ envars
|
||||
def get_dccsi_config(DCCSIG_PATH=_DCCSIG_PATH):
|
||||
# _settings.setenv() # doing this will add the additional DYNACONF_ envars
|
||||
def get_dccsi_config(DCCSI_PATH=_DCCSI_PATH):
|
||||
"""Convenience method to set and retreive settings directly from module."""
|
||||
|
||||
# we can go ahead and just make sure the the DCCsi env is set
|
||||
# config is SO generic this ensures we are importing a specific one
|
||||
_spec_dccsi_config = importlib.util.spec_from_file_location("dccsi.config",
|
||||
Path(DCCSIG_PATH,
|
||||
# _config is SO generic this ensures we are importing a specific one
|
||||
_spec_dccsi_config = importlib.util.spec_from_file_location("dccsi._config",
|
||||
Path(DCCSI_PATH,
|
||||
"config.py"))
|
||||
_dccsi_config = importlib.util.module_from_spec(_spec_dccsi_config)
|
||||
_spec_dccsi_config.loader.exec_module(_dccsi_config)
|
||||
@@ -65,9 +89,12 @@ def get_dccsi_config(DCCSIG_PATH=_DCCSIG_PATH):
|
||||
return _dccsi_config
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# set and retreive the base settings on import
|
||||
config = get_dccsi_config()
|
||||
settings = config.get_config_settings()
|
||||
# set and retreive the base env context/_settings on import
|
||||
_config = get_dccsi_config()
|
||||
_settings = _config.get_config_settings()
|
||||
|
||||
if _DCCSI_DEV_MODE:
|
||||
_config.attach_debugger() # attempts to start debugger
|
||||
# done with basic setup
|
||||
# --- END -----------------------------------------------------------------
|
||||
|
||||
@@ -77,50 +104,99 @@ settings = config.get_config_settings()
|
||||
# -------------------------------------------------------------------------
|
||||
if __name__ == '__main__':
|
||||
"""Run this file as main"""
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
_O3DE_RUNNING=None
|
||||
try:
|
||||
import azlmbr
|
||||
_O3DE_RUNNING=True
|
||||
except:
|
||||
_O3DE_RUNNING=False
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
_G_DEBUG = False
|
||||
_G_TEST_PYSIDE = False
|
||||
_MODULENAME = __name__
|
||||
if _MODULENAME is '__main__':
|
||||
_MODULENAME = 'O3DE.DCCsi.bootstrap'
|
||||
|
||||
from azpy.constants import STR_CROSSBAR
|
||||
|
||||
# module internal debugging flags
|
||||
while 0: # temp internal debug flag
|
||||
_DCCSI_GDEBUG = True
|
||||
break
|
||||
|
||||
# overide logger for standalone to be more verbose and log to file
|
||||
import azpy
|
||||
_LOGGER = azpy.initialize_logger(_MODULENAME,
|
||||
log_to_file=_DCCSI_GDEBUG,
|
||||
default_log_level=_DCCSI_LOGLEVEL)
|
||||
# happy print
|
||||
_LOGGER.info(STR_CROSSBAR)
|
||||
_LOGGER.info('~ constants.py ... Running script as __main__')
|
||||
_LOGGER.info(STR_CROSSBAR)
|
||||
|
||||
# parse the command line args
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser(
|
||||
description='O3DE DCCsi Boostrap (Test)',
|
||||
epilog="Will externally test the DCCsi boostrap")
|
||||
|
||||
_config = get_dccsi_config()
|
||||
_settings = config.get_config_settings()
|
||||
|
||||
_log_level = int(_settings.DCCSI_LOGLEVEL)
|
||||
if _G_DEBUG:
|
||||
_log_level = int(10) # force debug level
|
||||
_LOGGER = azpy.initialize_logger(_MODULE,
|
||||
log_to_file=True,
|
||||
default_log_level=_log_level)
|
||||
_settings = _config.get_config_settings(enable_o3de_python=True,
|
||||
enable_o3de_pyside2=True)
|
||||
parser.add_argument('-gd', '--global-debug',
|
||||
type=bool,
|
||||
required=False,
|
||||
help='Enables global debug flag.')
|
||||
parser.add_argument('-dm', '--developer-mode',
|
||||
type=bool,
|
||||
required=False,
|
||||
help='Enables dev mode for early auto attaching debugger.')
|
||||
parser.add_argument('-tp', '--test-pyside2',
|
||||
type=bool,
|
||||
required=False,
|
||||
help='Runs Qt/PySide2 tests and reports.')
|
||||
args = parser.parse_args()
|
||||
|
||||
# we can now grab values from the DCCsi.config.py dynamic env settings
|
||||
# the rest of this block is basic debug testing the dynamic settings at boot
|
||||
_LOGGER.info(f'Running module: {_MODULE}')
|
||||
_LOGGER.info(f'DCCSIG_PATH: {_settings.DCCSIG_PATH}')
|
||||
_LOGGER.info(f'DCCSI_G_DEBUG: {_settings.DCCSI_GDEBUG}')
|
||||
_LOGGER.info(f'DCCSI_DEV_MODE: {_settings.DCCSI_DEV_MODE}')
|
||||
|
||||
_LOGGER.info(f'OS_FOLDER: {_settings.OS_FOLDER}')
|
||||
_LOGGER.info(f'LY_PROJECT: {_settings.LY_PROJECT}')
|
||||
_LOGGER.info(f'LY_PROJECT_PATH: {_settings.LY_PROJECT_PATH}')
|
||||
_LOGGER.info(f'LY_DEV: {_settings.LY_DEV}')
|
||||
_LOGGER.info(f'LY_BUILD_PATH: {_settings.LY_BUILD_PATH}')
|
||||
_LOGGER.info(f'LY_BIN_PATH: {_settings.LY_BIN_PATH}')
|
||||
# easy overrides
|
||||
if args.global_debug:
|
||||
_DCCSI_GDEBUG = True
|
||||
if args.developer_mode:
|
||||
_DCCSI_DEV_MODE = True
|
||||
_config.attach_debugger() # attempts to start debugger
|
||||
|
||||
_LOGGER.info(f'DCCSIG_PATH: {_settings.DCCSIG_PATH}')
|
||||
_LOGGER.info(f'DCCSI_PYTHON_LIB_PATH: {_settings.DCCSI_PYTHON_LIB_PATH}')
|
||||
_LOGGER.info(f'DDCCSI_PY_BASE: {_settings.DDCCSI_PY_BASE}')
|
||||
if _DCCSI_GDEBUG:
|
||||
_LOGGER.info(f'DCCSI_PATH: {_settings.DCCSI_PATH}')
|
||||
_LOGGER.info(f'DCCSI_G_DEBUG: {_settings.DCCSI_GDEBUG}')
|
||||
_LOGGER.info(f'DCCSI_DEV_MODE: {_settings.DCCSI_DEV_MODE}')
|
||||
|
||||
_LOGGER.info(f'DCCSI_OS_FOLDER: {_settings.DCCSI_OS_FOLDER}')
|
||||
_LOGGER.info(f'O3DE_PROJECT: {_settings.O3DE_PROJECT}')
|
||||
_LOGGER.info(f'O3DE_PROJECT_PATH: {_settings.O3DE_PROJECT_PATH}')
|
||||
_LOGGER.info(f'O3DE_DEV: {_settings.O3DE_DEV}')
|
||||
_LOGGER.info(f'O3DE_BUILD_PATH: {_settings.O3DE_BUILD_PATH}')
|
||||
_LOGGER.info(f'O3DE_BIN_PATH: {_settings.O3DE_BIN_PATH}')
|
||||
|
||||
_LOGGER.info(f'DCCSI_PATH: {_settings.DCCSI_PATH}')
|
||||
_LOGGER.info(f'DCCSI_PYTHON_LIB_PATH: {_settings.DCCSI_PYTHON_LIB_PATH}')
|
||||
_LOGGER.info(f'DCCSI_PY_BASE: {_settings.DCCSI_PY_BASE}')
|
||||
|
||||
if _G_TEST_PYSIDE:
|
||||
if _DCCSI_GDEBUG or args.test_pyside2:
|
||||
try:
|
||||
import PySide2
|
||||
except:
|
||||
# set up Qt/PySide2 access and test
|
||||
_settings = _config.get_config_settings(setup_ly_pyside=True)
|
||||
_settings = _config.get_config_settings(enable_o3de_pyside2=True)
|
||||
import PySide2
|
||||
|
||||
_LOGGER.info(f'PySide2: {PySide2}')
|
||||
_LOGGER.info(f'LY_BIN_PATH: {_settings.LY_BIN_PATH}')
|
||||
_LOGGER.info(f'O3DE_BIN_PATH: {_settings.O3DE_BIN_PATH}')
|
||||
_LOGGER.info(f'QT_PLUGIN_PATH: {_settings.QT_PLUGIN_PATH}')
|
||||
_LOGGER.info(f'QT_QPA_PLATFORM_PLUGIN_PATH: {_settings.QT_QPA_PLATFORM_PLUGIN_PATH}')
|
||||
|
||||
_config.test_pyside2()
|
||||
|
||||
if not _O3DE_RUNNING:
|
||||
# return
|
||||
sys.exit()
|
||||
# --- END -----------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
"""
|
||||
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
|
||||
"""
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
This folder contains the DccScriptingInterface (DCCsi) for O3DE
|
||||
|
||||
Notice: The old \\SDK folder is being replaced with \\Tools
|
||||
The scripts in \\SDK may be out of data (and not run)
|
||||
When scripts are finished being updated and refactored into \\Tools the \\SDK will be removed
|
||||
|
||||
What is the DCCsi?
|
||||
|
||||
- A shared development environment for technical art oriented to working with Python across a number of DCC tools.
|
||||
- Leverage the existing python ecosystem for technical art.
|
||||
- Integrate a DCC app like Substance (or Substance SAT api) from the Python driven VFX and Games ecosystem.
|
||||
- Extend O3DE and unlock its potential for content creators, and the Technical Artists that service them.
|
||||
|
||||
Tenets:
|
||||
(1) Interoperability: Design DCC-agnostic modules and DCC-bespoke modules
|
||||
to work together efficiently and intuitively.
|
||||
|
||||
(2) Encapsulation: Define a module in terms of its essential features and interface to other components,
|
||||
to facilitate logical layered design and easy maintenance.
|
||||
|
||||
(3) Extensibility: Design the tool set to be easily extensible with new functionality and new tools.
|
||||
Individual pieces should have a generic communication mechanism to allow newly written tools to slot cleanly and transparently into the tool chain.
|
||||
|
||||
What is provided (High Level):
|
||||
- DCC-Agnostic Python Framework (as a modular Gem) related to multiple integrations for:
|
||||
O3DE Editor (python scripting, utils and PySide2 tools)
|
||||
DCC applications and their Python APIs/SDKs
|
||||
Custom standalone tools and utils (python based)
|
||||
external from cmd line
|
||||
external standalone
|
||||
integrated to run within O3DE Editor
|
||||
|
||||
What is provided (by folder):
|
||||
|
||||
\3rdParty: Allows third party libs/packages to be integrated outside of O3DE
|
||||
Example: O3DE is py3, Maya 2020 (and earlier) is py27
|
||||
O3DE provides a patterns for Gems to provide a requirements.txt
|
||||
See:
|
||||
DccScriptingInterface\reqiurements.txt
|
||||
^ These packages will be fetched and installed into O3DE python at build time
|
||||
|
||||
This means for some applications like Maya we need another way to add the same packages
|
||||
See:
|
||||
DccScriptingInterface\SDK\Maya\readme.txt
|
||||
DccScriptingInterface\SDK\Maya\requirements.txt
|
||||
DccScriptingInterface\3rdParty\Python\Lib\2.x\2.7.x\site-packages\*
|
||||
|
||||
Packages that reside in 3rdParty are never commited to the repo (only fetched+installed)
|
||||
|
||||
\Assets: All O3DE Gems can maintain an asset folder
|
||||
If a Gem contains an \Asset folder, these assets are folded into the projects asset data
|
||||
These assets are processed by the Asset Processor for use in the Editor and Runtime
|
||||
In the DCCsi the \Assets folder primarily contains TestData
|
||||
|
||||
\azpy Core (shared) API, A pure python Package and Modules
|
||||
|
||||
\Code Contains the bare bones C++ scaffold to build and integrate the Gem with O3DE
|
||||
Notes: portions of the DCCsi can be utilized outside of O3DE
|
||||
thus this Gem doens't have to be enabled and built for some use cases
|
||||
|
||||
\Editor This folder provides an entry point pattern for extending O3DE Editor with python
|
||||
When a Gem is enabled ...
|
||||
If the following if found, it will be executed when the Editor boots:
|
||||
"Editor\Scripts\bootstrap.py"
|
||||
|
||||
This can be used to initialize code access, extend the editor (PySide2), etc.
|
||||
|
||||
\Tools This is where the following is maintained:
|
||||
|
||||
\Tools\DCC Integration for DCC tools:
|
||||
configuration of tool (managed env, etc.)
|
||||
bootstrapping, such as providing the tool access to azpy api code
|
||||
extensibility, such as adding new functionality or tool to the app
|
||||
|
||||
\Tools\DCC\Maya An example of adding a integration for Autodesk Maya
|
||||
|
||||
\Tools\Env\Windows This provides a .bat file managed env to configure and bootsrap windows apps
|
||||
\Tools\Launchers\windows Provides .bat files based tool launchers for windows (accesses env)
|
||||
|
||||
-132
@@ -1,132 +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
|
||||
"""
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
import pymel.core as pmc
|
||||
import sys
|
||||
import types
|
||||
|
||||
|
||||
def syspath():
|
||||
print 'sys.path:'
|
||||
for p in sys.path:
|
||||
print ' ' + p
|
||||
|
||||
|
||||
def info(obj):
|
||||
"""Prints information about the object."""
|
||||
|
||||
lines = ['Info for %s' % obj.name(),
|
||||
'Attributes:']
|
||||
# Get the name of all attributes
|
||||
for a in obj.listAttr():
|
||||
lines.append(' ' + a.name())
|
||||
lines.append('MEL type: %s' % obj.type())
|
||||
lines.append('MRO:')
|
||||
lines.extend([' ' + t.__name__ for t in type(obj).__mro__])
|
||||
result = '\n'.join(lines)
|
||||
print result
|
||||
|
||||
|
||||
def _is_pymel(obj):
|
||||
try: # (1)
|
||||
module = obj.__module__ # (2)
|
||||
except AttributeError: # (3)
|
||||
try:
|
||||
module = obj.__name__ # (4)
|
||||
except AttributeError:
|
||||
return None # (5)
|
||||
return module.startswith('pymel') # (6)
|
||||
|
||||
|
||||
def _py_to_helpstr(obj):
|
||||
if isinstance(obj, basestring):
|
||||
return 'search.html?q=%s' % (obj.replace(' ', '+'))
|
||||
if not _is_pymel(obj):
|
||||
return None
|
||||
if isinstance(obj, types.ModuleType):
|
||||
return ('generated/%(module)s.html#module-%(module)s' %
|
||||
dict(module=obj.__name__))
|
||||
if isinstance(obj, types.MethodType):
|
||||
return ('generated/classes/%(module)s/'
|
||||
'%(module)s.%(typename)s.html'
|
||||
'#%(module)s.%(typename)s.%(methname)s' % dict(
|
||||
module=obj.__module__,
|
||||
typename=obj.im_class.__name__,
|
||||
methname=obj.__name__))
|
||||
if isinstance(obj, types.FunctionType):
|
||||
return ('generated/functions/%(module)s/'
|
||||
'%(module)s.%(funcname)s.html'
|
||||
'#%(module)s.%(funcname)s' % dict(
|
||||
module=obj.__module__,
|
||||
funcname=obj.__name__))
|
||||
if not isinstance(obj, type):
|
||||
obj = type(obj)
|
||||
return ('generated/classes/%(module)s/'
|
||||
'%(module)s.%(typename)s.html'
|
||||
'#%(module)s.%(typename)s' % dict(
|
||||
module=obj.__module__,
|
||||
typename=obj.__name__))
|
||||
|
||||
|
||||
def test_py_to_helpstr():
|
||||
def dotest(obj, ideal):
|
||||
result = _py_to_helpstr(obj)
|
||||
assert result == ideal, '%s != %s' % (result, ideal)
|
||||
dotest('maya rocks', 'search.html?q=maya+rocks')
|
||||
dotest(pmc.nodetypes,
|
||||
'generated/pymel.core.nodetypes.html'
|
||||
'#module-pymel.core.nodetypes')
|
||||
dotest(pmc.nodetypes.Joint,
|
||||
'generated/classes/pymel.core.nodetypes/'
|
||||
'pymel.core.nodetypes.Joint.html'
|
||||
'#pymel.core.nodetypes.Joint')
|
||||
dotest(pmc.nodetypes.Joint(),
|
||||
'generated/classes/pymel.core.nodetypes/'
|
||||
'pymel.core.nodetypes.Joint.html'
|
||||
'#pymel.core.nodetypes.Joint')
|
||||
dotest(pmc.nodetypes.Joint().getTranslation,
|
||||
'generated/classes/pymel.core.nodetypes/'
|
||||
'pymel.core.nodetypes.Joint.html'
|
||||
'#pymel.core.nodetypes.Joint.getTranslation')
|
||||
dotest(pmc.joint,
|
||||
'generated/functions/pymel.core.animation/'
|
||||
'pymel.core.animation.joint.html'
|
||||
'#pymel.core.animation.joint')
|
||||
dotest(object(), None)
|
||||
dotest(10, None)
|
||||
dotest([], None)
|
||||
dotest(sys, None)
|
||||
|
||||
|
||||
def test_py_to_helpstrFAIL():
|
||||
assert 1 == 2, '1 != 2'
|
||||
|
||||
|
||||
import webbrowser # (1)
|
||||
HELP_ROOT_URL = ('http://help.autodesk.com/cloudhelp/2018/ENU/Maya-Tech-Docs/PyMel/')# (2)
|
||||
|
||||
|
||||
def pmhelp(obj): # (3)
|
||||
"""Gives help for a pymel or python object.
|
||||
|
||||
If obj is not a PyMEL object, use Python's built-in
|
||||
`help` function.
|
||||
If obj is a string, open a web browser to a search in the
|
||||
PyMEL help for the string.
|
||||
Otherwise, open a web browser to the page for the object.
|
||||
"""
|
||||
tail = _py_to_helpstr(obj)
|
||||
if tail is None:
|
||||
help(obj) # (4)
|
||||
else:
|
||||
webbrowser.open(HELP_ROOT_URL + tail) # (5)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_py_to_helpstr()
|
||||
print 'Tests ran successfully.'
|
||||
-85
@@ -1,85 +0,0 @@
|
||||
@echo off
|
||||
|
||||
REM
|
||||
REM Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
REM For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
REM
|
||||
REM SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
REM
|
||||
REM
|
||||
|
||||
:: Set up and run LY Python CMD prompt
|
||||
:: Sets up the DccScriptingInterface_Env,
|
||||
:: Puts you in the CMD within the dev environment
|
||||
|
||||
:: Set up window
|
||||
TITLE Lumberyard DCC Scripting Interface Cmd
|
||||
:: Use obvious color to prevent confusion (Grey with Yellow Text)
|
||||
COLOR 8E
|
||||
|
||||
%~d0
|
||||
cd %~dp0
|
||||
|
||||
:: Keep changes local
|
||||
SETLOCAL enableDelayedExpansion
|
||||
|
||||
:: This maps up to the \Dev folder
|
||||
IF "%DEV_REL_PATH%"=="" (set DEV_REL_PATH=..\..\..\..\..\..\..\..\..)
|
||||
|
||||
:: Change to root Lumberyard dev dir
|
||||
:: Don't use the LY_DEV so we can test that ENVAR!!!
|
||||
CD /d %DEV_REL_PATH%
|
||||
set Rel_Dev=%CD%
|
||||
echo Rel_Dev = %Rel_Dev%
|
||||
:: Restore original directory
|
||||
popd
|
||||
|
||||
set DCCSI_PYTHON_INSTALL=%Rel_Dev%\Tools\Python\3.7.5\windows
|
||||
|
||||
:: add to the PATH
|
||||
SET PATH=%DCCSI_PYTHON_INSTALL%;%PATH%
|
||||
|
||||
:: dcc scripting interface gem path
|
||||
set DCCSIG_PATH=%Rel_Dev%\Gems\AtomLyIntegration\TechnicalArt\DccScriptingInterface
|
||||
echo DCCSIG_PATH = %DCCSIG_PATH%
|
||||
|
||||
:: add to the PATH
|
||||
SET PATH=%DCCSIG_PATH%;%PATH%
|
||||
|
||||
:: Constant Vars (Global)
|
||||
:: global debug (propogates)
|
||||
IF "%DCCSI_GDEBUG%"=="" (set DCCSI_GDEBUG=false)
|
||||
echo DCCSI_GDEBUG = %DCCSI_GDEBUG%
|
||||
:: initiates debugger connection
|
||||
IF "%DCCSI_DEV_MODE%"=="" (set DCCSI_DEV_MODE=false)
|
||||
echo DCCSI_DEV_MODE = %DCCSI_DEV_MODE%
|
||||
:: sets debugger, options: WING, PYCHARM
|
||||
IF "%DCCSI_GDEBUGGER%"=="" (set DCCSI_GDEBUGGER=WING)
|
||||
echo DCCSI_GDEBUGGER = %DCCSI_GDEBUGGER%
|
||||
|
||||
echo.
|
||||
echo _____________________________________________________________________
|
||||
echo.
|
||||
echo ~ LY DCCsi, DCC Material Converter
|
||||
echo _____________________________________________________________________
|
||||
echo.
|
||||
|
||||
:: Change to root dir
|
||||
CD /D %DCCSIG_PATH%
|
||||
|
||||
:: add to the PATH
|
||||
SET PATH=%DCCSIG_PATH%;%PATH%
|
||||
|
||||
set PYTHONPATH=%DCCSIG_PATH%;%PYTHONPATH%
|
||||
|
||||
CALL %DCCSI_PYTHON_INSTALL%\python.exe "%DCCSIG_PATH%\SDK\Maya\Scripts\Python\kitbash_converter\standalone.py"
|
||||
|
||||
|
||||
ENDLOCAL
|
||||
|
||||
:: Return to starting directory
|
||||
POPD
|
||||
|
||||
:END_OF_FILE
|
||||
|
||||
exit /b 0
|
||||
+2
-2
@@ -51,8 +51,8 @@ module_name = 'kitbash_converter.main'
|
||||
log_file_path = os.path.join(settings.DCCSI_LOG_PATH, f'{module_name}.log')
|
||||
|
||||
_log_level = int(20)
|
||||
_G_DEBUG = True
|
||||
if _G_DEBUG:
|
||||
_DCCSI_GDEBUG = True
|
||||
if _DCCSI_GDEBUG:
|
||||
_log_level = int(10)
|
||||
|
||||
from azpy.constants import FRMT_LOG_LONG
|
||||
|
||||
-45
@@ -1,45 +0,0 @@
|
||||
:: coding:utf-8
|
||||
:: !/usr/bin/python
|
||||
::
|
||||
:: 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
|
||||
::
|
||||
::
|
||||
|
||||
@echo off
|
||||
:: Set up and run LY Python CMD prompt
|
||||
:: Sets up the DccScriptingInterface_Env,
|
||||
:: Puts you in the CMD within the dev environment
|
||||
|
||||
:: Set up window
|
||||
TITLE Lumberyard DCC Scripting Interface Cmd
|
||||
:: Use obvious color to prevent confusion (Grey with Yellow Text)
|
||||
COLOR 8E
|
||||
|
||||
%~d0
|
||||
cd %~dp0
|
||||
PUSHD %~dp0
|
||||
|
||||
:: Keep changes local
|
||||
SETLOCAL enableDelayedExpansion
|
||||
|
||||
CALL %~dp0\Project_Env.bat
|
||||
|
||||
echo.
|
||||
echo _____________________________________________________________________
|
||||
echo.
|
||||
echo ~ LY DCC Scripting Interface CMD ...
|
||||
echo _____________________________________________________________________
|
||||
echo.
|
||||
|
||||
:: Create command prompt with environment
|
||||
CALL %windir%\system32\cmd.exe
|
||||
|
||||
ENDLOCAL
|
||||
|
||||
:: Return to starting directory
|
||||
POPD
|
||||
|
||||
:END_OF_FILE
|
||||
-68
@@ -1,68 +0,0 @@
|
||||
:: coding:utf-8
|
||||
:: !/usr/bin/python
|
||||
::
|
||||
:: 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
|
||||
::
|
||||
::
|
||||
|
||||
@echo off
|
||||
:: Launches maya with a bunch of local hooks for Lumberyard
|
||||
:: ToDo: move all of this to a .json data driven boostrapping system
|
||||
|
||||
%~d0
|
||||
cd %~dp0
|
||||
PUSHD %~dp0
|
||||
|
||||
echo ________________________________
|
||||
echo ~ calling PROJ_Env.bat
|
||||
|
||||
:: Keep changes local
|
||||
SETLOCAL enableDelayedExpansion
|
||||
|
||||
:: PY version Major
|
||||
set DCCSI_PY_VERSION_MAJOR=2
|
||||
echo DCCSI_PY_VERSION_MAJOR = %DCCSI_PY_VERSION_MAJOR%
|
||||
|
||||
:: PY version Major
|
||||
set DCCSI_PY_VERSION_MINOR=7
|
||||
echo DCCSI_PY_VERSION_MINOR = %DCCSI_PY_VERSION_MINOR%
|
||||
|
||||
:: Maya Version
|
||||
set MAYA_VERSION=2020
|
||||
echo MAYA_VERSION = %MAYA_VERSION%
|
||||
|
||||
:: if a local customEnv.bat exists, run it
|
||||
IF EXIST "%~dp0Project_Env.bat" CALL %~dp0Project_Env.bat
|
||||
|
||||
echo ________________________________
|
||||
echo Launching Maya %MAYA_VERSION% for Lumberyard...
|
||||
|
||||
:::: Set Maya native project acess to this project
|
||||
::set MAYA_PROJECT=%LY_PROJECT%
|
||||
::echo MAYA_PROJECT = %MAYA_PROJECT%
|
||||
|
||||
:: DX11 Viewport
|
||||
Set MAYA_VP2_DEVICE_OVERRIDE = VirtualDeviceDx11
|
||||
|
||||
:: Default to the right version of Maya if we can detect it... and launch
|
||||
IF EXIST "%MAYA_LOCATION%\bin\Maya.exe" (
|
||||
start "" "%MAYA_LOCATION%\bin\Maya.exe" %*
|
||||
) ELSE (
|
||||
Where maya.exe 2> NUL
|
||||
IF ERRORLEVEL 1 (
|
||||
echo Maya.exe could not be found
|
||||
pause
|
||||
) ELSE (
|
||||
start "" Maya.exe %*
|
||||
)
|
||||
)
|
||||
|
||||
:: Return to starting directory
|
||||
POPD
|
||||
|
||||
:END_OF_FILE
|
||||
|
||||
exit /b 0
|
||||
-81
@@ -1,81 +0,0 @@
|
||||
:: coding:utf-8
|
||||
:: !/usr/bin/python
|
||||
::
|
||||
:: 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
|
||||
::
|
||||
::
|
||||
|
||||
@echo off
|
||||
:: Launches Wing IDE and the DccScriptingInterface Project Files
|
||||
|
||||
echo.
|
||||
echo _____________________________________________________________________
|
||||
echo.
|
||||
echo ~ Setting up LY DCCsi WingIDE Dev Env...
|
||||
echo _____________________________________________________________________
|
||||
echo.
|
||||
|
||||
:: Store current dir
|
||||
%~d0
|
||||
cd %~dp0
|
||||
PUSHD %~dp0
|
||||
|
||||
:: Keep changes local
|
||||
SETLOCAL enableDelayedExpansion
|
||||
|
||||
SET ABS_PATH=%~dp0
|
||||
echo Current Dir, %ABS_PATH%
|
||||
|
||||
:: WingIDE version Major
|
||||
SET WING_VERSION_MAJOR=7
|
||||
echo WING_VERSION_MAJOR = %WING_VERSION_MAJOR%
|
||||
|
||||
:: WingIDE version Major
|
||||
SET WING_VERSION_MINOR=1
|
||||
echo WING_VERSION_MINOR = %WING_VERSION_MINOR%
|
||||
|
||||
:: note the changed path from IDE to Pro
|
||||
set WINGHOME=%PROGRAMFILES(X86)%\Wing Pro %WING_VERSION_MAJOR%.%WING_VERSION_MINOR%
|
||||
echo WINGHOME = %WINGHOME%
|
||||
|
||||
CALL %~dp0\Project_Env.bat
|
||||
|
||||
echo.
|
||||
echo _____________________________________________________________________
|
||||
echo.
|
||||
echo ~ WingIDE Version %WING_VERSION_MAJOR%.%WING_VERSION_MINOR%
|
||||
echo _____________________________________________________________________
|
||||
echo.
|
||||
|
||||
SET WING_PROJ=%DCCSIG_PATH%\Solutions\.wing\DCCsi_%WING_VERSION_MAJOR%x.wpr
|
||||
echo WING_PROJ = %WING_PROJ%
|
||||
|
||||
echo.
|
||||
echo _____________________________________________________________________
|
||||
echo.
|
||||
echo ~ Launching %LY_PROJECT% project in WingIDE %WING_VERSION_MAJOR%.%WING_VERSION_MINOR% ...
|
||||
echo _____________________________________________________________________
|
||||
echo.
|
||||
|
||||
|
||||
IF EXIST "%WINGHOME%\bin\wing.exe" (
|
||||
start "" "%WINGHOME%\bin\wing.exe" "%WING_PROJ%"
|
||||
) ELSE (
|
||||
Where wing.exe 2> NUL
|
||||
IF ERRORLEVEL 1 (
|
||||
echo wing.exe could not be found
|
||||
pause
|
||||
) ELSE (
|
||||
start "" wing.exe "%WING_PROJ%"
|
||||
)
|
||||
)
|
||||
|
||||
ENDLOCAL
|
||||
|
||||
:: Return to starting directory
|
||||
POPD
|
||||
|
||||
:END_OF_FILE
|
||||
-72
@@ -1,72 +0,0 @@
|
||||
:: coding:utf-8
|
||||
:: !/usr/bin/python
|
||||
::
|
||||
:: 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
|
||||
::
|
||||
::
|
||||
|
||||
@echo off
|
||||
:: Sets up environment for Lumberyard DCC tools and code access
|
||||
|
||||
:: Store current dir
|
||||
%~d0
|
||||
cd %~dp0
|
||||
PUSHD %~dp0
|
||||
|
||||
for %%a in (.) do set LY_PROJECT=%%~na
|
||||
|
||||
echo.
|
||||
echo _____________________________________________________________________
|
||||
echo.
|
||||
echo ~ Setting up LY DSI PROJECT Environment ...
|
||||
echo _____________________________________________________________________
|
||||
echo.
|
||||
|
||||
echo LY_PROJECT = %LY_PROJECT%
|
||||
|
||||
:: Put you project env vars and overrides here
|
||||
|
||||
:: chanhe the relative path up to dev
|
||||
set DEV_REL_PATH=../../..
|
||||
set ABS_PATH=%~dp0
|
||||
|
||||
:: Override the default maya version
|
||||
set MAYA_VERSION=2020
|
||||
echo MAYA_VERSION = %MAYA_VERSION%
|
||||
|
||||
set LY_PROJECT_PATH=%ABS_PATH%
|
||||
echo LY_PROJECT_PATH = %LY_PROJECT_PATH%
|
||||
|
||||
:: Change to root Lumberyard dev dir
|
||||
CD /d %LY_PROJECT_PATH%\%DEV_REL_PATH%
|
||||
set LY_DEV=%CD%
|
||||
echo LY_DEV = %LY_DEV%
|
||||
|
||||
CALL %LY_DEV%\Gems\AtomLyIntegration\TechnicalArt\DccScriptingInterface\Launchers\Windows\Env.bat
|
||||
|
||||
rem :: Constant Vars (Global)
|
||||
rem SET LYPY_GDEBUG=0
|
||||
rem echo LYPY_GDEBUG = %LYPY_GDEBUG%
|
||||
rem SET LYPY_DEV_MODE=0
|
||||
rem echo LYPY_DEV_MODE = %LYPY_DEV_MODE%
|
||||
rem SET LYPY_DEBUGGER=WING
|
||||
rem echo LYPY_DEBUGGER = %LYPY_DEBUGGER%
|
||||
|
||||
:: Restore original directory
|
||||
popd
|
||||
|
||||
:: Change to root dir
|
||||
CD /D %ABS_PATH%
|
||||
|
||||
:: if the user has set up a custom env call it
|
||||
IF EXIST "%~dp0User_Env.bat" CALL %~dp0User_Env.bat
|
||||
|
||||
GOTO END_OF_FILE
|
||||
|
||||
:: Return to starting directory
|
||||
POPD
|
||||
|
||||
:END_OF_FILE
|
||||
+2
-2
@@ -80,8 +80,8 @@ module_name = 'legacy_asset_converter.main'
|
||||
log_file_path = os.path.join(settings.DCCSI_LOG_PATH, f'{module_name}.log')
|
||||
|
||||
_log_level = int(20)
|
||||
_G_DEBUG = True
|
||||
if _G_DEBUG:
|
||||
_DCCSI_GDEBUG = True
|
||||
if _DCCSI_GDEBUG:
|
||||
_log_level = int(10)
|
||||
|
||||
from azpy.constants import FRMT_LOG_LONG
|
||||
|
||||
-135
@@ -1,135 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# !/usr/bin/python
|
||||
#
|
||||
# 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
|
||||
#
|
||||
#
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
import pymel.core as pmc
|
||||
import sys
|
||||
import types
|
||||
|
||||
|
||||
def syspath():
|
||||
print 'sys.path:'
|
||||
for p in sys.path:
|
||||
print ' ' + p
|
||||
|
||||
|
||||
def info(obj):
|
||||
"""Prints information about the object."""
|
||||
|
||||
lines = ['Info for %s' % obj.name(),
|
||||
'Attributes:']
|
||||
# Get the name of all attributes
|
||||
for a in obj.listAttr():
|
||||
lines.append(' ' + a.name())
|
||||
lines.append('MEL type: %s' % obj.type())
|
||||
lines.append('MRO:')
|
||||
lines.extend([' ' + t.__name__ for t in type(obj).__mro__])
|
||||
result = '\n'.join(lines)
|
||||
print result
|
||||
|
||||
|
||||
def _is_pymel(obj):
|
||||
try: # (1)
|
||||
module = obj.__module__ # (2)
|
||||
except AttributeError: # (3)
|
||||
try:
|
||||
module = obj.__name__ # (4)
|
||||
except AttributeError:
|
||||
return None # (5)
|
||||
return module.startswith('pymel') # (6)
|
||||
|
||||
|
||||
def _py_to_helpstr(obj):
|
||||
if isinstance(obj, basestring):
|
||||
return 'search.html?q=%s' % (obj.replace(' ', '+'))
|
||||
if not _is_pymel(obj):
|
||||
return None
|
||||
if isinstance(obj, types.ModuleType):
|
||||
return ('generated/%(module)s.html#module-%(module)s' %
|
||||
dict(module=obj.__name__))
|
||||
if isinstance(obj, types.MethodType):
|
||||
return ('generated/classes/%(module)s/'
|
||||
'%(module)s.%(typename)s.html'
|
||||
'#%(module)s.%(typename)s.%(methname)s' % dict(
|
||||
module=obj.__module__,
|
||||
typename=obj.im_class.__name__,
|
||||
methname=obj.__name__))
|
||||
if isinstance(obj, types.FunctionType):
|
||||
return ('generated/functions/%(module)s/'
|
||||
'%(module)s.%(funcname)s.html'
|
||||
'#%(module)s.%(funcname)s' % dict(
|
||||
module=obj.__module__,
|
||||
funcname=obj.__name__))
|
||||
if not isinstance(obj, type):
|
||||
obj = type(obj)
|
||||
return ('generated/classes/%(module)s/'
|
||||
'%(module)s.%(typename)s.html'
|
||||
'#%(module)s.%(typename)s' % dict(
|
||||
module=obj.__module__,
|
||||
typename=obj.__name__))
|
||||
|
||||
|
||||
def test_py_to_helpstr():
|
||||
def dotest(obj, ideal):
|
||||
result = _py_to_helpstr(obj)
|
||||
assert result == ideal, '%s != %s' % (result, ideal)
|
||||
dotest('maya rocks', 'search.html?q=maya+rocks')
|
||||
dotest(pmc.nodetypes,
|
||||
'generated/pymel.core.nodetypes.html'
|
||||
'#module-pymel.core.nodetypes')
|
||||
dotest(pmc.nodetypes.Joint,
|
||||
'generated/classes/pymel.core.nodetypes/'
|
||||
'pymel.core.nodetypes.Joint.html'
|
||||
'#pymel.core.nodetypes.Joint')
|
||||
dotest(pmc.nodetypes.Joint(),
|
||||
'generated/classes/pymel.core.nodetypes/'
|
||||
'pymel.core.nodetypes.Joint.html'
|
||||
'#pymel.core.nodetypes.Joint')
|
||||
dotest(pmc.nodetypes.Joint().getTranslation,
|
||||
'generated/classes/pymel.core.nodetypes/'
|
||||
'pymel.core.nodetypes.Joint.html'
|
||||
'#pymel.core.nodetypes.Joint.getTranslation')
|
||||
dotest(pmc.joint,
|
||||
'generated/functions/pymel.core.animation/'
|
||||
'pymel.core.animation.joint.html'
|
||||
'#pymel.core.animation.joint')
|
||||
dotest(object(), None)
|
||||
dotest(10, None)
|
||||
dotest([], None)
|
||||
dotest(sys, None)
|
||||
|
||||
|
||||
def test_py_to_helpstrFAIL():
|
||||
assert 1 == 2, '1 != 2'
|
||||
|
||||
|
||||
import webbrowser # (1)
|
||||
HELP_ROOT_URL = ('http://help.autodesk.com/cloudhelp/2018/ENU/Maya-Tech-Docs/PyMel/')# (2)
|
||||
|
||||
|
||||
def pmhelp(obj): # (3)
|
||||
"""Gives help for a pymel or python object.
|
||||
|
||||
If obj is not a PyMEL object, use Python's built-in
|
||||
`help` function.
|
||||
If obj is a string, open a web browser to a search in the
|
||||
PyMEL help for the string.
|
||||
Otherwise, open a web browser to the page for the object.
|
||||
"""
|
||||
tail = _py_to_helpstr(obj)
|
||||
if tail is None:
|
||||
help(obj) # (4)
|
||||
else:
|
||||
webbrowser.open(HELP_ROOT_URL + tail) # (5)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_py_to_helpstr()
|
||||
print 'Tests ran successfully.'
|
||||
+1
-1
@@ -23,7 +23,7 @@ def returnStubDir(stub):
|
||||
break
|
||||
if (len(tail) == 0):
|
||||
path = ""
|
||||
if _G_DEBUG:
|
||||
if _DCCSI_GDEBUG:
|
||||
print('~ Debug Message: I was not able to find the '
|
||||
'path to that file (stub) in a walk-up from currnet path')
|
||||
break
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user