Implemented support for semi-live previews of materials in the material property inspector.
Changed thumbnailer bus to use const pixmap Changed capture request call back to use const pixmap instead of image Replaced scene and pipeline members with constructor parameters Added material preview renderer to editor material system component with new requests and notifications Changed material property inspector details group to persistent heading so the preview image widget would not get destroyed during refreshes. But this was also a backlog task. Changed common preview render camera to use lookat Moved default asset caching to thumbnail renderer Signed-off-by: Guthrie Adams <guthadam@amazon.com>
This commit is contained in:
@@ -90,7 +90,7 @@ namespace AzToolsFramework
|
||||
typedef SharedThumbnailKey BusIdType;
|
||||
|
||||
//! notify product thumbnail that the data is ready
|
||||
virtual void ThumbnailRendered(QPixmap& thumbnailImage) = 0;
|
||||
virtual void ThumbnailRendered(const QPixmap& thumbnailImage) = 0;
|
||||
//! notify product thumbnail that the thumbnail failed to render
|
||||
virtual void ThumbnailFailedToRender() = 0;
|
||||
};
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace ImageProcessingAtom
|
||||
m_renderWait.acquire();
|
||||
}
|
||||
|
||||
void ImageThumbnail::ThumbnailRendered(QPixmap& thumbnailImage)
|
||||
void ImageThumbnail::ThumbnailRendered(const QPixmap& thumbnailImage)
|
||||
{
|
||||
m_pixmap = thumbnailImage;
|
||||
m_renderWait.release();
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace ImageProcessingAtom
|
||||
~ImageThumbnail() override;
|
||||
|
||||
//! AzToolsFramework::ThumbnailerRendererNotificationBus::Handler overrides...
|
||||
void ThumbnailRendered(QPixmap& thumbnailImage) override;
|
||||
void ThumbnailRendered(const QPixmap& thumbnailImage) override;
|
||||
void ThumbnailFailedToRender() override;
|
||||
|
||||
protected:
|
||||
|
||||
+5
-7
@@ -20,7 +20,7 @@ namespace AzFramework
|
||||
class Scene;
|
||||
}
|
||||
|
||||
class QImage;
|
||||
class QPixmap;
|
||||
|
||||
namespace AtomToolsFramework
|
||||
{
|
||||
@@ -30,7 +30,7 @@ namespace AtomToolsFramework
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(PreviewRenderer, AZ::SystemAllocator, 0);
|
||||
|
||||
PreviewRenderer();
|
||||
PreviewRenderer(const AZStd::string& sceneName, const AZStd::string& pipelineName);
|
||||
~PreviewRenderer();
|
||||
|
||||
struct CaptureRequest final
|
||||
@@ -38,15 +38,15 @@ namespace AtomToolsFramework
|
||||
int m_size = 512;
|
||||
AZStd::shared_ptr<PreviewContent> m_content;
|
||||
AZStd::function<void()> m_captureFailedCallback;
|
||||
AZStd::function<void(const QImage&)> m_captureCompleteCallback;
|
||||
AZStd::function<void(const QPixmap&)> m_captureCompleteCallback;
|
||||
};
|
||||
|
||||
void AddCaptureRequest(const CaptureRequest& captureRequest);
|
||||
|
||||
AZ::RPI::ScenePtr GetScene() const;
|
||||
AZ::RPI::ViewPtr GetView() const;
|
||||
AZ::Uuid GetEntityContextId() const;
|
||||
|
||||
void AddCaptureRequest(const CaptureRequest& captureRequest);
|
||||
|
||||
enum class State : AZ::s8
|
||||
{
|
||||
None,
|
||||
@@ -81,8 +81,6 @@ namespace AtomToolsFramework
|
||||
static constexpr float FieldOfView = AZ::Constants::HalfPi;
|
||||
|
||||
AZ::RPI::ScenePtr m_scene;
|
||||
AZStd::string m_sceneName = "Preview Renderer Scene";
|
||||
AZStd::string m_pipelineName = "Preview Renderer Pipeline";
|
||||
AZStd::shared_ptr<AzFramework::Scene> m_frameworkScene;
|
||||
AZ::RPI::RenderPipelinePtr m_renderPipeline;
|
||||
AZ::RPI::ViewPtr m_view;
|
||||
|
||||
+14
-11
@@ -24,9 +24,12 @@
|
||||
#include <PreviewRenderer/PreviewRendererIdleState.h>
|
||||
#include <PreviewRenderer/PreviewRendererLoadState.h>
|
||||
|
||||
#include <QImage>
|
||||
#include <QPixmap>
|
||||
|
||||
namespace AtomToolsFramework
|
||||
{
|
||||
PreviewRenderer::PreviewRenderer()
|
||||
PreviewRenderer::PreviewRenderer(const AZStd::string& sceneName, const AZStd::string& pipelineName)
|
||||
{
|
||||
PreviewerFeatureProcessorProviderBus::Handler::BusConnect();
|
||||
|
||||
@@ -46,7 +49,7 @@ namespace AtomToolsFramework
|
||||
auto sceneSystem = AzFramework::SceneSystemInterface::Get();
|
||||
AZ_Assert(sceneSystem, "Failed to get scene system implementation.");
|
||||
|
||||
AZ::Outcome<AZStd::shared_ptr<AzFramework::Scene>, AZStd::string> createSceneOutcome = sceneSystem->CreateScene(m_sceneName);
|
||||
AZ::Outcome<AZStd::shared_ptr<AzFramework::Scene>, AZStd::string> createSceneOutcome = sceneSystem->CreateScene(sceneName);
|
||||
AZ_Assert(createSceneOutcome, createSceneOutcome.GetError().c_str());
|
||||
|
||||
m_frameworkScene = createSceneOutcome.TakeValue();
|
||||
@@ -56,7 +59,7 @@ namespace AtomToolsFramework
|
||||
// Create a render pipeline from the specified asset for the window context and add the pipeline to the scene
|
||||
AZ::RPI::RenderPipelineDescriptor pipelineDesc;
|
||||
pipelineDesc.m_mainViewTagName = "MainCamera";
|
||||
pipelineDesc.m_name = m_pipelineName;
|
||||
pipelineDesc.m_name = pipelineName;
|
||||
pipelineDesc.m_rootPassTemplate = "MainPipelineRenderToTexture";
|
||||
|
||||
// We have to set the samples to 4 to match the pipeline passes' setting, otherwise it may lead to device lost issue
|
||||
@@ -66,7 +69,7 @@ namespace AtomToolsFramework
|
||||
m_scene->AddRenderPipeline(m_renderPipeline);
|
||||
m_scene->Activate();
|
||||
AZ::RPI::RPISystemInterface::Get()->RegisterScene(m_scene);
|
||||
m_passHierarchy.push_back(m_pipelineName);
|
||||
m_passHierarchy.push_back(pipelineName);
|
||||
m_passHierarchy.push_back("CopyToSwapChain");
|
||||
|
||||
// Connect camera to pipeline's default view after camera entity activated
|
||||
@@ -97,6 +100,11 @@ namespace AtomToolsFramework
|
||||
m_frameworkScene->UnsetSubsystem(m_entityContext.get());
|
||||
}
|
||||
|
||||
void PreviewRenderer::AddCaptureRequest(const CaptureRequest& captureRequest)
|
||||
{
|
||||
m_captureRequestQueue.push(captureRequest);
|
||||
}
|
||||
|
||||
AZ::RPI::ScenePtr PreviewRenderer::GetScene() const
|
||||
{
|
||||
return m_scene;
|
||||
@@ -112,11 +120,6 @@ namespace AtomToolsFramework
|
||||
return m_entityContext->GetContextId();
|
||||
}
|
||||
|
||||
void PreviewRenderer::AddCaptureRequest(const CaptureRequest& captureRequest)
|
||||
{
|
||||
m_captureRequestQueue.push(captureRequest);
|
||||
}
|
||||
|
||||
void PreviewRenderer::SetState(State state)
|
||||
{
|
||||
auto stepItr = m_states.find(m_currentState);
|
||||
@@ -199,9 +202,9 @@ namespace AtomToolsFramework
|
||||
{
|
||||
if (result.m_dataBuffer)
|
||||
{
|
||||
currentCaptureRequest.m_captureCompleteCallback(QImage(
|
||||
currentCaptureRequest.m_captureCompleteCallback(QPixmap::fromImage(QImage(
|
||||
result.m_dataBuffer.get()->data(), result.m_imageDescriptor.m_size.m_width, result.m_imageDescriptor.m_size.m_height,
|
||||
QImage::Format_RGBA8888));
|
||||
QImage::Format_RGBA8888)));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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>
|
||||
#include <AzCore/std/string/string.h>
|
||||
|
||||
class QPixmap;
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
//! EditorMaterialSystemComponentNotifications provides an interface to communicate with EditorMaterialSystemComponent
|
||||
class EditorMaterialSystemComponentNotifications : public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
// Only a single handler is allowed
|
||||
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
|
||||
+6
-2
@@ -5,6 +5,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Atom/Feature/Material/MaterialAssignmentId.h>
|
||||
@@ -17,8 +18,7 @@ namespace AZ
|
||||
namespace Render
|
||||
{
|
||||
//! EditorMaterialSystemComponentRequests provides an interface to communicate with MaterialEditor
|
||||
class EditorMaterialSystemComponentRequests
|
||||
: public AZ::EBusTraits
|
||||
class EditorMaterialSystemComponentRequests : public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
// Only a single handler is allowed
|
||||
@@ -31,6 +31,10 @@ 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;
|
||||
};
|
||||
using EditorMaterialSystemComponentRequestBus = AZ::EBus<EditorMaterialSystemComponentRequests>;
|
||||
} // namespace Render
|
||||
|
||||
+1
-1
@@ -98,9 +98,9 @@ namespace AZ
|
||||
|
||||
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();
|
||||
|
||||
+92
-85
@@ -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,62 @@ 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->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 +225,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 +234,15 @@ 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);
|
||||
|
||||
AddGroup(groupName, groupDisplayName, groupDescription, propertyGroupContainer);
|
||||
m_overviewText->setText(materialInfo);
|
||||
m_overviewText->setAlignment(Qt::AlignLeading | Qt::AlignLeft | Qt::AlignTop);
|
||||
m_overviewImage->setVisible(true);
|
||||
m_updatePreview = true;
|
||||
}
|
||||
|
||||
void MaterialPropertyInspector::AddUvNamesGroup()
|
||||
@@ -282,13 +283,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 +323,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()
|
||||
@@ -375,6 +375,7 @@ namespace AZ
|
||||
m_dirtyPropertyFlags.set();
|
||||
RunEditorMaterialFunctors();
|
||||
RebuildAll();
|
||||
UpdateHeading();
|
||||
}
|
||||
|
||||
void MaterialPropertyInspector::SaveOverridesToEntity(bool commitChanges)
|
||||
@@ -398,6 +399,8 @@ namespace AZ
|
||||
MaterialComponentNotificationBus::Event(m_entityId, &MaterialComponentNotifications::OnMaterialsEdited);
|
||||
m_internalEditNotification = false;
|
||||
}
|
||||
|
||||
m_updatePreview = true;
|
||||
}
|
||||
|
||||
void MaterialPropertyInspector::RunEditorMaterialFunctors()
|
||||
@@ -607,7 +610,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 +706,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 +720,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,14 +776,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
|
||||
|
||||
+17
-4
@@ -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>
|
||||
@@ -39,6 +40,7 @@ namespace AZ
|
||||
, public AZ::EntitySystemBus::Handler
|
||||
, public AZ::TickBus::Handler
|
||||
, public MaterialComponentNotificationBus::Handler
|
||||
, public EditorMaterialSystemComponentNotificationBus::Handler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
@@ -89,11 +91,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 +125,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
|
||||
|
||||
+3
@@ -315,6 +315,9 @@ namespace AZ
|
||||
AzToolsFramework::ToolsApplicationRequests::Bus::Broadcast(
|
||||
&AzToolsFramework::ToolsApplicationRequests::Bus::Events::AddDirtyEntity, m_entityId);
|
||||
|
||||
EditorMaterialSystemComponentRequestBus::Broadcast(
|
||||
&EditorMaterialSystemComponentRequestBus::Events::RenderMaterialPreview, m_entityId, m_id);
|
||||
|
||||
MaterialComponentNotificationBus::Event(m_entityId, &MaterialComponentNotifications::OnMaterialsEdited);
|
||||
|
||||
AzToolsFramework::ToolsApplicationEvents::Bus::Broadcast(
|
||||
|
||||
+67
-2
@@ -6,7 +6,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AtomLyIntegration/CommonFeatures/Material/EditorMaterialSystemComponentNotificationBus.h>
|
||||
#include <Atom/RHI/Factory.h>
|
||||
#include <Atom/RPI.Reflect/Asset/AssetUtils.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/Material/MaterialComponentBus.h>
|
||||
#include <AtomToolsFramework/Util/Util.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/EditContextConstants.inl>
|
||||
@@ -19,6 +22,7 @@
|
||||
#include <Editor/LyViewPaneNames.h>
|
||||
#include <Material/EditorMaterialComponentInspector.h>
|
||||
#include <Material/EditorMaterialSystemComponent.h>
|
||||
#include <Previewer/CommonPreviewContent.h>
|
||||
|
||||
// Disables warning messages triggered by the Qt library
|
||||
// 4251: class needs to have dll-interface to be used by clients of class
|
||||
@@ -28,6 +32,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
|
||||
|
||||
@@ -86,17 +92,20 @@ namespace AZ
|
||||
AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler::BusConnect();
|
||||
AzToolsFramework::EditorMenuNotificationBus::Handler::BusConnect();
|
||||
AzToolsFramework::EditorEvents::Bus::Handler::BusConnect();
|
||||
|
||||
m_materialBrowserInteractions.reset(aznew MaterialBrowserInteractions);
|
||||
AzFramework::AssetCatalogEventBus::Handler::BusConnect();
|
||||
AzFramework::ApplicationLifecycleEvents::Bus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
void EditorMaterialSystemComponent::Deactivate()
|
||||
{
|
||||
AzFramework::ApplicationLifecycleEvents::Bus::Handler::BusDisconnect();
|
||||
AzFramework::AssetCatalogEventBus::Handler::BusDisconnect();
|
||||
EditorMaterialSystemComponentRequestBus::Handler::BusDisconnect();
|
||||
AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler::BusDisconnect();
|
||||
AzToolsFramework::EditorMenuNotificationBus::Handler::BusDisconnect();
|
||||
AzToolsFramework::EditorEvents::Bus::Handler::BusDisconnect();
|
||||
|
||||
m_previewRenderer.reset();
|
||||
m_materialBrowserInteractions.reset();
|
||||
|
||||
if (m_openMaterialEditorAction)
|
||||
@@ -143,6 +152,47 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
void EditorMaterialSystemComponent::RenderMaterialPreview(
|
||||
const AZ::EntityId& entityId, const AZ::Render::MaterialAssignmentId& materialAssignmentId)
|
||||
{
|
||||
static constexpr const char* DefaultModelPath = "models/sphere.azmodel";
|
||||
static constexpr const char* DefaultLightingPresetPath = "lightingpresets/thumbnail.lightingpreset.azasset";
|
||||
|
||||
if (m_previewRenderer)
|
||||
{
|
||||
AZ::Data::AssetId materialAssetId = {};
|
||||
MaterialComponentRequestBus::EventResult(
|
||||
materialAssetId, entityId, &MaterialComponentRequestBus::Events::GetMaterialOverride, materialAssignmentId);
|
||||
if (!materialAssetId.IsValid())
|
||||
{
|
||||
MaterialComponentRequestBus::EventResult(
|
||||
materialAssetId, entityId, &MaterialComponentRequestBus::Events::GetDefaultMaterialAssetId, materialAssignmentId);
|
||||
}
|
||||
|
||||
AZ::Render::MaterialPropertyOverrideMap propertyOverrides;
|
||||
AZ::Render::MaterialComponentRequestBus::EventResult(
|
||||
propertyOverrides, entityId, &AZ::Render::MaterialComponentRequestBus::Events::GetPropertyOverrides,
|
||||
materialAssignmentId);
|
||||
|
||||
m_previewRenderer->AddCaptureRequest(
|
||||
{ 128,
|
||||
AZStd::make_shared<AZ::LyIntegration::CommonPreviewContent>(
|
||||
m_previewRenderer->GetScene(), m_previewRenderer->GetView(), m_previewRenderer->GetEntityContextId(),
|
||||
AZ::RPI::AssetUtils::GetAssetIdForProductPath(DefaultModelPath), materialAssetId,
|
||||
AZ::RPI::AssetUtils::GetAssetIdForProductPath(DefaultLightingPresetPath), propertyOverrides),
|
||||
[]()
|
||||
{
|
||||
// failed
|
||||
},
|
||||
[entityId, materialAssignmentId](const QPixmap& pixmap)
|
||||
{
|
||||
AZ::Render::EditorMaterialSystemComponentNotificationBus::Broadcast(
|
||||
&AZ::Render::EditorMaterialSystemComponentNotificationBus::Events::OnRenderMaterialPreviewComplete, entityId,
|
||||
materialAssignmentId, pixmap);
|
||||
} });
|
||||
}
|
||||
}
|
||||
|
||||
void EditorMaterialSystemComponent::OnPopulateToolMenuItems()
|
||||
{
|
||||
if (!m_openMaterialEditorAction)
|
||||
@@ -185,6 +235,21 @@ namespace AZ
|
||||
"Material Property Inspector", LyViewPane::CategoryTools, inspectorOptions);
|
||||
}
|
||||
|
||||
void EditorMaterialSystemComponent::OnCatalogLoaded([[maybe_unused]] const char* catalogFile)
|
||||
{
|
||||
AZ::TickBus::QueueFunction([this](){
|
||||
m_materialBrowserInteractions.reset(aznew MaterialBrowserInteractions);
|
||||
m_previewRenderer.reset(aznew AtomToolsFramework::PreviewRenderer(
|
||||
"EditorMaterialSystemComponent Preview Scene", "EditorMaterialSystemComponent Preview Pipeline"));
|
||||
});
|
||||
}
|
||||
|
||||
void EditorMaterialSystemComponent::OnApplicationAboutToStop()
|
||||
{
|
||||
m_previewRenderer.reset();
|
||||
m_materialBrowserInteractions.reset();
|
||||
}
|
||||
|
||||
AzToolsFramework::AssetBrowser::SourceFileDetails EditorMaterialSystemComponent::GetSourceFileDetails(
|
||||
const char* fullSourceFileName)
|
||||
{
|
||||
|
||||
+21
-9
@@ -7,13 +7,14 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AtomLyIntegration/CommonFeatures/Material/EditorMaterialSystemComponentRequestBus.h>
|
||||
#include <AtomToolsFramework/PreviewRenderer/PreviewRenderer.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/Component/Component.h>
|
||||
#include <AzFramework/Application/Application.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
|
||||
#include <AzToolsFramework/Viewport/ActionBus.h>
|
||||
|
||||
#include <AtomLyIntegration/CommonFeatures/Material/EditorMaterialSystemComponentRequestBus.h>
|
||||
|
||||
#include <Material/MaterialBrowserInteractions.h>
|
||||
|
||||
namespace AZ
|
||||
@@ -21,12 +22,14 @@ 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 AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler
|
||||
, private AzToolsFramework::EditorMenuNotificationBus::Handler
|
||||
, private AzToolsFramework::EditorEvents::Bus::Handler
|
||||
, public EditorMaterialSystemComponentRequestBus::Handler
|
||||
, public AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler
|
||||
, public AzToolsFramework::EditorMenuNotificationBus::Handler
|
||||
, public AzToolsFramework::EditorEvents::Bus::Handler
|
||||
, public AzFramework::AssetCatalogEventBus::Handler
|
||||
, public AzFramework::ApplicationLifecycleEvents::Bus::Handler
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(EditorMaterialSystemComponent, "{96652157-DA0B-420F-B49C-0207C585144C}");
|
||||
@@ -47,6 +50,8 @@ 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;
|
||||
|
||||
//! AssetBrowserInteractionNotificationBus::Handler overrides...
|
||||
AzToolsFramework::AssetBrowser::SourceFileDetails GetSourceFileDetails(const char* fullSourceFileName) override;
|
||||
@@ -58,9 +63,16 @@ namespace AZ
|
||||
// AztoolsFramework::EditorEvents::Bus::Handler overrides...
|
||||
void NotifyRegisterViews() override;
|
||||
|
||||
QAction* m_openMaterialEditorAction = nullptr;
|
||||
|
||||
// AzFramework::AssetCatalogEventBus::Handler overrides ...
|
||||
void OnCatalogLoaded(const char* catalogFile) override;
|
||||
|
||||
// AzFramework::ApplicationLifecycleEvents overrides...
|
||||
void OnApplicationAboutToStop() override;
|
||||
|
||||
QAction* m_openMaterialEditorAction = nullptr;
|
||||
AZStd::unique_ptr<MaterialBrowserInteractions> m_materialBrowserInteractions;
|
||||
AZStd::unique_ptr<AtomToolsFramework::PreviewRenderer> m_previewRenderer;
|
||||
};
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
+38
-31
@@ -35,10 +35,12 @@ namespace AZ
|
||||
AZ::Uuid entityContextId,
|
||||
const Data::AssetId& modelAssetId,
|
||||
const Data::AssetId& materialAssetId,
|
||||
const Data::AssetId& lightingPresetAssetId)
|
||||
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(
|
||||
@@ -49,13 +51,9 @@ namespace AZ
|
||||
m_modelEntity->Init();
|
||||
m_modelEntity->Activate();
|
||||
|
||||
m_defaultModelAsset.Create(DefaultModelAssetId, true);
|
||||
m_defaultMaterialAsset.Create(DefaultMaterialAssetId, true);
|
||||
m_defaultLightingPresetAsset.Create(DefaultLightingPresetAssetId, true);
|
||||
|
||||
m_modelAsset.Create(modelAssetId.IsValid() ? modelAssetId : DefaultModelAssetId, false);
|
||||
m_materialAsset.Create(materialAssetId.IsValid() ? materialAssetId : DefaultMaterialAssetId, false);
|
||||
m_lightingPresetAsset.Create(lightingPresetAssetId.IsValid() ? lightingPresetAssetId : DefaultLightingPresetAssetId, false);
|
||||
m_modelAsset.Create(modelAssetId);
|
||||
m_materialAsset.Create(materialAssetId);
|
||||
m_lightingPresetAsset.Create(lightingPresetAssetId);
|
||||
}
|
||||
|
||||
CommonPreviewContent::~CommonPreviewContent()
|
||||
@@ -113,35 +111,44 @@ namespace AZ
|
||||
m_modelEntity->GetId(), &Render::MeshComponentRequestBus::Events::SetModelAsset, m_modelAsset);
|
||||
|
||||
Render::MaterialComponentRequestBus::Event(
|
||||
m_modelEntity->GetId(), &Render::MaterialComponentRequestBus::Events::SetDefaultMaterialOverride, m_materialAsset.GetId());
|
||||
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 CommonPreviewContent::UpdateLighting()
|
||||
{
|
||||
auto preset = m_lightingPresetAsset->GetDataAs<Render::LightingPreset>();
|
||||
if (preset)
|
||||
if (m_lightingPresetAsset.IsReady())
|
||||
{
|
||||
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);
|
||||
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;
|
||||
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;
|
||||
AZStd::vector<Render::DirectionalLightFeatureProcessorInterface::LightHandle> lightHandles;
|
||||
|
||||
preset->ApplyLightingPreset(
|
||||
iblFeatureProcessor, skyboxFeatureProcessor, exposureControlSettingInterface, directionalLightFeatureProcessor,
|
||||
cameraConfig, lightHandles);
|
||||
preset->ApplyLightingPreset(
|
||||
iblFeatureProcessor, skyboxFeatureProcessor, exposureControlSettingInterface, directionalLightFeatureProcessor,
|
||||
cameraConfig, lightHandles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,8 +164,8 @@ namespace AZ
|
||||
|
||||
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::CreateFromQuaternionAndTranslation(cameraRotation, cameraPosition);
|
||||
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
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Atom/Feature/Material/MaterialAssignment.h>
|
||||
#include <Atom/RPI.Public/Base.h>
|
||||
#include <Atom/RPI.Reflect/Asset/AssetUtils.h>
|
||||
#include <Atom/RPI.Reflect/Material/MaterialAsset.h>
|
||||
#include <Atom/RPI.Reflect/Model/ModelAsset.h>
|
||||
#include <Atom/RPI.Reflect/System/AnyAsset.h>
|
||||
@@ -31,7 +31,8 @@ namespace AZ
|
||||
AZ::Uuid entityContextId,
|
||||
const Data::AssetId& modelAssetId,
|
||||
const Data::AssetId& materialAssetId,
|
||||
const Data::AssetId& lightingPresetAssetId);
|
||||
const Data::AssetId& lightingPresetAssetId,
|
||||
const Render::MaterialPropertyOverrideMap& materialPropertyOverrides);
|
||||
|
||||
~CommonPreviewContent() override;
|
||||
|
||||
@@ -57,22 +58,10 @@ namespace AZ
|
||||
AZ::Uuid m_entityContextId;
|
||||
Entity* m_modelEntity = nullptr;
|
||||
|
||||
static constexpr const char* DefaultLightingPresetPath = "lightingpresets/thumbnail.lightingpreset.azasset";
|
||||
const Data::AssetId DefaultLightingPresetAssetId = AZ::RPI::AssetUtils::GetAssetIdForProductPath(DefaultLightingPresetPath);
|
||||
Data::Asset<RPI::AnyAsset> m_defaultLightingPresetAsset;
|
||||
Data::Asset<RPI::AnyAsset> m_lightingPresetAsset;
|
||||
|
||||
//! Model asset about to be rendered
|
||||
static constexpr const char* DefaultModelPath = "models/sphere.azmodel";
|
||||
const Data::AssetId DefaultModelAssetId = AZ::RPI::AssetUtils::GetAssetIdForProductPath(DefaultModelPath);
|
||||
Data::Asset<RPI::ModelAsset> m_defaultModelAsset;
|
||||
Data::Asset<RPI::ModelAsset> m_modelAsset;
|
||||
|
||||
//! Material asset about to be rendered
|
||||
static constexpr const char* DefaultMaterialPath = "materials/basic_grey.azmaterial";
|
||||
const Data::AssetId DefaultMaterialAssetId = AZ::RPI::AssetUtils::GetAssetIdForProductPath(DefaultMaterialPath);
|
||||
Data::Asset<RPI::MaterialAsset> m_defaultMaterialAsset;
|
||||
Data::Asset<RPI::MaterialAsset> m_materialAsset;
|
||||
Data::Asset<RPI::AnyAsset> m_lightingPresetAsset;
|
||||
Render::MaterialPropertyOverrideMap m_materialPropertyOverrides;
|
||||
};
|
||||
} // namespace LyIntegration
|
||||
} // namespace AZ
|
||||
|
||||
+23
-18
@@ -20,6 +20,13 @@ namespace AZ
|
||||
{
|
||||
CommonThumbnailRenderer::CommonThumbnailRenderer()
|
||||
{
|
||||
m_previewRenderer.reset(aznew AtomToolsFramework::PreviewRenderer(
|
||||
"CommonThumbnailRenderer Preview Scene", "CommonThumbnailRenderer Preview Pipeline"));
|
||||
|
||||
m_defaultModelAsset.Create(DefaultModelAssetId, true);
|
||||
m_defaultMaterialAsset.Create(DefaultMaterialAssetId, true);
|
||||
m_defaultLightingPresetAsset.Create(DefaultLightingPresetAssetId, true);
|
||||
|
||||
// CommonThumbnailRenderer supports both models and materials
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::MultiHandler::BusConnect(RPI::MaterialAsset::RTTI_Type());
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::MultiHandler::BusConnect(RPI::ModelAsset::RTTI_Type());
|
||||
@@ -35,26 +42,24 @@ namespace AZ
|
||||
|
||||
void CommonThumbnailRenderer::RenderThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey thumbnailKey, int thumbnailSize)
|
||||
{
|
||||
m_previewRenderer.AddCaptureRequest(
|
||||
m_previewRenderer->AddCaptureRequest(
|
||||
{ thumbnailSize,
|
||||
AZStd::make_shared<CommonPreviewContent>(
|
||||
m_previewRenderer.GetScene(),
|
||||
m_previewRenderer.GetView(),
|
||||
m_previewRenderer.GetEntityContextId(),
|
||||
GetAssetId(thumbnailKey, RPI::ModelAsset::RTTI_Type()),
|
||||
GetAssetId(thumbnailKey, RPI::MaterialAsset::RTTI_Type()),
|
||||
GetAssetId(thumbnailKey, RPI::AnyAsset::RTTI_Type())),
|
||||
[thumbnailKey]()
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Event(
|
||||
thumbnailKey, &AzToolsFramework::Thumbnailer::ThumbnailerRendererNotifications::ThumbnailFailedToRender);
|
||||
},
|
||||
[thumbnailKey](const QImage& image)
|
||||
{
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Event(
|
||||
thumbnailKey, &AzToolsFramework::Thumbnailer::ThumbnailerRendererNotifications::ThumbnailRendered,
|
||||
QPixmap::fromImage(image));
|
||||
} });
|
||||
m_previewRenderer->GetScene(), m_previewRenderer->GetView(), m_previewRenderer->GetEntityContextId(),
|
||||
GetAssetId(thumbnailKey, RPI::ModelAsset::RTTI_Type(), DefaultModelAssetId),
|
||||
GetAssetId(thumbnailKey, RPI::MaterialAsset::RTTI_Type(), DefaultMaterialAssetId),
|
||||
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 CommonThumbnailRenderer::Installed() const
|
||||
|
||||
+17
-1
@@ -8,6 +8,10 @@
|
||||
|
||||
#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 <AtomToolsFramework/PreviewRenderer/PreviewRenderer.h>
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
#include <AzToolsFramework/Thumbnails/Thumbnail.h>
|
||||
@@ -39,7 +43,19 @@ namespace AZ
|
||||
//! SystemTickBus::Handler interface overrides...
|
||||
void OnSystemTick() override;
|
||||
|
||||
AtomToolsFramework::PreviewRenderer m_previewRenderer;
|
||||
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;
|
||||
|
||||
AZStd::unique_ptr<AtomToolsFramework::PreviewRenderer> m_previewRenderer;
|
||||
};
|
||||
} // namespace Thumbnails
|
||||
} // namespace LyIntegration
|
||||
|
||||
+1
-1
@@ -53,7 +53,7 @@ namespace AZ
|
||||
AzFramework::AssetCatalogEventBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
void LightingPresetThumbnail::ThumbnailRendered(QPixmap& thumbnailImage)
|
||||
void LightingPresetThumbnail::ThumbnailRendered(const QPixmap& thumbnailImage)
|
||||
{
|
||||
m_pixmap = thumbnailImage;
|
||||
m_renderWait.release();
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ namespace AZ
|
||||
~LightingPresetThumbnail() override;
|
||||
|
||||
//! AzToolsFramework::ThumbnailerRendererNotificationBus::Handler overrides...
|
||||
void ThumbnailRendered(QPixmap& thumbnailImage) override;
|
||||
void ThumbnailRendered(const QPixmap& thumbnailImage) override;
|
||||
void ThumbnailFailedToRender() override;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace AZ
|
||||
AzFramework::AssetCatalogEventBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
void MaterialThumbnail::ThumbnailRendered(QPixmap& thumbnailImage)
|
||||
void MaterialThumbnail::ThumbnailRendered(const QPixmap& thumbnailImage)
|
||||
{
|
||||
m_pixmap = thumbnailImage;
|
||||
m_renderWait.release();
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace AZ
|
||||
~MaterialThumbnail() override;
|
||||
|
||||
//! AzToolsFramework::ThumbnailerRendererNotificationBus::Handler overrides...
|
||||
void ThumbnailRendered(QPixmap& thumbnailImage) override;
|
||||
void ThumbnailRendered(const QPixmap& thumbnailImage) override;
|
||||
void ThumbnailFailedToRender() override;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace AZ
|
||||
AzFramework::AssetCatalogEventBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
void ModelThumbnail::ThumbnailRendered(QPixmap& thumbnailImage)
|
||||
void ModelThumbnail::ThumbnailRendered(const QPixmap& thumbnailImage)
|
||||
{
|
||||
m_pixmap = thumbnailImage;
|
||||
m_renderWait.release();
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace AZ
|
||||
~ModelThumbnail() override;
|
||||
|
||||
//! AzToolsFramework::ThumbnailerRendererNotificationBus::Handler overrides...
|
||||
void ThumbnailRendered(QPixmap& thumbnailImage) override;
|
||||
void ThumbnailRendered(const QPixmap& thumbnailImage) override;
|
||||
void ThumbnailFailedToRender() override;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -19,10 +19,11 @@ namespace AZ
|
||||
{
|
||||
namespace Thumbnails
|
||||
{
|
||||
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)
|
||||
@@ -32,7 +33,7 @@ namespace AZ
|
||||
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(),
|
||||
[&assetType](const Data::AssetInfo& assetInfo)
|
||||
@@ -41,7 +42,7 @@ namespace AZ
|
||||
});
|
||||
if (assetInfoIt == productsAssetInfo.end())
|
||||
{
|
||||
return invalidAssetId;
|
||||
return defaultAssetId;
|
||||
}
|
||||
|
||||
return assetInfoIt->m_assetId;
|
||||
@@ -53,7 +54,7 @@ namespace AZ
|
||||
{
|
||||
return productKey->GetAssetId();
|
||||
}
|
||||
return invalidAssetId;
|
||||
return defaultAssetId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -21,7 +21,10 @@ namespace AZ
|
||||
namespace Thumbnails
|
||||
{
|
||||
//! 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
|
||||
QString WordWrap(const QString& string, int maxLength);
|
||||
|
||||
+1
@@ -7,6 +7,7 @@
|
||||
#
|
||||
|
||||
set(FILES
|
||||
Include/AtomLyIntegration/CommonFeatures/Material/EditorMaterialSystemComponentNotificationBus.h
|
||||
Include/AtomLyIntegration/CommonFeatures/Material/EditorMaterialSystemComponentRequestBus.h
|
||||
Include/AtomLyIntegration/CommonFeatures/ReflectionProbe/EditorReflectionProbeBus.h
|
||||
Source/Module.cpp
|
||||
|
||||
Reference in New Issue
Block a user