Merge branch 'Atom/guthadam/atomtools_updating_cmake_config' into Atom/guthadam/atomtools_updating_cmake_config_plus_bootstrap
This commit is contained in:
+6
@@ -24,6 +24,12 @@ namespace AtomToolsFramework
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
|
||||
typedef AZ::Uuid BusIdType;
|
||||
|
||||
//! Add heading widget above scroll area
|
||||
virtual void AddHeading(QWidget* headingWidget) = 0;
|
||||
|
||||
//! Clear heading widgets
|
||||
virtual void ClearHeading() = 0;
|
||||
|
||||
//! Clear all inspector groups and content
|
||||
virtual void Reset() = 0;
|
||||
|
||||
|
||||
+4
-1
@@ -41,6 +41,10 @@ namespace AtomToolsFramework
|
||||
~InspectorWidget() override;
|
||||
|
||||
// InspectorRequestBus::Handler overrides...
|
||||
void AddHeading(QWidget* headingWidget) override;
|
||||
|
||||
void ClearHeading() override;
|
||||
|
||||
void Reset() override;
|
||||
|
||||
void AddGroupsBegin() override;
|
||||
@@ -77,7 +81,6 @@ namespace AtomToolsFramework
|
||||
virtual void OnHeaderClicked(const AZStd::string& groupNameId, QMouseEvent* event);
|
||||
|
||||
private:
|
||||
QVBoxLayout* m_layout = nullptr;
|
||||
QScopedPointer<Ui::InspectorWidget> m_ui;
|
||||
|
||||
struct GroupWidgetPair
|
||||
|
||||
+25
-1
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <QWidget>
|
||||
#include <QElapsedTimer>
|
||||
#include <QPointer>
|
||||
#include <Atom/RPI.Public/Base.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportMessages.h>
|
||||
#include <AzToolsFramework/Input/QtEventToAzInputManager.h>
|
||||
@@ -21,6 +22,8 @@
|
||||
#include <AzFramework/Windowing/WindowBus.h>
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
#include <Atom/RPI.Public/AuxGeom/AuxGeomFeatureProcessorInterface.h>
|
||||
#include <Atom/Bootstrap/BootstrapNotificationBus.h>
|
||||
#include <AtomToolsFramework/Viewport/RenderViewportWidgetNotificationBus.h>
|
||||
|
||||
namespace AtomToolsFramework
|
||||
{
|
||||
@@ -35,6 +38,8 @@ namespace AtomToolsFramework
|
||||
, public AzFramework::WindowRequestBus::Handler
|
||||
, protected AzFramework::InputChannelEventListener
|
||||
, protected AZ::TickBus::Handler
|
||||
, protected AZ::Render::Bootstrap::NotificationBus::Handler
|
||||
, protected AtomToolsFramework::RenderViewportWidgetNotificationBus::Handler
|
||||
{
|
||||
public:
|
||||
//! Creates a RenderViewportWidget.
|
||||
@@ -113,7 +118,7 @@ namespace AtomToolsFramework
|
||||
void ToggleFullScreenState() override;
|
||||
float GetDpiScaleFactor() const override;
|
||||
uint32_t GetSyncInterval() const override;
|
||||
uint32_t GetDisplayRefreshRate() const;
|
||||
uint32_t GetDisplayRefreshRate() const override;
|
||||
|
||||
protected:
|
||||
// AzFramework::InputChannelEventListener ...
|
||||
@@ -121,6 +126,7 @@ namespace AtomToolsFramework
|
||||
|
||||
// AZ::TickBus::Handler ...
|
||||
void OnTick(float deltaTime, AZ::ScriptTimePoint time) override;
|
||||
int GetTickOrder() override;
|
||||
|
||||
// QWidget ...
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
@@ -128,9 +134,21 @@ namespace AtomToolsFramework
|
||||
void enterEvent(QEvent* event) override;
|
||||
void leaveEvent(QEvent* event) override;
|
||||
void mouseMoveEvent(QMouseEvent* event) override;
|
||||
void focusInEvent(QFocusEvent* event) override;
|
||||
|
||||
// AZ::Render::Bootstrap::NotificationBus::Handler ...
|
||||
void OnFrameRateLimitChanged(float fpsLimit) override;
|
||||
|
||||
// AtomToolsFramework::RenderViewportWidgetNotificationBus::Handler ...
|
||||
void OnInactiveViewportFrameRateChanged(float fpsLimit) override;
|
||||
|
||||
private:
|
||||
AzFramework::NativeWindowHandle GetNativeWindowHandle() const;
|
||||
void UpdateFrameRate();
|
||||
|
||||
void SetScreen(QScreen* screen);
|
||||
void SendWindowResizeEvent();
|
||||
void NotifyUpdateRefreshRate();
|
||||
|
||||
// The underlying ViewportContext, our entry-point to the Atom RPI.
|
||||
AZ::RPI::ViewportContextPtr m_viewportContext;
|
||||
@@ -153,5 +171,11 @@ namespace AtomToolsFramework
|
||||
AZ::ScriptTimePoint m_time;
|
||||
// Maps our internal Qt events into AzFramework InputChannels for our ViewportControllerList.
|
||||
AzToolsFramework::QtEventToAzInputMapper* m_inputChannelMapper = nullptr;
|
||||
// Stores our current screen, used for tracking the current refresh rate.
|
||||
QScreen* m_screen = nullptr;
|
||||
// Stores the last RenderViewportWidget that has received user focus.
|
||||
// This is used for optional framerate throtting for "inactive" viewports via the
|
||||
// ed_inactive_viewport_fps_limit CVAR.
|
||||
AZ::EnvironmentVariable<RenderViewportWidget*> m_lastFocusedViewport;
|
||||
};
|
||||
} //namespace AtomToolsFramework
|
||||
|
||||
+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 <AzCore/EBus/EBus.h>
|
||||
|
||||
namespace AtomToolsFramework
|
||||
{
|
||||
//! Provides an interface for providing notifications specific to RenderViewportWidget.
|
||||
//! @note Most behaviors in RenderViewportWidget are handled by its underyling
|
||||
//! ViewportContext, this bus is specifically for functionality exclusive to the
|
||||
//! Qt layer provided by RenderViewportWidget.
|
||||
class RenderViewportWidgetNotifications : public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
|
||||
|
||||
//! Triggered when the idle frame rate limit for inactive viewports changed.
|
||||
//! Controlled by the ed_inactive_viewport_fps_limit CVAR.
|
||||
//! Active viewports are controlled by the r_fps_limit CVAR.
|
||||
virtual void OnInactiveViewportFrameRateChanged([[maybe_unused]]float fpsLimit){}
|
||||
|
||||
protected:
|
||||
~RenderViewportWidgetNotifications() = default;
|
||||
};
|
||||
|
||||
using RenderViewportWidgetNotificationBus = AZ::EBus<RenderViewportWidgetNotifications>;
|
||||
} // namespace AtomToolsFramework
|
||||
+1
-1
@@ -38,7 +38,7 @@ namespace AtomToolsFramework
|
||||
m_propertyEditor->Setup(context, instanceNotificationHandler, false);
|
||||
m_propertyEditor->AddInstance(instance, instanceClassId, nullptr, instanceToCompare);
|
||||
m_propertyEditor->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
m_propertyEditor->QueueInvalidation(AzToolsFramework::PropertyModificationRefreshLevel::Refresh_EntireTree);
|
||||
m_propertyEditor->InvalidateAll();
|
||||
|
||||
m_layout->addWidget(m_propertyEditor);
|
||||
setLayout(m_layout);
|
||||
|
||||
@@ -29,30 +29,40 @@ namespace AtomToolsFramework
|
||||
{
|
||||
}
|
||||
|
||||
void InspectorWidget::AddHeading(QWidget* headingWidget)
|
||||
{
|
||||
headingWidget->setParent(m_ui->m_headingSection);
|
||||
m_ui->m_headingSectionLayout->addWidget(headingWidget);
|
||||
}
|
||||
|
||||
void InspectorWidget::ClearHeading()
|
||||
{
|
||||
qDeleteAll(m_ui->m_headingSection->findChildren<QWidget*>(QString(), Qt::FindDirectChildrenOnly));
|
||||
qDeleteAll(m_ui->m_headingSectionLayout->children());
|
||||
}
|
||||
|
||||
void InspectorWidget::Reset()
|
||||
{
|
||||
qDeleteAll(m_ui->m_propertyContent->children());
|
||||
m_layout = new QVBoxLayout(m_ui->m_propertyContent);
|
||||
m_layout->setContentsMargins(0, 0, 0, 0);
|
||||
m_layout->setSpacing(0);
|
||||
qDeleteAll(m_ui->m_groupContents->findChildren<QWidget*>(QString(), Qt::FindDirectChildrenOnly));
|
||||
qDeleteAll(m_ui->m_groupContentsLayout->children());
|
||||
m_groups.clear();
|
||||
}
|
||||
|
||||
void InspectorWidget::AddGroupsBegin()
|
||||
{
|
||||
setUpdatesEnabled(false);
|
||||
setVisible(false);
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
void InspectorWidget::AddGroupsEnd()
|
||||
{
|
||||
m_layout->addStretch();
|
||||
m_ui->m_groupContentsLayout->addStretch();
|
||||
|
||||
// Scroll to top whenever there is new content
|
||||
m_ui->m_propertyScrollArea->verticalScrollBar()->setValue(m_ui->m_propertyScrollArea->verticalScrollBar()->minimum());
|
||||
m_ui->m_groupScrollArea->verticalScrollBar()->setValue(m_ui->m_groupScrollArea->verticalScrollBar()->minimum());
|
||||
|
||||
setUpdatesEnabled(true);
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
void InspectorWidget::AddGroup(
|
||||
@@ -61,14 +71,14 @@ namespace AtomToolsFramework
|
||||
const AZStd::string& groupDescription,
|
||||
QWidget* groupWidget)
|
||||
{
|
||||
InspectorGroupHeaderWidget* groupHeader = new InspectorGroupHeaderWidget(m_ui->m_propertyContent);
|
||||
InspectorGroupHeaderWidget* groupHeader = new InspectorGroupHeaderWidget(m_ui->m_groupContents);
|
||||
groupHeader->setText(groupDisplayName.c_str());
|
||||
groupHeader->setToolTip(groupDescription.c_str());
|
||||
m_layout->addWidget(groupHeader);
|
||||
m_ui->m_groupContentsLayout->addWidget(groupHeader);
|
||||
|
||||
groupWidget->setObjectName(groupNameId.c_str());
|
||||
groupWidget->setParent(m_ui->m_propertyContent);
|
||||
m_layout->addWidget(groupWidget);
|
||||
groupWidget->setParent(m_ui->m_groupContents);
|
||||
m_ui->m_groupContentsLayout->addWidget(groupWidget);
|
||||
|
||||
m_groups[groupNameId] = {groupHeader, groupWidget};
|
||||
|
||||
@@ -101,28 +111,18 @@ namespace AtomToolsFramework
|
||||
bool InspectorWidget::IsGroupVisible(const AZStd::string& groupNameId) const
|
||||
{
|
||||
auto groupItr = m_groups.find(groupNameId);
|
||||
if (groupItr != m_groups.end())
|
||||
{
|
||||
return groupItr->second.m_header->isVisible();
|
||||
}
|
||||
|
||||
return false;
|
||||
return groupItr != m_groups.end() ? groupItr->second.m_header->isVisible() : false;
|
||||
}
|
||||
|
||||
bool InspectorWidget::IsGroupHidden(const AZStd::string& groupNameId) const
|
||||
{
|
||||
auto groupItr = m_groups.find(groupNameId);
|
||||
if (groupItr != m_groups.end())
|
||||
{
|
||||
return groupItr->second.m_header->isHidden();
|
||||
}
|
||||
|
||||
return false;
|
||||
return groupItr != m_groups.end() ? groupItr->second.m_header->isHidden() : false;
|
||||
}
|
||||
|
||||
void InspectorWidget::RefreshGroup(const AZStd::string& groupNameId)
|
||||
{
|
||||
for (auto groupWidget : m_ui->m_propertyContent->findChildren<InspectorGroupWidget*>(groupNameId.c_str()))
|
||||
for (auto groupWidget : m_ui->m_groupContents->findChildren<InspectorGroupWidget*>(groupNameId.c_str()))
|
||||
{
|
||||
groupWidget->Refresh();
|
||||
}
|
||||
@@ -130,7 +130,7 @@ namespace AtomToolsFramework
|
||||
|
||||
void InspectorWidget::RebuildGroup(const AZStd::string& groupNameId)
|
||||
{
|
||||
for (auto groupWidget : m_ui->m_propertyContent->findChildren<InspectorGroupWidget*>(groupNameId.c_str()))
|
||||
for (auto groupWidget : m_ui->m_groupContents->findChildren<InspectorGroupWidget*>(groupNameId.c_str()))
|
||||
{
|
||||
groupWidget->Rebuild();
|
||||
}
|
||||
@@ -138,7 +138,7 @@ namespace AtomToolsFramework
|
||||
|
||||
void InspectorWidget::RefreshAll()
|
||||
{
|
||||
for (auto groupWidget : m_ui->m_propertyContent->findChildren<InspectorGroupWidget*>())
|
||||
for (auto groupWidget : m_ui->m_groupContents->findChildren<InspectorGroupWidget*>())
|
||||
{
|
||||
groupWidget->Refresh();
|
||||
}
|
||||
@@ -146,7 +146,7 @@ namespace AtomToolsFramework
|
||||
|
||||
void InspectorWidget::RebuildAll()
|
||||
{
|
||||
for (auto groupWidget : m_ui->m_propertyContent->findChildren<InspectorGroupWidget*>())
|
||||
for (auto groupWidget : m_ui->m_groupContents->findChildren<InspectorGroupWidget*>())
|
||||
{
|
||||
groupWidget->Rebuild();
|
||||
}
|
||||
|
||||
@@ -6,20 +6,14 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>693</width>
|
||||
<height>798</height>
|
||||
<width>685</width>
|
||||
<height>775</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Inspector</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<layout class="QVBoxLayout" name="m_inspectorLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
@@ -36,50 +30,103 @@
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QScrollArea" name="m_propertyScrollArea">
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAsNeeded</enum>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>691</width>
|
||||
<height>796</height>
|
||||
</rect>
|
||||
<widget class="QWidget" name="m_sections">
|
||||
<layout class="QVBoxLayout" name="m_sectionsLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QFrame" name="m_propertyContent">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="m_headingSection" native="true">
|
||||
<layout class="QVBoxLayout" name="m_headingSectionLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="m_groupSection" native="true">
|
||||
<layout class="QVBoxLayout" name="m_groupSectionLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QScrollArea" name="m_groupScrollArea">
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAsNeeded</enum>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="m_groupContents">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>683</width>
|
||||
<height>763</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="m_groupContentsLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
||||
@@ -6,23 +6,42 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AtomToolsFramework/Viewport/RenderViewportWidget.h>
|
||||
#include <Atom/Bootstrap/BootstrapRequestBus.h>
|
||||
#include <Atom/RHI/RHISystemInterface.h>
|
||||
#include <Atom/RPI.Public/View.h>
|
||||
#include <Atom/RPI.Public/ViewportContext.h>
|
||||
#include <Atom/RPI.Public/ViewportContextBus.h>
|
||||
#include <Atom/RPI.Public/View.h>
|
||||
#include <AtomToolsFramework/Viewport/RenderViewportWidget.h>
|
||||
#include <AzCore/Console/Console.h>
|
||||
#include <AzCore/Math/MathUtils.h>
|
||||
#include <AzFramework/Input/Devices/Mouse/InputDeviceMouse.h>
|
||||
#include <AzFramework/Viewport/ViewportControllerList.h>
|
||||
#include <AzFramework/Viewport/ViewportScreen.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportTypes.h>
|
||||
#include <AzCore/Math/MathUtils.h>
|
||||
#include <Atom/RHI/RHISystemInterface.h>
|
||||
#include <Atom/Bootstrap/BootstrapRequestBus.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCursor>
|
||||
#include <QBoxLayout>
|
||||
#include <QWindow>
|
||||
#include <QCursor>
|
||||
#include <QMouseEvent>
|
||||
#include <QScreen>
|
||||
#include <QTimer>
|
||||
#include <QWindow>
|
||||
|
||||
static void OnInactiveViewportFrameRateChanged(const float& fpsLimit)
|
||||
{
|
||||
AtomToolsFramework::RenderViewportWidgetNotificationBus::Broadcast(
|
||||
&AtomToolsFramework::RenderViewportWidgetNotificationBus::Events::OnInactiveViewportFrameRateChanged, fpsLimit);
|
||||
}
|
||||
|
||||
AZ_CVAR(
|
||||
float,
|
||||
ed_inactive_viewport_fps_limit,
|
||||
0,
|
||||
OnInactiveViewportFrameRateChanged,
|
||||
AZ::ConsoleFunctorFlags::Null,
|
||||
"The maximum framerate to render viewports that don't have focus at");
|
||||
|
||||
static constexpr const char* LastFocusedViewportVariableName = "AtomToolsFramework::RenderViewportWidget::LastFocusedViewport";
|
||||
|
||||
namespace AtomToolsFramework
|
||||
{
|
||||
@@ -30,6 +49,12 @@ namespace AtomToolsFramework
|
||||
: QWidget(parent)
|
||||
, AzFramework::InputChannelEventListener(AzFramework::InputChannelEventListener::GetPriorityDefault())
|
||||
{
|
||||
m_lastFocusedViewport = AZ::Environment::FindVariable<RenderViewportWidget*>(LastFocusedViewportVariableName);
|
||||
if (!m_lastFocusedViewport)
|
||||
{
|
||||
m_lastFocusedViewport = AZ::Environment::CreateVariable<RenderViewportWidget*>(LastFocusedViewportVariableName, nullptr);
|
||||
}
|
||||
|
||||
if (shouldInitializeViewportContext)
|
||||
{
|
||||
InitializeViewportContext();
|
||||
@@ -38,13 +63,24 @@ namespace AtomToolsFramework
|
||||
setUpdatesEnabled(false);
|
||||
setFocusPolicy(Qt::FocusPolicy::WheelFocus);
|
||||
setMouseTracking(true);
|
||||
|
||||
// Wait a frame for our window handle to be constructed, then wire up our screen change signals.
|
||||
QTimer::singleShot(
|
||||
0,
|
||||
[this]()
|
||||
{
|
||||
QObject::connect(windowHandle(), &QWindow::screenChanged, this, &RenderViewportWidget::SetScreen);
|
||||
});
|
||||
SetScreen(screen());
|
||||
}
|
||||
|
||||
bool RenderViewportWidget::InitializeViewportContext(AzFramework::ViewportId id)
|
||||
{
|
||||
if (m_viewportContext != nullptr)
|
||||
{
|
||||
AZ_Assert(id == AzFramework::InvalidViewportId || m_viewportContext->GetId() == id, "Attempted to reinitialize RenderViewportWidget with a different ID");
|
||||
AZ_Assert(
|
||||
id == AzFramework::InvalidViewportId || m_viewportContext->GetId() == id,
|
||||
"Attempted to reinitialize RenderViewportWidget with a different ID");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -59,7 +95,7 @@ namespace AtomToolsFramework
|
||||
// Before we do anything else, we must create a ViewportContext which will give us a ViewportId if we didn't manually specify one.
|
||||
AZ::RPI::ViewportContextRequestsInterface::CreationParameters params;
|
||||
params.device = AZ::RHI::RHISystemInterface::Get()->GetDevice();
|
||||
params.windowHandle = reinterpret_cast<AzFramework::NativeWindowHandle>(winId());
|
||||
params.windowHandle = GetNativeWindowHandle();
|
||||
params.id = id;
|
||||
AzFramework::WindowRequestBus::Handler::BusConnect(params.windowHandle);
|
||||
m_viewportContext = viewportContextManager->CreateViewportContext(AZ::Name(), params);
|
||||
@@ -80,29 +116,46 @@ namespace AtomToolsFramework
|
||||
AzFramework::InputChannelEventListener::Connect();
|
||||
AZ::TickBus::Handler::BusConnect();
|
||||
AzFramework::WindowRequestBus::Handler::BusConnect(params.windowHandle);
|
||||
AZ::Render::Bootstrap::NotificationBus::Handler::BusConnect();
|
||||
AtomToolsFramework::RenderViewportWidgetNotificationBus::Handler::BusConnect();
|
||||
|
||||
m_inputChannelMapper = new AzToolsFramework::QtEventToAzInputMapper(this, id);
|
||||
|
||||
// Forward input events to our controller list.
|
||||
QObject::connect(m_inputChannelMapper, &AzToolsFramework::QtEventToAzInputMapper::InputChannelUpdated, this,
|
||||
QObject::connect(
|
||||
m_inputChannelMapper, &AzToolsFramework::QtEventToAzInputMapper::InputChannelUpdated, this,
|
||||
[this](const AzFramework::InputChannel* inputChannel, QEvent* event)
|
||||
{
|
||||
AzFramework::NativeWindowHandle windowId = reinterpret_cast<AzFramework::NativeWindowHandle>(winId());
|
||||
if (m_controllerList->HandleInputChannelEvent(AzFramework::ViewportControllerInputEvent{GetId(), windowId, *inputChannel}))
|
||||
{
|
||||
// If the controller handled the input event, mark the event as accepted so it doesn't continue to propagate.
|
||||
if (event)
|
||||
const AzFramework::NativeWindowHandle windowId = GetNativeWindowHandle();
|
||||
if (m_controllerList->HandleInputChannelEvent(
|
||||
AzFramework::ViewportControllerInputEvent{ GetId(), windowId, *inputChannel }))
|
||||
{
|
||||
event->setAccepted(true);
|
||||
// If the controller handled the input event, mark the event as accepted so it doesn't continue to propagate.
|
||||
if (event)
|
||||
{
|
||||
event->setAccepted(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Update our target frame rate. If we're the only viewport, become active.
|
||||
if (m_lastFocusedViewport.Get() == nullptr)
|
||||
{
|
||||
m_lastFocusedViewport.Set(this);
|
||||
}
|
||||
UpdateFrameRate();
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
RenderViewportWidget::~RenderViewportWidget()
|
||||
{
|
||||
if (m_lastFocusedViewport.Get() == this)
|
||||
{
|
||||
m_lastFocusedViewport.Set(nullptr);
|
||||
}
|
||||
|
||||
AzFramework::WindowRequestBus::Handler::BusDisconnect();
|
||||
AZ::TickBus::Handler::BusDisconnect();
|
||||
AzFramework::InputChannelEventListener::Disconnect();
|
||||
@@ -181,17 +234,22 @@ namespace AtomToolsFramework
|
||||
|
||||
bool shouldConsumeEvent = true;
|
||||
|
||||
AzFramework::NativeWindowHandle windowId = reinterpret_cast<AzFramework::NativeWindowHandle>(winId());
|
||||
const bool eventHandled = m_controllerList->HandleInputChannelEvent({GetId(), windowId, inputChannel});
|
||||
const bool eventHandled = m_controllerList->HandleInputChannelEvent({ GetId(), GetNativeWindowHandle(), inputChannel });
|
||||
|
||||
// If our controllers handled the event and it's one we can safely consume (i.e. it's not an Ended event that other viewports might need), consume it.
|
||||
// If our controllers handled the event and it's one we can safely consume (i.e. it's not an Ended event that other viewports might
|
||||
// need), consume it.
|
||||
return eventHandled && shouldConsumeEvent;
|
||||
}
|
||||
|
||||
void RenderViewportWidget::OnTick([[maybe_unused]]float deltaTime, AZ::ScriptTimePoint time)
|
||||
void RenderViewportWidget::OnTick([[maybe_unused]] float deltaTime, AZ::ScriptTimePoint time)
|
||||
{
|
||||
m_time = time;
|
||||
m_controllerList->UpdateViewport({GetId(), AzFramework::FloatSeconds(deltaTime), m_time});
|
||||
m_controllerList->UpdateViewport({ GetId(), AzFramework::FloatSeconds(deltaTime), m_time });
|
||||
}
|
||||
|
||||
int RenderViewportWidget::GetTickOrder()
|
||||
{
|
||||
return AZ::ComponentTickBus::TICK_PRE_RENDER;
|
||||
}
|
||||
|
||||
void RenderViewportWidget::resizeEvent([[maybe_unused]] QResizeEvent* event)
|
||||
@@ -236,6 +294,75 @@ namespace AtomToolsFramework
|
||||
m_mousePosition = event->localPos();
|
||||
}
|
||||
|
||||
void RenderViewportWidget::focusInEvent([[maybe_unused]] QFocusEvent* event)
|
||||
{
|
||||
RenderViewportWidget* lastFocusedViewport = m_lastFocusedViewport.Get();
|
||||
if (lastFocusedViewport == this)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RenderViewportWidget* previousFocusWidget = lastFocusedViewport;
|
||||
m_lastFocusedViewport.Set(this);
|
||||
|
||||
// Ensure this viewport and whatever viewport last had focus (if any) respect
|
||||
// the active / inactive viewport frame rate settings.
|
||||
UpdateFrameRate();
|
||||
if (previousFocusWidget != nullptr)
|
||||
{
|
||||
previousFocusWidget->UpdateFrameRate();
|
||||
}
|
||||
}
|
||||
|
||||
void RenderViewportWidget::OnFrameRateLimitChanged([[maybe_unused]] float fpsLimit)
|
||||
{
|
||||
UpdateFrameRate();
|
||||
}
|
||||
|
||||
void RenderViewportWidget::OnInactiveViewportFrameRateChanged([[maybe_unused]] float fpsLimit)
|
||||
{
|
||||
UpdateFrameRate();
|
||||
}
|
||||
|
||||
AzFramework::NativeWindowHandle RenderViewportWidget::GetNativeWindowHandle() const
|
||||
{
|
||||
return reinterpret_cast<AzFramework::NativeWindowHandle>(winId());
|
||||
}
|
||||
|
||||
void RenderViewportWidget::UpdateFrameRate()
|
||||
{
|
||||
if (ed_inactive_viewport_fps_limit > 0.f && m_lastFocusedViewport.Get() != this)
|
||||
{
|
||||
m_viewportContext->SetFpsLimit(ed_inactive_viewport_fps_limit);
|
||||
}
|
||||
else
|
||||
{
|
||||
float fpsLimit = 0.f;
|
||||
AZ::Render::Bootstrap::RequestBus::BroadcastResult(fpsLimit, &AZ::Render::Bootstrap::RequestBus::Events::GetFrameRateLimit);
|
||||
m_viewportContext->SetFpsLimit(fpsLimit);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderViewportWidget::SetScreen(QScreen* screen)
|
||||
{
|
||||
if (m_screen != screen)
|
||||
{
|
||||
if (m_screen)
|
||||
{
|
||||
QObject::disconnect(m_screen, &QScreen::refreshRateChanged, this, &RenderViewportWidget::NotifyUpdateRefreshRate);
|
||||
}
|
||||
|
||||
if (screen)
|
||||
{
|
||||
QObject::connect(m_screen, &QScreen::refreshRateChanged, this, &RenderViewportWidget::NotifyUpdateRefreshRate);
|
||||
}
|
||||
|
||||
NotifyUpdateRefreshRate();
|
||||
|
||||
m_screen = screen;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderViewportWidget::SendWindowResizeEvent()
|
||||
{
|
||||
// Scale the size by the DPI of the platform to
|
||||
@@ -243,11 +370,17 @@ namespace AtomToolsFramework
|
||||
const QSize uiWindowSize = size();
|
||||
const QSize windowSize = uiWindowSize * devicePixelRatioF();
|
||||
|
||||
const AzFramework::NativeWindowHandle windowId = reinterpret_cast<AzFramework::NativeWindowHandle>(winId());
|
||||
AzFramework::WindowNotificationBus::Event(windowId, &AzFramework::WindowNotifications::OnWindowResized, windowSize.width(), windowSize.height());
|
||||
AzFramework::WindowNotificationBus::Event(
|
||||
GetNativeWindowHandle(), &AzFramework::WindowNotifications::OnWindowResized, windowSize.width(), windowSize.height());
|
||||
m_windowResizedEvent = false;
|
||||
}
|
||||
|
||||
void RenderViewportWidget::NotifyUpdateRefreshRate()
|
||||
{
|
||||
AzFramework::WindowNotificationBus::Event(
|
||||
GetNativeWindowHandle(), &AzFramework::WindowNotificationBus::Events::OnRefreshRateChanged, GetDisplayRefreshRate());
|
||||
}
|
||||
|
||||
AZ::Name RenderViewportWidget::GetCurrentContextName() const
|
||||
{
|
||||
return m_viewportContext->GetName();
|
||||
@@ -303,9 +436,7 @@ namespace AtomToolsFramework
|
||||
|
||||
// Build camera state from Atom camera transforms
|
||||
AzFramework::CameraState cameraState = AzFramework::CreateCameraFromWorldFromViewMatrix(
|
||||
currentView->GetViewToWorldMatrix(),
|
||||
AZ::Vector2{aznumeric_cast<float>(width()), aznumeric_cast<float>(height())}
|
||||
);
|
||||
currentView->GetViewToWorldMatrix(), AZ::Vector2{ aznumeric_cast<float>(width()), aznumeric_cast<float>(height()) });
|
||||
AzFramework::SetCameraClippingVolumeFromPerspectiveFovMatrixRH(cameraState, currentView->GetViewToClipMatrix());
|
||||
|
||||
// Convert from Z-up
|
||||
@@ -317,8 +448,7 @@ namespace AtomToolsFramework
|
||||
|
||||
AzFramework::ScreenPoint RenderViewportWidget::ViewportWorldToScreen(const AZ::Vector3& worldPosition)
|
||||
{
|
||||
if (AZ::RPI::ViewPtr currentView = m_viewportContext->GetDefaultView();
|
||||
currentView == nullptr)
|
||||
if (AZ::RPI::ViewPtr currentView = m_viewportContext->GetDefaultView(); currentView == nullptr)
|
||||
{
|
||||
return AzFramework::ScreenPoint(0, 0);
|
||||
}
|
||||
@@ -331,12 +461,10 @@ namespace AtomToolsFramework
|
||||
const auto& cameraProjection = m_viewportContext->GetCameraProjectionMatrix();
|
||||
const auto& cameraView = m_viewportContext->GetCameraViewMatrix();
|
||||
|
||||
const AZ::Vector4 normalizedScreenPosition {
|
||||
screenPosition.m_x * 2.f / width() - 1.0f,
|
||||
(height() - screenPosition.m_y) * 2.f / height() - 1.0f,
|
||||
1.f - depth, // [GFX TODO] [ATOM-1501] Currently we always assume reverse depth
|
||||
1.f
|
||||
};
|
||||
const AZ::Vector4 normalizedScreenPosition{ screenPosition.m_x * 2.f / width() - 1.0f,
|
||||
(height() - screenPosition.m_y) * 2.f / height() - 1.0f,
|
||||
1.f - depth, // [GFX TODO] [ATOM-1501] Currently we always assume reverse depth
|
||||
1.f };
|
||||
|
||||
AZ::Matrix4x4 worldFromScreen = cameraProjection * cameraView;
|
||||
worldFromScreen.InvertFull();
|
||||
@@ -365,7 +493,7 @@ namespace AtomToolsFramework
|
||||
AZ::Vector3 rayDirection = pos1.value() - pos0.value();
|
||||
rayDirection.Normalize();
|
||||
|
||||
return AzToolsFramework::ViewportInteraction::ProjectedViewportRay{rayOrigin, rayDirection};
|
||||
return AzToolsFramework::ViewportInteraction::ProjectedViewportRay{ rayOrigin, rayDirection };
|
||||
}
|
||||
|
||||
float RenderViewportWidget::DeviceScalingFactor()
|
||||
@@ -395,12 +523,12 @@ namespace AtomToolsFramework
|
||||
|
||||
AzFramework::WindowSize RenderViewportWidget::GetClientAreaSize() const
|
||||
{
|
||||
return AzFramework::WindowSize{aznumeric_cast<uint32_t>(width()), aznumeric_cast<uint32_t>(height())};
|
||||
return AzFramework::WindowSize{ aznumeric_cast<uint32_t>(width()), aznumeric_cast<uint32_t>(height()) };
|
||||
}
|
||||
|
||||
void RenderViewportWidget::ResizeClientArea(AzFramework::WindowSize clientAreaSize)
|
||||
{
|
||||
const QSize targetSize = QSize{aznumeric_cast<int>(clientAreaSize.m_width), aznumeric_cast<int>(clientAreaSize.m_height)};
|
||||
const QSize targetSize = QSize{ aznumeric_cast<int>(clientAreaSize.m_width), aznumeric_cast<int>(clientAreaSize.m_height) };
|
||||
resize(targetSize);
|
||||
}
|
||||
|
||||
@@ -410,7 +538,7 @@ namespace AtomToolsFramework
|
||||
return false;
|
||||
}
|
||||
|
||||
void RenderViewportWidget::SetFullScreenState([[maybe_unused]]bool fullScreenState)
|
||||
void RenderViewportWidget::SetFullScreenState([[maybe_unused]] bool fullScreenState)
|
||||
{
|
||||
// The RenderViewportWidget does not currently support full screen.
|
||||
}
|
||||
@@ -433,11 +561,20 @@ namespace AtomToolsFramework
|
||||
|
||||
uint32_t RenderViewportWidget::GetDisplayRefreshRate() const
|
||||
{
|
||||
return 60;
|
||||
return static_cast<uint32_t>(screen()->refreshRate());
|
||||
}
|
||||
|
||||
uint32_t RenderViewportWidget::GetSyncInterval() const
|
||||
{
|
||||
return 1;
|
||||
uint32_t interval = 1;
|
||||
|
||||
// Get vsync_interval from AzFramework::NativeWindow, which owns it.
|
||||
// NativeWindow also handles broadcasting OnVsyncIntervalChanged to all
|
||||
// WindowNotificationBus listeners.
|
||||
if (auto console = AZ::Interface<AZ::IConsole>::Get())
|
||||
{
|
||||
console->GetCvarValue<uint32_t>("vsync_interval", interval);
|
||||
}
|
||||
return interval;
|
||||
}
|
||||
} //namespace AtomToolsFramework
|
||||
} // namespace AtomToolsFramework
|
||||
|
||||
@@ -28,6 +28,7 @@ set(FILES
|
||||
Include/AtomToolsFramework/Util/MaterialPropertyUtil.h
|
||||
Include/AtomToolsFramework/Util/Util.h
|
||||
Include/AtomToolsFramework/Viewport/RenderViewportWidget.h
|
||||
Include/AtomToolsFramework/Viewport/RenderViewportWidgetNotificationBus.h
|
||||
Include/AtomToolsFramework/Viewport/ModularViewportCameraController.h
|
||||
Include/AtomToolsFramework/Viewport/ModularViewportCameraControllerRequestBus.h
|
||||
Include/AtomToolsFramework/Window/AtomToolsMainWindow.h
|
||||
|
||||
Reference in New Issue
Block a user